1 #include <tclap/CmdLine.h>     5 #include <itkSignedDanielssonDistanceMapImageFilter.h>     6 #include <itkRegionalMaximaImageFilter.h>     7 #include <itkConnectedComponentImageFilter.h>     8 #include <itkGrayscaleDilateImageFilter.h>     9 #include <itkBinaryBallStructuringElement.h>    10 #include <itkImageRegionIterator.h>    11 #include <itkExtractImageFilter.h>    15 int main(
int argc, 
char **argv)
    17     TCLAP::CmdLine cmd(
"INRIA / IRISA - VisAGeS/Empenn Team", 
' ',ANIMA_VERSION);
    19     TCLAP::ValueArg<std::string> inArg(
"i",
"input",
"Input binary image",
true,
"",
"input binary image",cmd);
    20     TCLAP::ValueArg<std::string> outArg(
"o",
"output",
"Output image",
true,
"",
"output image",cmd);
    21     TCLAP::ValueArg<unsigned int> radiusArg(
"r",
"radius",
"Dilation radius for regional maxima",
false,1,
"dilation radius",cmd);
    23     TCLAP::ValueArg<unsigned int> numThreadsArg(
"T",
"threads",
"Number of execution threads (default: all cores)",
false,itk::MultiThreaderBase::GetGlobalDefaultNumberOfThreads(),
"number of threads",cmd);
    29     catch (TCLAP::ArgException& e)
    31         std::cerr << 
"Error: " << e.error() << 
"for argument " << e.argId() << std::endl;
    35     typedef itk::Image <unsigned char,3> InputImageType;
    36     typedef itk::Image <unsigned short,3> OutputImageType;
    37     typedef itk::Image <double,3> DistanceImageType;
    39     InputImageType::Pointer inputImage = anima::readImage <InputImageType> (inArg.getValue());
    41     InputImageType::RegionType reqRegion = inputImage->GetLargestPossibleRegion();
    42     itk::ImageRegionConstIteratorWithIndex <InputImageType> inItr(inputImage,reqRegion);
    43     int xMin = reqRegion.GetSize()[0];
    45     int yMin = reqRegion.GetSize()[1];
    47     int zMin = reqRegion.GetSize()[2];
    50     InputImageType::IndexType currentIndex;
    51     while (!inItr.IsAtEnd())
    55             currentIndex = inItr.GetIndex();
    56             if (xMax < currentIndex[0])
    57                 xMax = currentIndex[0];
    58             if (yMax < currentIndex[1])
    59                 yMax = currentIndex[1];
    60             if (zMax < currentIndex[2])
    61                 zMax = currentIndex[2];
    63             if (xMin >= currentIndex[0])
    64                 xMin = currentIndex[0];
    65             if (yMin >= currentIndex[1])
    66                 yMin = currentIndex[1];
    67             if (zMin >= currentIndex[2])
    68                 zMin = currentIndex[2];
    74     xMin = std::max(0,xMin - 2);
    75     yMin = std::max(0,yMin - 2);
    76     zMin = std::max(0,zMin - 2);
    78     xMax = std::min((
int)(reqRegion.GetIndex()[0] + reqRegion.GetSize()[0] - 1),xMax + 2);
    79     yMax = std::min((
int)(reqRegion.GetIndex()[1] + reqRegion.GetSize()[1] - 1),yMax + 2);
    80     zMax = std::min((
int)(reqRegion.GetIndex()[2] + reqRegion.GetSize()[2] - 1),zMax + 2);
    82     reqRegion.SetIndex(0,xMin);
    83     reqRegion.SetIndex(1,yMin);
    84     reqRegion.SetIndex(2,zMin);
    86     reqRegion.SetSize(0,xMax - xMin + 1);
    87     reqRegion.SetSize(1,yMax - yMin + 1);
    88     reqRegion.SetSize(2,zMax - zMin + 1);
    91     typedef itk::ExtractImageFilter<InputImageType, InputImageType> ExtractFilterType;
    92     typename ExtractFilterType::Pointer extractFilter = ExtractFilterType::New();
    93     extractFilter->SetExtractionRegion(reqRegion);
    94     extractFilter->SetDirectionCollapseToGuess();
    95     extractFilter->SetInput(inputImage);
    96     extractFilter->SetNumberOfWorkUnits(numThreadsArg.getValue());
    98     typedef itk::SignedDanielssonDistanceMapImageFilter <InputImageType, DistanceImageType, OutputImageType> DistanceMapFilterType;
    99     DistanceMapFilterType::Pointer distanceMap = DistanceMapFilterType::New();
   100     distanceMap->SetInput(extractFilter->GetOutput());
   101     distanceMap->InsideIsPositiveOn();
   102     distanceMap->SetUseImageSpacing(
true);
   103     distanceMap->SetNumberOfWorkUnits(numThreadsArg.getValue());
   105     typedef itk::RegionalMaximaImageFilter <DistanceImageType,InputImageType> RegionalMaximaFilterType;
   106     RegionalMaximaFilterType::Pointer regionalFilter = RegionalMaximaFilterType::New();
   107     regionalFilter->SetInput(distanceMap->GetOutput());
   108     regionalFilter->SetFullyConnected(
true);
   109     regionalFilter->SetNumberOfWorkUnits(numThreadsArg.getValue());
   111     typedef itk::BinaryBallStructuringElement<InputImageType::PixelType,3> StructuringElementType;
   112     StructuringElementType structuringElement;
   113     structuringElement.SetRadius(radiusArg.getValue());
   114     structuringElement.CreateStructuringElement();
   116     typedef itk::GrayscaleDilateImageFilter <InputImageType,InputImageType,StructuringElementType> DilateFilterType;
   117     DilateFilterType::Pointer dilateFilter = DilateFilterType::New();
   118     dilateFilter->SetInput(regionalFilter->GetOutput());
   119     dilateFilter->SetKernel(structuringElement);
   120     dilateFilter->SetNumberOfWorkUnits(numThreadsArg.getValue());
   122     typedef itk::ConnectedComponentImageFilter <InputImageType,OutputImageType> CCFilterType;
   123     CCFilterType::Pointer ccFilter = CCFilterType::New();
   124     ccFilter->SetInput(dilateFilter->GetOutput());
   125     ccFilter->SetFullyConnected(
true);
   126     ccFilter->SetNumberOfWorkUnits(numThreadsArg.getValue());
   128     typedef itk::SignedDanielssonDistanceMapImageFilter <OutputImageType, DistanceImageType, OutputImageType> VoronoiMapFilterType;
   129     VoronoiMapFilterType::Pointer voronoiFilter = VoronoiMapFilterType::New();
   130     voronoiFilter->SetInput(ccFilter->GetOutput());
   131     voronoiFilter->SetUseImageSpacing(
true);
   132     voronoiFilter->InsideIsPositiveOff();
   133     voronoiFilter->SetNumberOfWorkUnits(numThreadsArg.getValue());
   135     voronoiFilter->Update();
   137     OutputImageType::Pointer voronoiImage = voronoiFilter->GetVoronoiMap();
   139     OutputImageType::Pointer outImage = OutputImageType::New();
   140     outImage->Initialize();
   141     outImage->SetRegions(inputImage->GetLargestPossibleRegion());
   142     outImage->SetSpacing (inputImage->GetSpacing());
   143     outImage->SetOrigin (inputImage->GetOrigin());
   144     outImage->SetDirection (inputImage->GetDirection());
   145     outImage->Allocate();
   146     outImage->FillBuffer(0);
   148     itk::ImageRegionIterator <OutputImageType> voronoiIt(voronoiImage,voronoiImage->GetLargestPossibleRegion());
   149     itk::ImageRegionIterator <OutputImageType> outIt(outImage,reqRegion);
   150     itk::ImageRegionIterator <InputImageType> inputIt(inputImage,reqRegion);
   152     while (!inputIt.IsAtEnd())
   154         if (inputIt.Get() != 0)
   155             outIt.Set(voronoiIt.Get());
   162     anima::writeImage <OutputImageType> (outArg.getValue(),outImage);
 int main(int argc, char **argv)