ANIMA  4.0
animaOtsuThrImage.cxx
Go to the documentation of this file.
1 #include <tclap/CmdLine.h>
2 
3 #include <itkOtsuMultipleThresholdsImageFilter.h>
4 #include <itkExtractImageFilter.h>
5 
7 
8 #include <iostream>
9 #include <fstream>
10 
11 int main(int argc, char **argv)
12 {
13  TCLAP::CmdLine cmd("INRIA / IRISA - VisAGeS/Empenn Team", ' ',ANIMA_VERSION);
14 
15  TCLAP::ValueArg<std::string> inputArg("i","input","Input image",true,"","Input image",cmd);
16  TCLAP::ValueArg<std::string> maskArg("m","mask","Mask image for faster computation in a bounding box",false,"","Mask image",cmd);
17  TCLAP::ValueArg<std::string> outputArg("o","output","Output image",true,"","Output image",cmd);
18 
19  TCLAP::ValueArg<unsigned long> nbThresholds("n", "nbThresholds", "Number of thresholds (default : 1)",false,1,"Number of thresholds",cmd);
20 
21  try
22  {
23  cmd.parse(argc,argv);
24  }
25  catch (TCLAP::ArgException& e)
26  {
27  std::cerr << "Error: " << e.error() << "for argument " << e.argId() << std::endl;
28  return EXIT_FAILURE;
29  }
30 
31  typedef itk::Image<double,3> DoubleImageType;
32  typedef itk::Image<unsigned short,3> USImageType;
33 
34  typedef itk::OtsuMultipleThresholdsImageFilter <DoubleImageType, USImageType> OtsuMultipleThresholdsImageFilterType;
35 
36  DoubleImageType::Pointer inputImage = anima::readImage <DoubleImageType> (inputArg.getValue());
37 
38  USImageType::Pointer maskImage;
39  if (maskArg.getValue() != "")
40  maskImage = anima::readImage <USImageType> (maskArg.getValue());
41  else
42  {
43  maskImage = USImageType::New();
44  maskImage->Initialize();
45  maskImage->SetRegions(inputImage->GetLargestPossibleRegion());
46  maskImage->SetSpacing (inputImage->GetSpacing());
47  maskImage->SetOrigin (inputImage->GetOrigin());
48  maskImage->SetDirection (inputImage->GetDirection());
49  maskImage->Allocate();
50  maskImage->FillBuffer(1);
51  }
52 
53  USImageType::RegionType reqRegion = inputImage->GetLargestPossibleRegion();
54  itk::ImageRegionConstIteratorWithIndex <USImageType> maskItr(maskImage,reqRegion);
55  int xMin = reqRegion.GetSize()[0];
56  int xMax = -1;
57  int yMin = reqRegion.GetSize()[1];
58  int yMax = -1;
59  int zMin = reqRegion.GetSize()[2];
60  int zMax = -1;
61 
62  USImageType::IndexType currentIndex;
63  while (!maskItr.IsAtEnd())
64  {
65  if (maskItr.Get() != 0)
66  {
67  currentIndex = maskItr.GetIndex();
68  if (xMax < currentIndex[0])
69  xMax = currentIndex[0];
70  if (yMax < currentIndex[1])
71  yMax = currentIndex[1];
72  if (zMax < currentIndex[2])
73  zMax = currentIndex[2];
74 
75  if (xMin >= currentIndex[0])
76  xMin = currentIndex[0];
77  if (yMin >= currentIndex[1])
78  yMin = currentIndex[1];
79  if (zMin >= currentIndex[2])
80  zMin = currentIndex[2];
81  }
82 
83  ++maskItr;
84  }
85 
86  xMin = std::max(0,xMin - 2);
87  yMin = std::max(0,yMin - 2);
88  zMin = std::max(0,zMin - 2);
89 
90  xMax = std::min((int)(reqRegion.GetIndex()[0] + reqRegion.GetSize()[0] - 1),xMax + 2);
91  yMax = std::min((int)(reqRegion.GetIndex()[1] + reqRegion.GetSize()[1] - 1),yMax + 2);
92  zMax = std::min((int)(reqRegion.GetIndex()[2] + reqRegion.GetSize()[2] - 1),zMax + 2);
93 
94  reqRegion.SetIndex(0,xMin);
95  reqRegion.SetIndex(1,yMin);
96  reqRegion.SetIndex(2,zMin);
97 
98  reqRegion.SetSize(0,xMax - xMin + 1);
99  reqRegion.SetSize(1,yMax - yMin + 1);
100  reqRegion.SetSize(2,zMax - zMin + 1);
101 
102  // extract filter before and expand filter at the end to gain time
103  typedef itk::ExtractImageFilter<DoubleImageType, DoubleImageType> ExtractFilterType;
104  typename ExtractFilterType::Pointer extractFilter = ExtractFilterType::New();
105  extractFilter->SetExtractionRegion(reqRegion);
106  extractFilter->SetDirectionCollapseToGuess();
107  extractFilter->SetInput(inputImage);
108 
109  OtsuMultipleThresholdsImageFilterType::Pointer otsuMultipleThrFilter = OtsuMultipleThresholdsImageFilterType::New();
110  otsuMultipleThrFilter->SetInput(extractFilter->GetOutput());
111  otsuMultipleThrFilter->SetNumberOfThresholds(nbThresholds.getValue());
112 
113  try
114  {
115  otsuMultipleThrFilter->Update();
116  }
117  catch (itk::ExceptionObject &e)
118  {
119  std::cerr << e << std::endl;
120  return EXIT_FAILURE;
121  }
122 
123  USImageType::Pointer outImage = USImageType::New();
124  outImage->Initialize();
125  outImage->SetRegions(inputImage->GetLargestPossibleRegion());
126  outImage->SetSpacing (inputImage->GetSpacing());
127  outImage->SetOrigin (inputImage->GetOrigin());
128  outImage->SetDirection (inputImage->GetDirection());
129  outImage->Allocate();
130  outImage->FillBuffer(0);
131 
132  itk::ImageRegionIterator <USImageType> otsuIt(otsuMultipleThrFilter->GetOutput(),otsuMultipleThrFilter->GetOutput()->GetLargestPossibleRegion());
133  itk::ImageRegionIterator <USImageType> outIt(outImage,reqRegion);
134 
135  while (!otsuIt.IsAtEnd())
136  {
137  outIt.Set(otsuIt.Get());
138 
139  ++outIt;
140  ++otsuIt;
141  }
142 
143  anima::writeImage <USImageType> (outputArg.getValue(),outImage);
144 
145  return EXIT_SUCCESS;
146 }
int main(int argc, char **argv)