Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

How to step through pixels of an image?  RSS feed

 
Justin Robbins
Ranch Hand
Posts: 121
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I need to test intensities of a pixel by determining the intensities of the 8 pixels that surround it. So there is a middle pixel which is always left untouched. So I need to run through the bottom pixels and then the top pixels.
for example:
[ T, T, T ]
[ _, M ,_ ]
[ B, B, B ]

Where M would be that middle pixel in question.

My problem is I don't know how to create a loop which would step through things like this. Like looping from bottom 3 B's while grabbing their individual intensities, then create another loop which would step through all the top 3 T's while grabbing their individual intensities.

Then the same but for running through the right and left side pixels, for example:

[ L, _, R ]
[ L, M ,R ]
[ L, _, R ]

Another issue is if I am stepping through each pixel of an image grid. Don't grids and loops work from left to right? so at (0,0) then wouldn't I have something like:

[ P, P1 ]
[ P2, P3]

How would I test for cases like this where it starts out and only have 3 pixel neighbors instead of example of 8?


Please help
Thank you
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Justin Robbins wrote:Then the same but for running through the right and left side pixels...

Well first of all, how are these pixels held? In a 2D grid, or in a stream with some sort of "width" specification?

Assuming it's a grid (although it doesn't really matter too much) my suggestion would be to simply treat them as offsets, and supply those as coordinates to your intensity() method in whatever order they're needed .

So, for your first example you might supply
  {1, -1}, {1, 0}, {1, 1} for the bottom row,
  {-1, -1}, {-1, 0}, {-1, 1} for the top row, and
  {0, -1}, {0, 1} for the two on either side.

And then all you need to do is sum them with the real coordinate of the middle pixel to get the coordinates of the ones you want.

BTW, java.awt.Point is good for creating coordinates - although it's an abominable class.

HIH

Winston
 
Justin Robbins
Ranch Hand
Posts: 121
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
Well first of all, how are these pixels held? In a 2D grid, or in a stream with some sort of "width" specification?

Assuming it's a grid (although it doesn't really matter too much) my suggestion would be to simply treat them as offsets, and supply those as coordinates to your intensity() method in whatever order they're needed .

So, for your first example you might supply
  {1, -1}, {1, 0}, {1, 1} for the bottom row,
  {-1, -1}, {-1, 0}, {-1, 1} for the top row, and
  {0, -1}, {0, 1} for the two on either side.

And then all you need to do is sum them with the real coordinate of the middle pixel to get the coordinates of the ones you want.

BTW, java.awt.Point is good for creating coordinates - although it's an abominable class.

HIH

Winston

Thank you
It's just a typical image I grabbed off google images.
How do I constrain things within a fixed 3x3 grid? if I have thousands of pixels in an image.
Thinking some type of loop that constraints things but not sure how to set things up
I thought everything start at 0,0 in a grid or pixels. where are there negative signs?
Would the grid be like this?
{-1, -1}, {-1, 0}, {-1, 1}
{0, -1}, {0, 0}, {0, 1}
{1, -1}, {1, 0}, {1, 1}

Then 0,0 being the target pixel. So then I'd want to gather information about all the pixels that surround it. Still pretty confused on the constraining a 3x3 grid.
I guess it would go through a loop, each time it goes through a loop it would lock in a 3x3 grid then to the next and so on?


 
Justin Robbins
Ranch Hand
Posts: 121
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think Java will throw an error if it's negative, right? because it doesn't include negative coordinates? because it's outside of the image. How would I account for that?
I must only account for the pixels that are inside of the image but I am having trouble making sure that's always the case. Should I do something like add some padding somehow? how do I guarantee to only use the pixels that exist within the image and then set pixel (0,0) to that average

Thanks
 
Paul Clapham
Sheriff
Posts: 22482
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It seems to me that what you're trying to say is "But the pixels on the edge aren't surrounded by 8 other pixels." Yes, that's true. So you should ignore them in your processing.

You ignored the question about how you were storing the pixels so it's impossible to advise how to process those pixels.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Justin Robbins wrote:I thought everything start at 0,0 in a grid or pixels. where are there negative signs?

I thought I'd explained myself. Those are offsets from the pixel in the centre.

So if it's at {376, 1143}, then {-1, -1} (the top left pixel) wil be at {376 + -1, 1143 + -1}.

- ie. {375, 1142}.

Winston
 
Justin Robbins
Ranch Hand
Posts: 121
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I thought I'd explained myself. Those are offsets from the pixel in the centre.

So if it's at {376, 1143}, then {-1, -1} (the top left pixel) wil be at {376 + -1, 1143 + -1}.

- ie. {375, 1142}.

Winston


Could you explain some more about offsets, feel I don't understand them. What is meant by if it's at {376, 1143} where is this what does this mean? is this like the height and width of an image? So is offsetting sort of like a failsafe so that the loops don't grab pixels that are off the grid?
 
Paul Clapham
Sheriff
Posts: 22482
43
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Instead of designing from the inside out, design from the outside in. First of all you want a loop which goes through each pixel which isn't on the outside of the grid. So if the grid entries were numbered from 0 to width-1 across and from 0 to height-1 down, then you'd want to iterate from 1 to width-2 across and from 1 to height-2 down. What you're going to do with each of those pixels, doesn't matter yet. Start with writing that loop.

That does assume you have a rectangular array of pixels. If you've got something else, you're going to have to do more work to loop through the pixels.
 
Piet Souris
Rancher
Posts: 1979
67
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Have a look at the 'ConvolveOp' class. It lets you specify a source image, a destination image and a matrix that can do exactly what you want.
Be warned though: the API's are not particularly easy to understand, neither, so was my experiene, are they very fast.
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Justin Robbins wrote:Could you explain some more about offsets, feel I don't understand them. What is meant by if it's at {376, 1143} where is this what does this mean? is this like the height and width of an image?

Yes. And TBH (no offence intended), if you don't understand how pixels are arranged, I'm wondering if you're quite ready for this assignment.
Don't worry, you will be ... just maybe not this week.

However, very briefly, an image is usually a grid of pixels whose size is defined by a height (in rows) and width (in columns). A specific pixel will be defined by a coordinate specifying its position as a row and column number, both numbered from 0. Therefore, a pixel "at" (ie, with with the coordinates) {376, 1143} will be in the 377th row and the 1144th column (coordinate numbering is from 0 remember).

So is offsetting sort of like a failsafe so that the loops don't grab pixels that are off the grid?

No, its a generic way of representing a position relative to another one.

In your examples, you have 8 points "around" a pixel that you want to process in a specific sequence. From your first diagram:

[ T, T, T ]
[ L, M, R ]
(I added 'L' and 'R' for 'left' and 'right')
[ B, B, B ]

The only thing is that, right now, you don't know where 'M' is.

However, just by looking at the diagram, you can immediately tell something about 'L' - its row is the same as 'M's, and its column is 1 less than 'M's.
That gives you an offset of {0, -1} (coordinates are always in row,column order), and it is the same regardless of where 'M' is in the grid.

Once you DO know 'M's position - eg, {376, 1143} - you can use the offset to work out where 'L' is by simply adding the two together:
  {376, 1143} + {0, -1} == {376 + 0, 1143 + -1} == {376, 1142}

If you prefer, you can think of an offset as treating 'M' as if it were at position {0, 0}, and defining a position relative to it.
But the main thing to remember is that (at least in your case) offsets don't change.

So, you can define offsets for the 8 points around a pixel and use them in whatever order you like; and when you finally know where 'M' is, also use them to get the positions of the other 8 pixels you want.

Hope I've explained it a bit better now, but I agree with Paul's last post completely:
Take things one at a time, and work out how to go through the pixels you want FIRST. One you have that working, then you can worry about processing "surrounding" pixels.

Winston
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
BTW, one thing that I find useful when dealing with grids, and specifically when dealing with squares or directions (or pixels) from a specific position is to use compass points. Eg, from your diagram:
You may find it useful or not, but I thought it might be worth mentioning.

Winston
 
Piet Souris
Rancher
Posts: 1979
67
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To be even more concrete:

have a look at the BufferedImage class, and its method 'getRGB'.

Be aware that the 'x' is the column number, 'y' the row number.

Also, look at the tutorial about the fork-join-framework
(https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html)
where an example is given about blurring an image.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!