23 #ifndef itkLinearAnisotropicDiffusionCommandLine_h
24 #define itkLinearAnisotropicDiffusionCommandLine_h
30 namespace LinearAnisotropicDiffusionCommandLine
35 "Input image filename. 2D and 3D images supported. Required.\n" <<
36 "Output tensor field filename. Required.\n" <<
37 "Diffusion time. Required.\n" <<
38 "Output image filename. Required.\n" <<
39 "RatioToMaxStableStep. Range: ]0,1]. Default: 0.7. Optionnal.\n" <<
40 "MaxNumberOfIterations. Range: 1...Infinity. Default: 200. Optionnal.\n"
46 int Execute(
int argc,
char * argv[]);
48 template<
int VDimension>
51 template<
int VDimension,
typename ScalarType,
typename ComponentType>
52 int Execute(
int argc,
char * argv[],
int nComponents);
54 template<
int VDimension,
typename ScalarType,
typename PixelType,
typename ExportPixelType>
55 int Execute(
int argc,
char * argv[]);
66 std::cout <<
object->GetNameOfClass() <<
" has completed: "
67 << int(100*dynamic_cast<const itk::ProcessObject*>(
object)->GetProgress())
79 if(argc<4+1) {
Usage();
return EXIT_SUCCESS;}
81 const char *imageFileName =argv[0+1];
83 ReaderType::Pointer reader = ReaderType::New();
84 reader->SetFileName(imageFileName);
86 reader->UpdateOutputInformation();
91 const int nComponents = io->GetNumberOfComponents();
94 const char *tensorFileName = argv[1+1];
95 ReaderType::Pointer reader2 = ReaderType::New();
96 reader2->SetFileName(tensorFileName);
97 reader2->UpdateOutputInformation();
100 std::cerr <<
"Warning: image and tensors have distinct component types.\n";
102 itkGenericExceptionMacro(
"Error: image and tensor image have distinct dimension");
103 const int TensorDimension = (ImageDimension*(ImageDimension+1))/2;
105 itkGenericExceptionMacro(
"Error: wrong tensor dimension, should be n*(n+1)/2 where n=ImageDimension.");
107 std::cerr <<
"Warning: tensor image pixel type not marked as Symmetric Second Rank Tensor.\n";
110 switch (ImageDimension) {
111 case 2:
return Execute<2>(argc,argv,componentType,nComponents);
113 default: itkGenericExceptionMacro(
"Sorry, unsupported image dimension.");
117 template<
int Dimension>
119 switch (componentType) {
123 default: itkGenericExceptionMacro(
"Sorry, unsupported component type");
127 template<
int Dimension,
typename ScalarType,
typename ComponentType>
128 int Execute(
int argc,
char * argv[],
int nComponents){
129 switch (nComponents) {
130 case 1:
return Execute<Dimension,ScalarType,ScalarType,ComponentType>(argc,argv);
133 default: itkGenericExceptionMacro(
"Sorry, unsupported number of components");
137 template<
int Dimension,
typename ScalarType,
typename PixelType,
typename ExportPixelType>
138 int Execute(
int argc,
char * argv[]){
143 typename ReaderType::Pointer reader = ReaderType::New();
144 const char *imageFileName =argv[0+1];
145 reader->SetFileName(imageFileName);
151 typename TensorReaderType::Pointer tensorReader = TensorReaderType::New();
152 const char * tensorImageFileName = argv[1+1];
153 tensorReader->SetFileName(tensorImageFileName);
156 const double diffusionTime = std::stod(argv[2+1]);
157 if(diffusionTime==0) itkGenericExceptionMacro(
"Error: Unrecognized diffusion time (third argument).\n");
160 const char *outputFileName = argv[3+1];
164 typename DiffusionFilterType::Pointer diffusionFilter = DiffusionFilterType::New();
165 diffusionFilter->SetInputImage(reader->GetOutput());
166 diffusionFilter->SetInputTensor(tensorReader->GetOutput());
167 diffusionFilter->SetMaxDiffusionTime(diffusionTime);
171 const double ratioToMaxStableTimeStep = std::stod(argv[argIndex++]);
172 if(ratioToMaxStableTimeStep==0) itkGenericExceptionMacro(
"Error: Unrecognized RatioToMaxStableTimeStep (fourth argument).\n");
173 diffusionFilter->SetRatioToMaxStableTimeStep(ratioToMaxStableTimeStep);
177 const int maxNumberOfTimeSteps = std::stoi(argv[argIndex++]);
178 if(maxNumberOfTimeSteps==0) itkGenericExceptionMacro(
"Error: Unrecognized maxNumberOfTimeSteps (fifth argument).\n");
179 diffusionFilter->SetMaxNumberOfTimeSteps(maxNumberOfTimeSteps);
181 diffusionFilter->SetMaxNumberOfTimeSteps(200);
184 diffusionFilter->AddObserver(ProgressEvent(), reportDiffusionProgress);
188 typename CasterType::Pointer caster = CasterType::New();
189 caster->SetInput(diffusionFilter->GetOutput());
193 typename WriterType::Pointer writer = WriterType::New();
194 writer->SetInput(caster->GetOutput());
195 writer->SetFileName(outputFileName);
198 const ScalarType effectiveDiffusionTime=diffusionFilter->GetEffectiveDiffusionTime();
199 if(effectiveDiffusionTime < 0.99 * diffusionTime){
201 "Warning: early abort at effective diffusion time: " << effectiveDiffusionTime <<
202 ", you may want to increase the max number of time steps: " << diffusionFilter->GetMaxNumberOfTimeSteps() <<
"\n";
Abstract superclass defines image IO interface.
Represent a symmetric tensor of second rank.
void Execute(itk::Object *caller, const itk::EventObject &event) override
Anisotropic diffusion using lattice basis reduction.
A templated class holding a n-Dimensional vector.
int Execute(int argc, char *argv[])
Abstraction of the Events used to communicating among filters and with GUIs.
SmartPointer< Self > Pointer
virtual IOComponentType GetComponentType() const
Writes image data to a single file.
virtual IOPixelType GetPixelType() const
Data source that reads image data from a single file.
virtual const unsigned int & GetNumberOfComponents() const
virtual unsigned int GetNumberOfDimensions() const
Base class for most ITK classes.
Superclass for callback/observer methods.
Templated n-dimensional image class.
Casts input pixels to output pixel type.
void Execute(const itk::Object *object, const itk::EventObject &) override