[Insight-users] Fast binary morphology dilation

Miller, James V (Research) millerjv at crd.ge.com
Tue Sep 14 11:37:53 EDT 2004


Jerome, 

For the multiple objects, I am thinking of copying the input labels to the
output as I previously mentioned.  However, I think if I replace the pixels
that have DilateValue with the BackgroundValue, then your cross without the 
center pixel may work properly.

For the check on the dimensions, I am going to try to use the
ConceptChecking
macros to ensure the proper dimensions instead of putting that code in 
GenerateInputRequestedRegion. This will force the code not to compile as
opposed to generating a runtime error.

With respect to the GenerateInputRequestedRegion, you are padding the 1 so
that 
any surface connectivity can be tracked. Shouldn't also have to pad by the 
radius of the structuring element.  In particular, 

padBy = max(m_Radius, m_Kernel.GetRadius())

using the max check will allow structuring elements that are for instance
3x3x0, i.e. a 2D kernel in a 3D volume.

Jim


-----Original Message-----
From: jerome schmid [mailto:jerome.schmid at ircad.u-strasbg.fr]
Sent: Tuesday, September 14, 2004 4:39 AM
To: Miller, James V (Research)
Cc: insight-users at itk.org
Subject: RE: [Insight-users] Fast binary morphology dilation


James,

Thanks for the interest for the filter proposed together we should improve
it.

First of all you are right for the GenerateInputRequestedRegion() function,
we must pad the input requested region. My first version did it but I cannot
remember why I remove this function...There is also a test which must be
done, for instance in this same function:

		// Test dimensions of input, output images and structuring
elements
		if( !(	TInputImage::ImageDimension ==
TOutputImage::ImageDimension && \
				TKernel::NeighborhoodDimension ==
TInputImage::ImageDimension ) )
		{
			// build an exception
			DataObjectError e(__FILE__, __LINE__);

			OStringStream msg;
			msg << static_cast<const char
*>(this->GetNameOfClass())
				<< "::GenerateInputRequestedRegion()";
			e.SetLocation(msg.str().c_str());
			e.SetDescription("The dimensions of input, output
and structuring element
must be the same.");
			throw e;
		}

This test is necessary if user plays to give a SE in 2D whereas the input
image are in 3D , etc...In fact as we manage
index internally it can be dangerous. Honestly I do not think users use an
input image in 3D with a output in 2D with a SE in 1D for instance!

I add your version with the modification attached to this mail.( I hadn't
attach the .h, the modifications are of course in the
generateInputRequestedRegion and in the GenerateData one at the beginnning
when we define the tmpRequestedRegion ). It is zipped because my previous
mail was refused, > 40 kb...

Secondly, if you want to manage your objects stuff ( some objects labeled
with #i ) I think the final loop you put is ok. I understand better your
"most appropriate background value" now however you are agree with me that
when center pixel was not on, some problems appeared previously.

Last point it is true that threading this filter can be difficult, that is
why I started with the normal version...

Regards,

Jerome

-----Message d'origine-----
De : Miller, James V (Research) [mailto:millerjv at crd.ge.com]
Envoye : lundi 13 septembre 2004 22:30
A : 'jerome schmid'
Objet : RE: [Insight-users] Fast binary morphology dilation


Jerome,

I have a few other questions on this new filter.

I am a bit confused by the "second stage" code.  I think this filter needs
a GenerateInputRequestedRegion().  The superclass' version will only request
an input requested region that matches the output requested region.  At a
minimum, the input requested region would need to be padded by one.  And I
think
it should really be padded by the m_Kernel.GetRadius().

That being said, I do not see how a pixel that "on" and on the border of the

image (defined by the LargestPossibleRegion) will ever be marked as a border
pixel.  Since the boundary condition for the oNeighIt is the background tag,

any neighboring pixel that is outside the border of the image will return
the background tag.   So the code

      // Test current pixel: it is a border pixel or an inner pixel?
      bool bIsOnContour = false;

      for (i = 0; i < neighborhoodSize; ++i)
        {
        // If at least one neighbour pixel is off the center pixel
        // belongs to contour
        if( oNeighbIt.GetPixel(i) == backgroundTag )
          {
          bIsOnContour = true;
          break;
          }
        }

will say bIsOnContour is true for a pixel that is on and one of its
neighbors is
off AND bIsOnContour is true for a pixel that is on and on the boundary of
the
image (wrt LargestPossibleRegion).

(On a side note, it is not going to be trivial to thread this filter.  The
"third stage" code is not thread safe. Multiple threads could try to write
to
the same pixel at the same time. For instance, pixels near the boundary
between
threads.)

I've attached my modified versions of your filter.

Jim


More information about the Insight-users mailing list