Extracting mesh from itk::AntiAliasBinaryImageFilter?

All–

I am currently using marching cubes [1] to extract a mesh from a binarized volume. However, the surface area of the resulting mesh somewhat overestimates ground truth estimates due to the pixelation artifacts. I recently came across the anti-aliasing filter [2], which seems to address exactly this issue. However, I’m now unsure of how to extract the zero-crossing isosurface as a mesh. I naively tried adding [2] into my pipeline immediately before [1], but get no output. Am I using the marching cubes filter incorrectly, or is there perhaps another filter for this purpose?

Best, and thanks,

–Davis

p.s. Code, adapted from the wiki example. Produces no mesh output.

#include <itkAntiAliasBinaryImageFilter.h>
#include <itkBinaryMask3DMeshSource.h>
 
const unsigned int Dimension = 3; 
using TIntegral = unsigned char;
using TReal = float;

using TMesh   = itk::Mesh< TReal, Dimension >;
using TIntegralImage = itk::Image< TIntegral, Dimension>;
using TRealImage = itk::Image<TReal, Dimension>;

using TAntiAlias = itk::AntiAliasBinaryImageFilter <TIntegralImage, TRealImage>;
using TMeshSource = itk::BinaryMask3DMeshSource< TRealImage, TMesh >;
 
static void CreateImage(TIntegralImage::Pointer image);
 
int main()
{

  const auto image = TIntegralImage::New();
  CreateImage(image);
 
  const auto antiAlias = TAntiAlias::New ();
  antiAlias->SetInput(image);
  antiAlias->Update();

  const auto marching = TMeshSource::New();
  marching->SetInput( antiAlias->GetOutput() );
  marching->SetObjectValue( 1.0 );
  marching->Update();

  std::cout << marching->GetOutput()->GetNumberOfPoints() << std::endl; // 0

  return EXIT_SUCCESS;
}
 
void CreateImage(TIntegralImage::Pointer image)
{
  TIntegralImage::IndexType start;
  start.Fill(0);
 
  TIntegralImage::SizeType size;
  size.Fill(200);
 
  TIntegralImage::RegionType region;
  region.SetSize(size);
  region.SetIndex(start);
 
  image->SetRegions(region);
  image->Allocate();
 
  itk::ImageRegionIterator<TIntegralImage> imageIterator(image,region);
 
  while(!imageIterator.IsAtEnd())
    {
    if(imageIterator.GetIndex()[0] - imageIterator.GetIndex()[1] > 5) // some pixels white, some black
      {
      imageIterator.Set(1);
      }
    else
      {
      imageIterator.Set(0);
      }
    ++imageIterator;
    }
 
}

[1] https://itk.org/Doxygen/html/classitk_1_1BinaryMask3DMeshSource.html
[2] https://itk.org/Doxygen/html/classitk_1_1AntiAliasBinaryImageFilter.html

I would use VTK’s Discrete Marching Cubes. Followed by WindowedSincPolyDats
. See this example:
https://lorensen.github.io/VTKExamples/site/Cxx/Modelling/SmoothDiscreteMarchingCubes/

2 Likes

You could try cuberille module of ITK. It produces a smoother mesh than marching cubes.

2 Likes

As long as it works with labels, not continuous data.

1 Like

Thanks very much to both–I will give these a try and let you know how it turns out.

1 Like