ITK  5.0.0
Insight Segmentation and Registration Toolkit
CoherenceEnhancingDiffusionCommandLine.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 //
19 //
20 // Created by Jean-Marie Mirebeau on 20/11/2014.
21 //
22 //
23 
24 #ifndef itkDiffusion_CoherenceEnhancingDiffusionCommandLine_h
25 #define itkDiffusion_CoherenceEnhancingDiffusionCommandLine_h
26 
27 #include "itkImageFileReader.h"
28 #include "itkImageFileWriter.h"
31 #include "itkTimeProbe.h"
32 
33 namespace CoherenceEnhancingDiffusionCommandLine
34 {
35 
36 void Usage()
37  {
38  std::cerr <<
39  "Input image filename. 2D and 3D images supported. Required.\n" <<
40  "Output image filename. Required.\n" <<
41  "Diffusion time. Suggested range: 0.5-5, up to 50 for strong noise. Default: 2.\n" <<
42  "Lambda. Small values detect more edges. Suggested range: 0.05, 0.0001. Default: 0.01\n" <<
43  "Weickert diffusion type. Accepted values: CED, cCED, EED, cEED, Isotropic. Default: CED.\n" <<
44  "Noise scale. Suggested range: 0.5 - 4. Default 1.\n" <<
45  "Feature scale. Suggested range: 2-6. Default 2.\n"
46  << "\n";
47  }
48 
49 using namespace itk;
50 
51 int Execute(int argc, char * argv[]);
52 
53 template<int VDimension>
54 int Execute(int argc, char * argv[], itk::ImageIOBase::IOComponentType, int nComponents);
55 
56 template<int VDimension, typename ScalarType, typename ComponentType>
57 int Execute(int argc, char * argv[], int nComponents);
58 
59 template<int VDimension, typename ScalarType, typename PixelType, typename ExportPixelType>
60 int Execute(int argc, char * argv[]);
61 
62 
64 
65 int Execute(int argc, char * argv[])
66 {
67  using std::cerr;
68  using std::endl;
69  using namespace itk;
70 
71  if(argc < 2 + 1 )
72  {
73  Usage();
74  return EXIT_SUCCESS;
75  }
76 
77  const char * imageFileName = argv[1];
78 
80  if( imageIO.IsNull() )
81  {
82  std::cerr << "Could not create ImageIO" << std::endl;
83  return EXIT_FAILURE;
84  }
85  imageIO->SetFileName( imageFileName );
86  imageIO->ReadImageInformation();
87 
88  const unsigned int imageDimension = imageIO->GetNumberOfDimensions();
89  const itk::ImageIOBase::IOComponentType componentType = imageIO->GetComponentType();
90  const unsigned int nComponents = imageIO->GetNumberOfComponents();
91 
92  switch( imageDimension )
93  {
94  case 2:
95  return Execute<2>(argc,argv,componentType,nComponents);
96  case 3:
97  return Execute<3>(argc,argv,componentType,nComponents);
98  default:
99  itkGenericExceptionMacro("Sorry, unsupported image dimension.");
100  }
101 }
102 
103 template<int Dimension>
104 int Execute(int argc, char * argv[], itk::ImageIOBase::IOComponentType componentType, int nComponents)
105 {
106  switch(componentType)
107  {
109  return Execute<Dimension, float, unsigned char>(argc,argv,nComponents);
111  return Execute<Dimension, float, float>(argc,argv,nComponents);
113  return Execute<Dimension, double, double>(argc,argv,nComponents);
114  default:
115  itkGenericExceptionMacro("Sorry, unsupported component type");
116  }
117 }
118 
119 template<int Dimension, typename ScalarType, typename ComponentType>
120 int Execute(int argc, char * argv[], int nComponents)
121 {
122  switch(nComponents)
123  {
124  case 1:
125  return Execute<Dimension,ScalarType,ScalarType,ComponentType>(argc,argv);
126  case 2:
127  return Execute<Dimension,ScalarType,Vector<ScalarType,2>,Vector<ComponentType,2> >(argc,argv);
128  case 3:
129  return Execute<Dimension,ScalarType,Vector<ScalarType,3>,Vector<ComponentType,3> >(argc,argv);
130  default:
131  itkGenericExceptionMacro("Sorry, unsupported number of components");
132  }
133 }
134 
135 template<int Dimension, typename ScalarType, typename PixelType, typename ExportPixelType>
136 int Execute(int argc, char * argv[])
137 {
138  using ImageType = Image<PixelType,Dimension>;
139 
140  using ReaderType = ImageFileReader<ImageType>;
141  typename ReaderType::Pointer reader = ReaderType::New();
142 
143  const char * imageFileName = argv[1];
144  const char * outputFileName = argv[2];
145  reader->SetFileName(imageFileName);
146 
148  typename DiffusionFilterType::Pointer diffusionFilter = DiffusionFilterType::New();
149  diffusionFilter->SetInput(reader->GetOutput());
150 
152  diffusionFilter->AddObserver(ProgressEvent(), reportDiffusionProgress);
153 
154  int argIndex = 3;
155  if( argIndex < argc )
156  {
157  const double diffusionTime = std::stod(argv[argIndex++]);
158  if(diffusionTime==0) itkGenericExceptionMacro("Error: Unrecognized diffusion time (third argument).\n");
159  diffusionFilter->SetDiffusionTime(diffusionTime);
160  }
161 
162  if( argIndex < argc )
163  {
164  const double lambda = std::stod(argv[argIndex++]);
165  if(lambda==0.) itkGenericExceptionMacro("Error: Unrecognized lambda (fourth argument).\n");
166  diffusionFilter->SetLambda(lambda);
167  }
168 
169  if( argIndex < argc )
170  {
171  const char * enhancement = argv[argIndex++];
172  if(!strcmp(enhancement,"EED"))
173  diffusionFilter->SetEnhancement(DiffusionFilterType::EED); // Weickert's exponent : 4.
174  else if(!strcmp(enhancement,"cEED"))
175  diffusionFilter->SetEnhancement(DiffusionFilterType::cEED); // Weickert's exponent : 4.
176  else if(!strcmp(enhancement,"CED"))
177  diffusionFilter->SetEnhancement(DiffusionFilterType::CED); // Weickert's exponent : 2.
178  else if(!strcmp(enhancement, "cCED"))
179  diffusionFilter->SetEnhancement(DiffusionFilterType::cCED); // Weickert's exponent : 2.
180  else if(!strcmp(enhancement, "Isotropic"))
181  diffusionFilter->SetEnhancement(DiffusionFilterType::Isotropic); //Perona-Mali's exponent: 2.
182  else
183  itkGenericExceptionMacro("Error: Unrecognized enhancement (fifth argument).\n");
184  }
185 
186  if( argIndex < argc )
187  {
188  const double noiseScale = std::stod(argv[argIndex++]);
189  if(noiseScale==0.) itkGenericExceptionMacro("Error: Unrecognized noiseScale (sixth argument).\n");
190  diffusionFilter->SetNoiseScale(noiseScale);
191  }
192 
193  if( argIndex < argc )
194  {
195  const double featureScale = std::stod(argv[argIndex++]);
196  if(featureScale==0.) itkGenericExceptionMacro("Error: Unrecognized featureScale (seventh argument).\n");
197  diffusionFilter->SetFeatureScale(featureScale);
198  }
199 
200  if( argIndex < argc )
201  {
202  const double exponent = std::stod(argv[argIndex++]);
203  if(exponent==0.) itkGenericExceptionMacro("Error: Unrecognized exponent (eighth argument).\n");
204  diffusionFilter->SetExponent(exponent);
205  }
206 
207  if( argIndex < argc )
208  {
209  itkGenericExceptionMacro("Error: excessive number of arguments");
210  }
211 
212  /*{
213  std::cerr <<
214  "T: " << diffusionFilter->GetDiffusionTime() << "\n" <<
215  "Lambda: " << diffusionFilter->GetLambda() << "\n" <<
216  "argc: " << argc << "\n";
217 
218  diffusionFilter->Update();
219  auto image = diffusionFilter->GetOutput();
220  std::cerr <<
221  image->GetBufferedRegion() << "\n\n" <<
222  "pixel export size: " << sizeof(ExportPixelType) << "\n";
223 ;
224 
225  }*/
226 
227  using ExportImageType = Image<ExportPixelType,Dimension>;
229  typename CasterType::Pointer caster = CasterType::New();
230  caster->SetInput(diffusionFilter->GetOutput());
231 
232  //using ScalarImageType = typename DiffusionFilterType::ScalarImageType;
233  using WriterType = ImageFileWriter<ExportImageType>;
234  typename WriterType::Pointer writer = WriterType::New();
235  writer->SetInput(caster->GetOutput());
236  writer->SetFileName(outputFileName);
237 
238  itk::TimeProbe clock;
239  clock.Start();
240  writer->Update();
241  clock.Stop();
242  std::cout << "Took: " << clock.GetMean() << " seconds\n";
243 
244  return EXIT_SUCCESS;
245 }
246 
247 } // end namespace CoherenceEnhancingDiffusionCommandLine
248 
249 #endif
virtual MeanType GetMean() const
Computes the time passed between two points in code.
Definition: itkTimeProbe.h:44
LinearAnisotropicDiffusionCommandLine::ReportProgressToCOutType ReportProgressToCOutType
A templated class holding a n-Dimensional vector.
Definition: itkVector.h:62
virtual void Stop()
Coherence enhancing diffusion and edge enhancing diffusion.
virtual void Start()
SmartPointer< Self > Pointer
Definition: itkCommand.h:52
Writes image data to a single file.
Data source that reads image data from a single file.
static ImageIOBasePointer CreateImageIO(const char *path, FileModeType mode)
Templated n-dimensional image class.
Definition: itkImage.h:75
Casts input pixels to output pixel type.