ANIMA  4.0
animaThrImage.cxx
Go to the documentation of this file.
1 #include <itkThresholdImageFilter.h>
2 #include <itkThresholdLabelerImageFilter.h>
3 #include <itkImageRegionConstIterator.h>
4 
6 
7 #include <limits.h>
8 #include <iostream>
9 #include <fstream>
10 #include <tclap/CmdLine.h>
11 
12 using namespace std;
13 
14 int main(int argc, char **argv)
15 {
16  TCLAP::CmdLine cmd("INRIA / IRISA - VisAGeS/Empenn Team", ' ',ANIMA_VERSION);
17 
18  TCLAP::ValueArg<std::string> inputArg("i","inputimage","Input image",true,"","Input image",cmd);
19  TCLAP::ValueArg<std::string> outputArg("o","outputimage","Output image",true,"","Output image",cmd);
20  TCLAP::ValueArg<std::string> maskArg("m","maskfile","mask file",false,"","mask file",cmd);
21 
22  TCLAP::ValueArg<double> thrArg("t","thr","Threshold value",false,1.0,"Threshold value",cmd);
23  TCLAP::ValueArg<double> upperThrArg("u","uthr","Upper threshold value",false,USHRT_MAX,"Upper threshold value",cmd);
24  TCLAP::ValueArg<double> adaptThrArg("a","adaptivethr","Adaptative threshold value (between 0 and 1)",false,0.0,"adaptative threshold value",cmd);
25 
26  TCLAP::SwitchArg invArg("I","inv","Computes 1-res",cmd,false);
27 
28  try
29  {
30  cmd.parse(argc,argv);
31  }
32  catch (TCLAP::ArgException& e)
33  {
34  std::cerr << "Error: " << e.error() << "for argument " << e.argId() << std::endl;
35  return EXIT_FAILURE;
36  }
37 
38  typedef itk::Image<double,3> DoubleImageType;
39  typedef itk::Image<unsigned char, 3> UCImageType;
40 
41  typedef itk::ImageRegionConstIterator <DoubleImageType> DoubleImageIterator;
42  typedef itk::ImageRegionIterator <UCImageType> UCImageIterator;
43 
44  typedef itk::ThresholdImageFilter <DoubleImageType> ThresholdFilterType;
45  typedef itk::ThresholdLabelerImageFilter <DoubleImageType,UCImageType> LabelerFilterType;
46 
47  DoubleImageType::Pointer inputImage = anima::readImage <DoubleImageType> (inputArg.getValue());
48 
49  DoubleImageType::RegionType tmpRegionInputImage = inputImage->GetLargestPossibleRegion();
50  DoubleImageIterator doubleIt(inputImage,tmpRegionInputImage);
51 
52  unsigned int totalSize = tmpRegionInputImage.GetSize()[0]*tmpRegionInputImage.GetSize()[1]*tmpRegionInputImage.GetSize()[2];
53  std::vector <double> tmpVec (totalSize);
54 
55  unsigned int idx=0;
56 
57  if (maskArg.getValue() != "")
58  {
59  UCImageType::Pointer maskImage = anima::readImage <UCImageType> (maskArg.getValue());
60 
61  UCImageType::RegionType tmpRegionMaskImage = maskImage->GetLargestPossibleRegion();
62  UCImageIterator ucIt(maskImage,tmpRegionMaskImage);
63 
64  if ((tmpRegionInputImage.GetSize()[0]!=tmpRegionMaskImage.GetSize()[0]) ||
65  (tmpRegionInputImage.GetSize()[1]!=tmpRegionMaskImage.GetSize()[1]) ||
66  (tmpRegionInputImage.GetSize()[2]!=tmpRegionMaskImage.GetSize()[2]))
67  {
68  std::cerr << "InputImage size != MaskImage size" << std::endl;
69  return EXIT_FAILURE;
70  }
71 
72  for (unsigned int i = 0;i < totalSize;++i)
73  {
74  if(ucIt.Get() == 1)
75  {
76  tmpVec[idx] = doubleIt.Get();
77  ++idx;
78  }
79 
80  ++ucIt;
81  ++doubleIt;
82  }
83 
84  tmpVec.resize(idx);
85  }
86  else
87  {
88  idx = totalSize;
89  for (unsigned int i = 0;i < totalSize;++i)
90  {
91  tmpVec[i] = doubleIt.Get();
92  ++doubleIt;
93  }
94  }
95 
96  if ((adaptThrArg.getValue() < 0) || (adaptThrArg.getValue() > 1))
97  {
98  std::cerr << "Adaptative threshold value has to be included in the [0,1] interval" << std::endl;
99  return EXIT_FAILURE;
100  }
101 
102  unsigned int partialElt = (unsigned int)floor(adaptThrArg.getValue()*idx);
103  if (partialElt == idx)
104  partialElt = idx - 1;
105 
106  if (partialElt != 0)
107  std::partial_sort(tmpVec.begin(),tmpVec.begin() + partialElt + 1,tmpVec.end());
108 
109  double thrV = thrArg.getValue();
110  if (partialElt != 0)
111  thrV = tmpVec[partialElt];
112 
113  ThresholdFilterType::Pointer thrFilter = ThresholdFilterType::New();
114  thrFilter->SetInput(inputImage);
115 
116  double upperThr = upperThrArg.getValue();
117  if (upperThr < thrV)
118  upperThr = thrV;
119 
120  if (upperThr != USHRT_MAX)
121  thrFilter->ThresholdOutside(thrV,upperThr);
122  else
123  thrFilter->ThresholdBelow(thrV);
124 
125  try
126  {
127  thrFilter->Update();
128  }
129  catch (itk::ExceptionObject &e)
130  {
131  std::cerr << e << std::endl;
132  return EXIT_FAILURE;
133  }
134 
135  LabelerFilterType::Pointer mainFilter = LabelerFilterType::New();
136  mainFilter->SetInput(thrFilter->GetOutput());
137 
138  LabelerFilterType::RealThresholdVector thrVals;
139  thrVals.push_back(0);
140 
141  mainFilter->SetRealThresholds(thrVals);
142 
143  try
144  {
145  mainFilter->Update();
146  }
147  catch (itk::ExceptionObject &e)
148  {
149  std::cerr << e << std::endl;
150  return EXIT_FAILURE;
151  }
152 
153  if (invArg.isSet())
154  {
155  UCImageIterator resIt(mainFilter->GetOutput(),tmpRegionInputImage);
156 
157  for (unsigned int i = 0;i < totalSize;++i)
158  {
159  resIt.Set(1-resIt.Get());
160  ++resIt;
161  }
162  }
163 
164  anima::writeImage <UCImageType> (outputArg.getValue(),mainFilter->GetOutput());
165 
166  return EXIT_SUCCESS;
167 }
int main(int argc, char **argv)
STL namespace.