Why should we do a Reverse on the image data after an ImageTake ?

For example:

OIcut = ImageTake[OIBW, {80, 160}, {90, 170}]

OIrev = Reverse[ImageData[OIcut]];
ListDensityPlot[OIrev, ColorFunction -> GrayLevel]

I see the image gets a little smoother and probably brighter. Any idea why this happens after an ImageTake?

  • 3
    $\begingroup$ The reversal is needed simply because different coordinate systems are in use. The coordinate system for images is different from the Cartesian coordinate system implicit in the density plots, and we thus have to do a transformation. $\endgroup$ – J. M.'s technical difficulties Jun 22 '13 at 4:34
  • $\begingroup$ In other words: it has nothing to do with ImageTake at all. If you tried to do the same ListDensityPlot with the original OIBW image, you'd have to Reverse its ImageData too. $\endgroup$ – user484 Jun 22 '13 at 5:16
  • 2
    $\begingroup$ By the way: "ImageData accepts a DataReversed option. With DataReversed->True, the order of the rows is reversed." $\endgroup$ – cormullion Jun 22 '13 at 8:27

This problem is endemic to all programs that handle images/graphics and matrices. Why? Because there are two different coordinate systems in common use. Images, like graphics, use regular Cartesian coordinates. For example, the point (1,2) means one to the right and two up. The point (10, 3) means 10 to the right and 3 up. The origin is effectively in the bottom-left and the two coordinates are indices into the (column, row).

Contrast this with matrices. Here the convention is

a11 a12 a13
a21 a22 a23
a31 a32 a33

In this arrangement, the origin is effectively at the top left and the two coordinates index into the (row, column). The symptom you see (having to Reverse the ImageData) is a result of this dual-origin problem.

You can see this dual-system at work by clicking on an image. Choose "get coordinates" and the coordinate system for the image has (1,1) in the lower left. But if you choose "get indices" then the coordinate system starts in the top left. Coordinates are the image coordinates, indices index into ImageData. So for instance, ImageValue[img, {1, 1}] gives the bottom left pixel value. The documentation tries to reduce this confusion by using words like "gives the pixel value of image at position {x,y}" (for example, see the help for ImageValue) to refer to image (Cartesian) coordinates, while it uses "row," "column," and "index" when it is using matrix-indices (for example, see the help file for ImageTake).

Not quite as deep as Cartesian duality, but confusing enough for anyone using images in Mathematica or Matlab.

| improve this answer | |
  • $\begingroup$ I think you mean that images don't use regular Cartesian coordinates. The "first" row of an image is the top row, like matrices. Consider Through@{Image, MatrixPlot, Graphics@Raster@# &, ListDensityPlot}@ IdentityMatrix@5 $\endgroup$ – Simon Woods Jun 22 '13 at 16:08
  • $\begingroup$ @Simon Woods -- I added more explanation and some references to the help files to try and clarify: row/column are index forms (like a matrix) while position/pixel coordinates are Cartesian forms. $\endgroup$ – bill s Jun 22 '13 at 17:31
  • $\begingroup$ I think that's much clearer now. +1 $\endgroup$ – Simon Woods Jun 22 '13 at 17:41
  • $\begingroup$ There's also a difference concerning the position of the center of a pixel. One system starts at the bottom left of a pixel, the other uses the center as reference. $\endgroup$ – Sjoerd C. de Vries Jul 1 '13 at 5:37
  • $\begingroup$ I think this is a very good topic for this question. Can you formulate an answer there (perhaps including the obvious transformation functions between both coordinate systems)? $\endgroup$ – Dr. belisarius Aug 14 '13 at 13:21

Not the answer you're looking for? Browse other questions tagged or ask your own question.