ImageData reverses the order of the row of an Image [duplicate]

Could someone convince me what is the utility of doing a function like ImageData that reverses the order of rows in an image? Why was it coded like this? Why does it not return the normal order of the rows? Would that not be better? What is the secret behind doing such programming? Please answer me!

• Same to the options of Modulus.Many function have this option.Usless for me.So just let it alone.
– yode
Mar 18 '16 at 4:56
• This is not a Mathematica issue. Mathematica is simply following the normal conventions of image processing. You would have same issue if you were coding in Java. Mar 18 '16 at 11:05
• If I'm reading this right, this was all tackled in here. Mar 18 '16 at 12:02

(I'm not sure what you mean; by default ImageData doesn't reverse anything. I'm going to assume your question is about the difference between coordinates and indices.)

Mathematical convention. In practically any textbook, graphs/plots are drawn with the x-axis pointing right, the y-axis pointing up, and the origin usually at 0/0. And indices in matrices are virtually always in the form (row/column), where the top row is 1 and the left column 1. If you get an image from any source (digital camera, image file, TV signal), it will almost always be in that order (row-major, starting at the top), too.

Sadly, this mismatch between conventions exists, and any computer graphics system has to deal with it. One way is to use an "upside down" coordinate system (like e.g. OpenCV): The result is that every time you plot a chart, you'll have calculations like plotHeight - y*scaleFactor to invert the y-direction.

The Mathematica designers decided to stick to the "y-axis is up" convention instead (probably because it makes plotting so much easier and Mathematica supported plots long before it supported image processing). The result is that you have to do analogous {imageHeight - row,col - 1} calculations every time you convert from indices to graphics coordinates.

Luckily, WRI seems to have noticed that this is awkward, and the newer image processing functions like ImageTrim or PixelValue all work consistently with coordinates. So if you stick to these, you can write code that simply uses coordinates (almost) everywhere, and never think about index/coordinate conversions.

• One could always use Rescale[] for better readability of the conversions, if need be. Mar 18 '16 at 12:03

Is this a coincidence, that this subject was touched upon in the QA next door?

Anyway, I'd like to just echo, that ImageData[image][[row,col]] gives you the pixel value in row row and column col, where, as @nikie pointed out, the "coordinate" row is measured from top to bottom. But if you want to get the pixel at {x, y} in the sense of coordinates, this is as trivial as

ImageData[ImageRotate[image, -Pi/2]][[x, y]]

And not only does y now measure from the bottom up, but as a bonus, you get the natural ordering for coordinates - the x value comes first, the y value after it.

• But indices still start at 1, coordinates at 0. Plus, rotating the whole image just to get one pixel is horribly inefficient. I'd prefer with GetPixelValue... Mar 18 '16 at 13:25
• @nikie Probably true, rotation is an overhead. Pixels are countable, though. Is {0,0} the bottom left pixel or the bottom left corner of the image and pixels are centered at half-integer points? Mar 18 '16 at 13:47
• @nikie Oh my, how right you are. I really ought to just roll a wrapper for the coordinate specification of ImageTake Mar 18 '16 at 13:50