Line structuring element in any orientations

(Jonas Lamy) #1

Hello,

I’m trying to implement “The Multiscale Bowler-Hat Transform for Vessel Enhancement in 3D Biomedical Images” by creating a custom itk filter.

They use morphological grayscale openings with a combination of spheres and 3D lines structuring elements. The lines structuring elements are oriented in several directions.

I would like to know how to make 3D oriented line structuring elements with ITK.

There is the itkFlatStructuringElement, but I don’t know if the Box function is the one I’m looking for. The documentation is a bit short and the examples on the wiki have been removed with the near ITK 5.0 release.

I also found the LineIterator to draw custom lines using two points. But the result probably won’t be usable by GrayscaleMorphologicalOpeningFilter…

Any pointers on how to proceed ?

Thank you.

(Matt McCormick) #2

Hello @Jonas

Welcome to the ITK community! :sunny:

Awesome!

Yes, you are on the right track. Depending on what you want, AddLine, FromImage, or Polygon are likely closer than Box for your application. The itk::FlatStructuringElement source code and the ITK Software Guide have more details or a higher level overview, respectively.

Please let us know how it goes!

(Tim Evain) #3

Hello @Jonas

When I have to create a custom structuring element, I usually go back to the Neighborhood base class.
For a small example, you can see this post I made a while back on the same topic.

HTH,

Tim

1 Like
(Jonas Lamy) #4

Thank you both for your input.

I want to stay close to the original matlab implementation. They use points uniformly distributed on a sphere to create orientations.

This is what I did :

  • Get a point generated on that sphere and his symmetric equivalent across the center (P1 & P2)
  • Create a boolean image
  • Use a LineIterator to draw the line between P1 and P2 in the image.
  • feed the image to an itkFlatStructuringElement using the FromImage function.

It seems to work. I still have a few things to check, but it’s going in the right direction.
I’ll keep you informed when the full filter is finished :wink:

2 Likes
(Jonas Lamy) #5

@matt.mccormick
I need your input once more because I’m doing something wrong here…

// A bit of typedef context
typename TInputImage::Pointer input = TInputImage::New();
input->Graft( const_cast<TInputImage*>( this->GetInput() ));
using LineSeType = FlatStructuringElement<3>;
using OpeningLineFilterType =GrayscaleMorphologicalOpeningImageFilter
<TInputImage,TInputImage,LineSeType>;
auto openingLineFilter = OpeningLineFilterType::New();
openingLineFilter->SetInput( input );

// Problematic code portion
LineSeType lineSe;
lineSeImage = line3D(s,v[n],1.0,1.0,1.0);
// Viewing structuring element image for debug purpose
auto castFilter = CastImageFilter<itk::Image<bool,3>,itk::Image<int,3>>::New();
castFilter->SetInput(lineSeImage);
itk::ViewImage<itk::Image<int,3>>::View(castFilter->GetOutput() );
openingLineFilter->SetKernel( lineSe.FromImage(lineSeImage) );
openingLineFilter->Update();
auto imLine = openingLineFilter->GetOutput();
// viewing Opening image for debug purpose
itk::ViewImage::View(imLine);

From my previous post the first 3 steps are doing great. I managed to create a 3D boolean image (odd dimensions as the documentation requires) with the structuring element. As you can see in the picture below.

But the output of the opening is really bad…There are big overflow values on the image boundaries (3.5 +300) and a constant value inside (128).

My original picture is this one with a grayscale gradient ( to mimic vessels disappearing in the tissue)

The opening is doing fine with a ball structuring element…My error should comme for the highlighted line.
What did I do wrong ?

(Matt McCormick) #6

Since SetKernel takes a reference and FromImage is a static method, try assigning to an instance, e.g.:

LineSeType kernel =  lineSe.FromImage(lineSeImage);
openingLineFilter->SetKernel( kernel )