I have observed that erode/dilate operations perform the opposite effect to that expected.
Here is the imageJ code in ij/process/byteprocessor.java public void erode() { if (isInvertedLut()) filter(MIN); else filter(MAX); } so when the look up table (LUT) is not inverted the erode operation grabs the max value in the region of evaluation (=3x3 square). This matches the documentation on http://rsbweb.nih.gov/ij/docs/menus/process.html "Erode: Removes pixels from the edges of black objects" However, this contradicts most people's convention that erosion acts on WHITE objects in the manner above. MatLAB: http://www.mathworks.com/help/toolbox/images/f18-12508.html "Erosion: The value of the output pixel is the minimum value of all the pixels in the input pixel's neighborhood. In a binary image, if any of the pixels is set to 0, the output pixel is set to 0." http://idlastro.gsfc.nasa.gov/idl_html_help/Eroding_and_Dilating_Image_Objects.html "With grayscale images, erosion reduces the brightness (and therefore the size) of bright objects on a dark background by taking the neighborhood minimum when passing the structuring element over the image." I surmise that this comes about because ImageJ also does the opposite to expected when it applies a threshold through (top menu bar)Image->Adjust->Threshold the to an image to create a binary image. Rather than directly setting pixels above the threshold to 255 (and below to 0), it instead sets pixels above the threshold to 0 (and above to 255) and then inverts the LUT to give the correct appearance. Why they decided to do this this way I do not know, but the effect is that the LUT is now inverted so that when you call erode() with the code above it then gives the correct result. The problem is seen when you pull up an already-thresholded (binary), correct-looking image (LUT not inverted), then erode and dilate (and hence, open and close) have the opposite effect to what it is supposed to achieve. Sorry, I do not see a simple solution except to reverse the code the above while also reversing the convention when applying the threshold to both reverse the bits and invert the LUT. I would expect a change in this latter convention to permeate into many downsteam functions as well. |
On Friday 21 Oct 2011 21:10:14 Walter O'Dell PhD wrote:
> I have observed that erode/dilate operations perform the opposite effect to > that expected. Hi, This depends on the "polarity" of the image, i.e. what you call background and what foreground. > However, this contradicts most people's convention that erosion acts on > WHITE objects in the manner above. MatLAB: That is an arbitrary convention :-) and IJ is just by default using black objects. When searching for supernovas, you probably want objects to be white, but if you search for black holes, you might want them black. Some imaging packages I used before would ask you at setup time if you wanted one or the other, but IJ does not and so for me was very confusing at the start to treat all objects as dark. However a solution is to set this in the Binary Options (black background). I too prefer white objects and expect black to be 0 and white 255 so logical operations between binary images make sense too. > Rather than directly setting pixels above the threshold to 255 (and below > to 0), it instead sets pixels above the threshold to 0 (and above to 255) > and then inverts the LUT to give the correct appearance. For thresholding there is a "dark background" checkbox on the thresholder applet. That should respect the binary options setting. > Why they decided > to do this this way I do not know, but the effect is that the LUT is now > inverted so that when you call erode() with the code above it then gives > the correct result. I find inverted LUTs extremely confusing. Like you, I also want all my foreground objects to be white, so in my setup, the foreground and background colours as well as the binary options are set in the StartupMacros file, in the Autorun macro, so by default everything is processed as "white" foreground. run("Options...", "iterations=1 black pad edm=Overwrite count=1"); run("Colors...", "foreground=white background=black selection=yellow"); I hope this helps. Cheers Gabriel |
Free forum by Nabble | Edit this page |