ANIMA  4.0
animaNLMeans.cxx
Go to the documentation of this file.
3 #include <tclap/CmdLine.h>
4 
5 #include <itkImage.h>
6 #include <itkCommand.h>
7 
8 //Update progression of the process
9 void eventCallback (itk::Object* caller, const itk::EventObject& event, void* clientData)
10 {
11  itk::ProcessObject * processObject = (itk::ProcessObject*) caller;
12  std::cout<<"\033[K\rProgression: "<<(int)(processObject->GetProgress() * 100)<<"%"<<std::flush;
13 }
14 
15 int main(int ac, const char** av)
16 {
17 
18  TCLAP::CmdLine cmd("INRIA / IRISA - VisAGeS/Empenn Team", ' ',ANIMA_VERSION);
19 
20  TCLAP::ValueArg<std::string> inputArg("i",
21  "input",
22  "A noisy image",
23  true,
24  "",
25  "A noisy image",
26  cmd);
27 
28  TCLAP::ValueArg<std::string> outputArg("o",
29  "output",
30  "Output denoised image",
31  true,
32  "",
33  "Output denoised image",
34  cmd);
35 
36  TCLAP::ValueArg<unsigned int> weightMethod("W",
37  "weight",
38  "Thr weight method -> 0: Exponential, 1: Rician, default: Exponential(0)",
39  false,
40  0,
41  "The Weighting method",
42  cmd);
43 
44  TCLAP::ValueArg<double> weightThrArg("w",
45  "weightThr",
46  "Weight threshold: patches around have to be similar enough -> default: 0.0",
47  false,
48  0.0,
49  "Weight threshold",
50  cmd);
51 
52  TCLAP::ValueArg<double> betaArg("b",
53  "beta",
54  "Beta parameter for local noise estimation -> default: 1",
55  false,
56  1,
57  "Beta for local noise estimation",
58  cmd);
59 
60  TCLAP::ValueArg<double> meanMinArg("m",
61  "meanMin",
62  "Minimun mean threshold (default: 0.95)",
63  false,
64  0.95,
65  "Minimun mean threshold",
66  cmd);
67 
68  TCLAP::ValueArg<double> varMinArg("v",
69  "varMin",
70  "Minimun variance threshold -> default: 0.5",
71  false,
72  0.5,
73  "Minimun variance threshold",
74  cmd);
75 
76  TCLAP::ValueArg<unsigned int> nbpArg("p",
77  "nbp",
78  "Number of threads to run on -> default : automatically determine",
79  false,
80  itk::MultiThreaderBase::GetGlobalDefaultNumberOfThreads(),
81  "Number of threads",
82  cmd);
83 
84  TCLAP::ValueArg<unsigned int> patchHSArg("S",
85  "patchHalfSize",
86  "Patch half size in each direction -> default: 1",
87  false,
88  1,
89  "patch half size",
90  cmd);
91 
92  TCLAP::ValueArg<unsigned int> patchSSArg("s",
93  "patchStepSize",
94  "Patch step size for searching -> default: 1",
95  false,
96  1,
97  "Patch search step size",
98  cmd);
99 
100  TCLAP::ValueArg<unsigned int> patchNeighArg("n",
101  "patchNeighborhood",
102  "Patch half neighborhood size -> default: 5",
103  false,
104  5,
105  "Patch search neighborhood size",
106  cmd);
107 
108  try
109  {
110  cmd.parse(ac,av);
111  }
112  catch (TCLAP::ArgException& e)
113  {
114  std::cerr << "Error: " << e.error() << "for argument " << e.argId() << std::endl;
115  return EXIT_FAILURE;
116  }
117 
118  // Find out the type of the image in file
119  itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(inputArg.getValue().c_str(),
120  itk::ImageIOFactory::ReadMode);
121 
122  if( !imageIO )
123  {
124  std::cerr << "Itk could not find a suitable IO factory for the input" << std::endl;
125  return EXIT_FAILURE;
126  }
127 
128  // Now that we found the appropriate ImageIO class, ask it to read the meta data from the image file.
129  imageIO->SetFileName(inputArg.getValue());
130  imageIO->ReadImageInformation();
131 
132  unsigned int const nbDimension = imageIO->GetNumberOfDimensions ();
133  std::cout<<"Image has "<<nbDimension<<" dimension.\n";
134 
135  itk::CStyleCommand::Pointer callback = itk::CStyleCommand::New();
136  callback->SetCallback(eventCallback);
137 
138  switch(nbDimension)
139  {
140  case 2:
141  {
142  std::cout<<"preparing filter..." << std::endl;
143 
144  typedef itk::Image<double, 2> ImageType;
146 
147  FilterType::Pointer filter = FilterType::New();
148  filter->SetInput(anima::readImage <ImageType> (inputArg.getValue()));
149 
150  filter->SetWeightThreshold(weightThrArg.getValue());
151  filter->SetPatchHalfSize(patchHSArg.getValue());
152  filter->SetSearchStepSize(patchSSArg.getValue());
153  filter->SetSearchNeighborhood(patchNeighArg.getValue());
154  filter->SetBetaParameter(betaArg.getValue());
155  filter->SetMeanMinThreshold(meanMinArg.getValue());
156  filter->SetVarMinThreshold(varMinArg.getValue());
157  filter->SetWeightMethod(FilterType::EXP);
158  if (weightMethod.getValue())
159  filter->SetWeightMethod(FilterType::RICIAN);
160 
161  filter->SetNumberOfWorkUnits(nbpArg.getValue());
162 
163  filter->AddObserver(itk::ProgressEvent(), callback );
164  filter->Update();
165 
166  try
167  {
168  anima::writeImage <ImageType> (outputArg.getValue(),filter->GetOutput());
169  }
170  catch( itk::ExceptionObject & err )
171  {
172  std::cerr << "Itk cannot write output, be sure to use a valid extension..." << std::endl;
173  std::cerr << err << std::endl;
174  return EXIT_FAILURE;
175  }
176  break;
177  }
178 
179  case 3:
180  {
181  std::cout<<"preparing filter..." << std::endl;
182 
183  typedef itk::Image<double, 3> ImageType;
185 
186  FilterType::Pointer filter = FilterType::New();
187  filter->SetInput(anima::readImage <ImageType> (inputArg.getValue()));
188 
189  filter->SetWeightThreshold(weightThrArg.getValue());
190  filter->SetPatchHalfSize(patchHSArg.getValue());
191  filter->SetSearchStepSize(patchSSArg.getValue());
192  filter->SetSearchNeighborhood(patchNeighArg.getValue());
193  filter->SetBetaParameter(betaArg.getValue());
194  filter->SetMeanMinThreshold(meanMinArg.getValue());
195  filter->SetVarMinThreshold(varMinArg.getValue());
196  filter->SetWeightMethod(FilterType::EXP);
197  if (weightMethod.getValue())
198  filter->SetWeightMethod(FilterType::RICIAN);
199 
200  filter->SetNumberOfWorkUnits(nbpArg.getValue());
201 
202  filter->AddObserver(itk::ProgressEvent(), callback );
203  filter->Update();
204 
205  try
206  {
207  anima::writeImage <ImageType> (outputArg.getValue(),filter->GetOutput());
208  }
209  catch( itk::ExceptionObject & err )
210  {
211  std::cerr << "Itk cannot write output, be sure to use a valid extension..." << std::endl;
212  std::cerr << err << std::endl;
213  return EXIT_FAILURE;
214  }
215  break;
216  }
217  case 4:
218  {
219  std::cerr<<"WARNING !\nInput is a 4D image, you should use the animaNLMeans-temporal command.\nContinue anyway? (y/n) ";
220  char ans;
221  do
222  {
223  std::cin>>ans;
224  if (ans == 'n')
225  return 0;
226 
227  else if (ans != 'y')
228  {
229  std::cerr<<"Please press \"n\" or \"y\".\nContinue anyway? (y/n) ";
230  }
231  }
232  while(ans != 'y');
233 
234  std::cout<<"preparing filter...\n";
235 
236  typedef itk::Image<double, 4> ImageType;
238 
239  FilterType::Pointer filter = FilterType::New();
240  filter->SetInput(anima::readImage <ImageType> (inputArg.getValue()));
241 
242  filter->SetWeightThreshold(weightThrArg.getValue());
243  filter->SetPatchHalfSize(patchHSArg.getValue());
244  filter->SetSearchStepSize(patchSSArg.getValue());
245  filter->SetSearchNeighborhood(patchNeighArg.getValue());
246  filter->SetBetaParameter(betaArg.getValue());
247  filter->SetMeanMinThreshold(meanMinArg.getValue());
248  filter->SetVarMinThreshold(varMinArg.getValue());
249  filter->SetWeightMethod(FilterType::EXP);
250  if (weightMethod.getValue())
251  filter->SetWeightMethod(FilterType::RICIAN);
252 
253  filter->SetNumberOfWorkUnits(nbpArg.getValue());
254 
255  filter->AddObserver(itk::ProgressEvent(), callback );
256  filter->Update();
257 
258  try
259  {
260  anima::writeImage <ImageType> (outputArg.getValue(),filter->GetOutput());
261  }
262  catch( itk::ExceptionObject & err )
263  {
264  std::cerr << "Itk cannot write output, be sure to use a valid extension..." << std::endl;
265  std::cerr << err << std::endl;
266  return EXIT_FAILURE;
267  }
268  break;
269  }
270  default:
271  {
272  itk::ExceptionObject excp;
273  excp.SetDescription("The file uses a number of dimension that is not supported in this application");
274  throw excp;
275  }
276  }
277 
278  std::cout << std::endl;
279 
280  return EXIT_SUCCESS;
281 }
void eventCallback(itk::Object *caller, const itk::EventObject &event, void *clientData)
Definition: animaNLMeans.cxx:9
int main(int ac, const char **av)