1 #include <tclap/CmdLine.h> 5 #include <itkVectorImage.h> 6 #include <itkImageRegionIterator.h> 8 #include <itkAddImageFilter.h> 9 #include <itkSubtractImageFilter.h> 10 #include <itkDivideImageFilter.h> 11 #include <itkMultiplyImageFilter.h> 12 #include <itkPowImageFilter.h> 14 template <
class ImageType>
15 void computeArithmetic (std::string &inStr, std::string &outStr, std::string &multImStr, std::string &divImStr, std::string &addImStr,
16 std::string &subImStr,
double multConstant,
double divideConstant,
double addConstant,
double subConstant,
17 double powConstant,
unsigned int nThreads)
19 typedef itk::Image <double, ImageType::ImageDimension> WorkImageType;
20 typedef itk::AddImageFilter <ImageType,ImageType,ImageType> AddFilterType;
21 typedef itk::AddImageFilter <ImageType,WorkImageType,ImageType> AddConstantFilterType;
22 typedef itk::SubtractImageFilter <ImageType,ImageType,ImageType> SubtractFilterType;
23 typedef itk::SubtractImageFilter <ImageType,WorkImageType,ImageType> SubtractConstantFilterType;
25 typedef itk::MultiplyImageFilter <ImageType,WorkImageType,ImageType> MultiplyFilterType;
26 typedef itk::DivideImageFilter <ImageType,WorkImageType,ImageType> DivideFilterType;
28 typename ImageType::Pointer currentImage = anima::readImage <ImageType> (inStr);
29 currentImage->DisconnectPipeline();
33 typedef itk::ImageFileReader <WorkImageType> MultiplyReaderType;
34 typename MultiplyReaderType::Pointer multImReader = MultiplyReaderType::New();
35 multImReader->SetFileName(multImStr);
36 multImReader->Update();
38 typename MultiplyFilterType::Pointer multFilter = MultiplyFilterType::New();
39 multFilter->SetInput1(currentImage);
40 multFilter->SetInput2(multImReader->GetOutput());
41 multFilter->SetNumberOfWorkUnits(nThreads);
42 multFilter->InPlaceOn();
45 currentImage = multFilter->GetOutput();
46 currentImage->DisconnectPipeline();
49 if (multConstant != 1.0)
51 typename MultiplyFilterType::Pointer multFilter = MultiplyFilterType::New();
52 multFilter->SetInput1(currentImage);
53 multFilter->SetConstant(multConstant);
54 multFilter->SetNumberOfWorkUnits(nThreads);
55 multFilter->InPlaceOn();
58 currentImage = multFilter->GetOutput();
59 currentImage->DisconnectPipeline();
62 if ((divideConstant != 0.0)&&(divideConstant != 1.0))
64 typename DivideFilterType::Pointer divFilter = DivideFilterType::New();
65 divFilter->SetInput1(currentImage);
66 divFilter->SetConstant(divideConstant);
67 divFilter->SetNumberOfWorkUnits(nThreads);
68 divFilter->InPlaceOn();
71 currentImage = divFilter->GetOutput();
72 currentImage->DisconnectPipeline();
77 typedef itk::ImageFileReader <WorkImageType> DivideReaderType;
78 typename DivideReaderType::Pointer divImReader = DivideReaderType::New();
79 divImReader->SetFileName(divImStr);
80 divImReader->Update();
82 typename DivideFilterType::Pointer divFilter = DivideFilterType::New();
83 divFilter->SetInput1(currentImage);
84 divFilter->SetInput2(divImReader->GetOutput());
85 divFilter->SetNumberOfWorkUnits(nThreads);
86 divFilter->InPlaceOn();
89 currentImage = divFilter->GetOutput();
90 currentImage->DisconnectPipeline();
92 itk::ImageRegionIterator <WorkImageType> divImItr (divImReader->GetOutput(),divImReader->GetOutput()->GetLargestPossibleRegion());
93 itk::ImageRegionIterator <ImageType> currentImageItr (currentImage,currentImage->GetLargestPossibleRegion());
95 while (!currentImageItr.IsAtEnd())
98 if (itk::Math::AlmostEquals(divImItr.Get(), itk::NumericTraits<typename WorkImageType::PixelType>::ZeroValue()))
99 currentImageItr.Set(currentImageItr.Get() * 0.0);
108 typename ImageType::Pointer addedImage = anima::readImage <ImageType> (addImStr);
110 typename AddFilterType::Pointer addFilter = AddFilterType::New();
111 addFilter->SetInput1(currentImage);
112 addFilter->SetInput2(addedImage);
113 addFilter->SetNumberOfWorkUnits(nThreads);
114 addFilter->InPlaceOn();
117 currentImage = addFilter->GetOutput();
118 currentImage->DisconnectPipeline();
123 typename ImageType::Pointer subtractedImage = anima::readImage <ImageType> (subImStr);
125 typename SubtractFilterType::Pointer subFilter = SubtractFilterType::New();
126 subFilter->SetInput1(currentImage);
127 subFilter->SetInput2(subtractedImage);
128 subFilter->SetNumberOfWorkUnits(nThreads);
129 subFilter->InPlaceOn();
132 currentImage = subFilter->GetOutput();
133 currentImage->DisconnectPipeline();
136 if (addConstant != 0.0)
138 typename AddConstantFilterType::Pointer addFilter = AddConstantFilterType::New();
139 addFilter->SetInput1(currentImage);
140 addFilter->SetConstant(addConstant);
141 addFilter->SetNumberOfWorkUnits(nThreads);
142 addFilter->InPlaceOn();
145 currentImage = addFilter->GetOutput();
146 currentImage->DisconnectPipeline();
149 if (subConstant != 0.0)
151 typename SubtractConstantFilterType::Pointer subFilter = SubtractConstantFilterType::New();
152 subFilter->SetInput1(currentImage);
153 subFilter->SetConstant(subConstant);
154 subFilter->SetNumberOfWorkUnits(nThreads);
155 subFilter->InPlaceOn();
158 currentImage = subFilter->GetOutput();
159 currentImage->DisconnectPipeline();
162 if (powConstant != 1.0)
164 typedef itk::Image <typename ImageType::IOPixelType, ImageType::ImageDimension> ScalarImageType;
165 typedef itk::PowImageFilter <ScalarImageType, WorkImageType, ScalarImageType> PowConstantFilterType;
167 ScalarImageType *castImage = dynamic_cast <ScalarImageType *> (currentImage.GetPointer());
170 typename PowConstantFilterType::Pointer powFilter = PowConstantFilterType::New();
171 powFilter->SetInput1(castImage);
172 powFilter->SetConstant(powConstant);
173 powFilter->SetNumberOfWorkUnits(nThreads);
174 powFilter->InPlaceOn();
178 currentImage = dynamic_cast <ImageType *> (powFilter->GetOutput());
179 currentImage->DisconnectPipeline();
184 anima::writeImage <ImageType> (outStr,currentImage);
187 int main(
int argc,
char **argv)
189 std::string descriptionMessage =
"Performs very basic mathematical operations on images: performs ( (I * m * M) / (D * d) + A + a - s - S)^P \n";
190 descriptionMessage +=
"This software has known limitations: you might have to use it several times in a row to perform the operation you want,\n";
191 descriptionMessage +=
"it requires the divide and multiply images to be scalar, and the add and subtract images to be of the same format as the input (although this is not verified).\n";
192 descriptionMessage +=
"INRIA / IRISA - VisAGeS/Empenn Team";
194 TCLAP::CmdLine cmd(descriptionMessage,
' ',ANIMA_VERSION);
196 TCLAP::ValueArg<std::string> inArg(
"i",
"input",
"Input image",
true,
"",
"input image",cmd);
197 TCLAP::ValueArg<std::string> outArg(
"o",
"output",
"output image",
true,
"",
"output image",cmd);
199 TCLAP::ValueArg<std::string> multImArg(
"m",
"mult-image",
"multiply image",
false,
"",
"multiply image",cmd);
200 TCLAP::ValueArg<std::string> divImArg(
"d",
"div-image",
"divide image",
false,
"",
"divide image",cmd);
201 TCLAP::ValueArg<std::string> addImArg(
"a",
"add-image",
"add image",
false,
"",
"add image",cmd);
202 TCLAP::ValueArg<std::string> subtractImArg(
"s",
"sub-image",
"subtract image",
false,
"",
"subtract image",cmd);
204 TCLAP::ValueArg<double> multiplyConstantArg(
"M",
"multiply-constant",
"multiply constant value",
false,1.0,
"multiply constant value",cmd);
205 TCLAP::ValueArg<double> divideConstantArg(
"D",
"divide-constant",
"divide constant value",
false,1.0,
"divide constant value",cmd);
206 TCLAP::ValueArg<double> addConstantArg(
"A",
"add-constant",
"add constant value",
false,0.0,
"add constant value",cmd);
207 TCLAP::ValueArg<double> subtractConstantArg(
"S",
"sub-constant",
"Subtract constant value",
false,0.0,
"subtract constant value",cmd);
208 TCLAP::ValueArg<double> powArg(
"P",
"pow-constant",
"power constant value (only for scalar images)",
false,1.0,
"power constant value",cmd);
210 TCLAP::ValueArg<unsigned int> nbpArg(
"T",
"numberofthreads",
"Number of threads to run on (default : all cores)",
false,itk::MultiThreaderBase::GetGlobalDefaultNumberOfThreads(),
"number of threads",cmd);
214 cmd.parse(argc,argv);
216 catch (TCLAP::ArgException& e)
218 std::cerr <<
"Error: " << e.error() <<
"for argument " << e.argId() << std::endl;
222 typedef itk::Image <double, 3> ImageType;
223 typedef itk::Image <double, 4> Image4DType;
224 typedef itk::VectorImage <double, 3> VectorImageType;
226 itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(inArg.getValue().c_str(),
227 itk::ImageIOFactory::ReadMode);
231 std::cerr <<
"Unable to read input image " << inArg.getValue() << std::endl;
235 imageIO->SetFileName(inArg.getValue());
236 imageIO->ReadImageInformation();
238 bool vectorImage = (imageIO->GetNumberOfComponents() > 1);
239 bool fourDimensionalImage = (imageIO->GetNumberOfDimensions() == 4);
242 computeArithmetic<VectorImageType>(inArg.getValue(),outArg.getValue(),multImArg.getValue(),divImArg.getValue(),addImArg.getValue(),
243 subtractImArg.getValue(),multiplyConstantArg.getValue(),divideConstantArg.getValue(),
244 addConstantArg.getValue(),subtractConstantArg.getValue(),powArg.getValue(),nbpArg.getValue());
245 else if (fourDimensionalImage)
246 computeArithmetic<Image4DType>(inArg.getValue(),outArg.getValue(),multImArg.getValue(),divImArg.getValue(),addImArg.getValue(),
247 subtractImArg.getValue(),multiplyConstantArg.getValue(),divideConstantArg.getValue(),
248 addConstantArg.getValue(),subtractConstantArg.getValue(),powArg.getValue(),nbpArg.getValue());
250 computeArithmetic<ImageType>(inArg.getValue(),outArg.getValue(),multImArg.getValue(),divImArg.getValue(),addImArg.getValue(),
251 subtractImArg.getValue(),multiplyConstantArg.getValue(),divideConstantArg.getValue(),
252 addConstantArg.getValue(),subtractConstantArg.getValue(),powArg.getValue(),nbpArg.getValue());
void computeArithmetic(std::string &inStr, std::string &outStr, std::string &multImStr, std::string &divImStr, std::string &addImStr, std::string &subImStr, double multConstant, double divideConstant, double addConstant, double subConstant, double powConstant, unsigned int nThreads)
int main(int argc, char **argv)