erode/dilate performing opposite effect to expected

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

erode/dilate performing opposite effect to expected

Walter O'Dell PhD
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.
Reply | Threaded
Open this post in threaded view
|

Re: erode/dilate performing opposite effect to expected

Gabriel Landini
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