ANIMA  4.0
animaInfluenceZones.cxx
Go to the documentation of this file.
1 #include <tclap/CmdLine.h>
2 #include <iostream>
3 #include <string>
4 
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>
12 
14 
15 int main(int argc, char **argv)
16 {
17  TCLAP::CmdLine cmd("INRIA / IRISA - VisAGeS/Empenn Team", ' ',ANIMA_VERSION);
18 
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);
22 
23  TCLAP::ValueArg<unsigned int> numThreadsArg("T","threads","Number of execution threads (default: all cores)",false,itk::MultiThreaderBase::GetGlobalDefaultNumberOfThreads(),"number of threads",cmd);
24 
25  try
26  {
27  cmd.parse(argc,argv);
28  }
29  catch (TCLAP::ArgException& e)
30  {
31  std::cerr << "Error: " << e.error() << "for argument " << e.argId() << std::endl;
32  return EXIT_FAILURE;
33  }
34 
35  typedef itk::Image <unsigned char,3> InputImageType;
36  typedef itk::Image <unsigned short,3> OutputImageType;
37  typedef itk::Image <double,3> DistanceImageType;
38 
39  InputImageType::Pointer inputImage = anima::readImage <InputImageType> (inArg.getValue());
40 
41  InputImageType::RegionType reqRegion = inputImage->GetLargestPossibleRegion();
42  itk::ImageRegionConstIteratorWithIndex <InputImageType> inItr(inputImage,reqRegion);
43  int xMin = reqRegion.GetSize()[0];
44  int xMax = -1;
45  int yMin = reqRegion.GetSize()[1];
46  int yMax = -1;
47  int zMin = reqRegion.GetSize()[2];
48  int zMax = -1;
49 
50  InputImageType::IndexType currentIndex;
51  while (!inItr.IsAtEnd())
52  {
53  if (inItr.Get() != 0)
54  {
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];
62 
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];
69  }
70 
71  ++inItr;
72  }
73 
74  xMin = std::max(0,xMin - 2);
75  yMin = std::max(0,yMin - 2);
76  zMin = std::max(0,zMin - 2);
77 
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);
81 
82  reqRegion.SetIndex(0,xMin);
83  reqRegion.SetIndex(1,yMin);
84  reqRegion.SetIndex(2,zMin);
85 
86  reqRegion.SetSize(0,xMax - xMin + 1);
87  reqRegion.SetSize(1,yMax - yMin + 1);
88  reqRegion.SetSize(2,zMax - zMin + 1);
89 
90  // extract filter before and expand filter at the end to gain time
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());
97 
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());
104 
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());
110 
111  typedef itk::BinaryBallStructuringElement<InputImageType::PixelType,3> StructuringElementType;
112  StructuringElementType structuringElement;
113  structuringElement.SetRadius(radiusArg.getValue());
114  structuringElement.CreateStructuringElement();
115 
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());
121 
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());
127 
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());
134 
135  voronoiFilter->Update();
136 
137  OutputImageType::Pointer voronoiImage = voronoiFilter->GetVoronoiMap();
138 
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);
147 
148  itk::ImageRegionIterator <OutputImageType> voronoiIt(voronoiImage,voronoiImage->GetLargestPossibleRegion());
149  itk::ImageRegionIterator <OutputImageType> outIt(outImage,reqRegion);
150  itk::ImageRegionIterator <InputImageType> inputIt(inputImage,reqRegion);
151 
152  while (!inputIt.IsAtEnd())
153  {
154  if (inputIt.Get() != 0)
155  outIt.Set(voronoiIt.Get());
156 
157  ++inputIt;
158  ++outIt;
159  ++voronoiIt;
160  }
161 
162  anima::writeImage <OutputImageType> (outArg.getValue(),outImage);
163 
164  return EXIT_SUCCESS;
165 }
int main(int argc, char **argv)