ANIMA  4.0
animaTensorApplyTransformSerie.cxx
Go to the documentation of this file.
1 #include <tclap/CmdLine.h>
2 
3 #include <itkImageFileReader.h>
4 #include <itkImageFileWriter.h>
5 
7 #include <itkNearestNeighborInterpolateImageFunction.h>
9 
13 
14 int main(int ac, const char** av)
15 {
16  std::string descriptionMessage;
17  descriptionMessage += "Resampler tool to apply a series of transformations to a tensor image. ";
18  descriptionMessage += "Input transform is an XML file describing all transforms to apply. ";
19  descriptionMessage += "Such a file should look like this:\n";
20  descriptionMessage += "<TransformationList>\n";
21  descriptionMessage += "<Transformation>\n";
22  descriptionMessage += "<Type>linear</Type> (it can be svf or dense too)\n";
23  descriptionMessage += "<Path>FileName</Path>\n";
24  descriptionMessage += "<Inversion>0</Inversion>\n";
25  descriptionMessage += "</Transformation>\n";
26  descriptionMessage += "...\n";
27  descriptionMessage += "</TransformationList>\n\n";
28  descriptionMessage += "INRIA / IRISA - VisAGeS/Empenn Team";
29 
30  TCLAP::CmdLine cmd(descriptionMessage, ' ',ANIMA_VERSION);
31 
32  TCLAP::ValueArg<std::string> inArg("i","input","Input image",true,"","input image",cmd);
33  TCLAP::ValueArg<std::string> trArg("t","trsf","Transformations XML list",true,"","transformations list",cmd);
34  TCLAP::ValueArg<std::string> outArg("o","output","Output resampled image",true,"","output image",cmd);
35  TCLAP::ValueArg<std::string> geomArg("g","geometry","Geometry image",true,"","geometry image",cmd);
36 
37  TCLAP::SwitchArg ppdArg("P","ppd","Use PPD re-orientation scheme (default: no)",cmd,false);
38  TCLAP::ValueArg<unsigned int> expOrderArg("e","exp-order","Order of field exponentiation approximation (in between 0 and 1, default: 0)",false,0,"exponentiation order",cmd);
39  TCLAP::SwitchArg invertArg("I","invert","Invert the transformation series",cmd,false);
40  TCLAP::SwitchArg nearestArg("N","nearest","Use nearest neighbor interpolation",cmd,false);
41 
42  TCLAP::ValueArg<unsigned int> nbpArg("p","numberofthreads","Number of threads to run on (default: all cores)",false,itk::MultiThreaderBase::GetGlobalDefaultNumberOfThreads(),"number of threads",cmd);
43 
44  try
45  {
46  cmd.parse(ac,av);
47  }
48  catch (TCLAP::ArgException& e)
49  {
50  std::cerr << "Error: " << e.error() << "for argument " << e.argId() << std::endl;
51  return EXIT_FAILURE;
52  }
53 
54  const unsigned int Dimension = 3;
55  typedef double PixelType;
56 
57  typedef itk::VectorImage< PixelType, Dimension > ImageType;
58  typedef anima::TransformSeriesReader <double, Dimension> TransformSeriesReaderType;
59  typedef TransformSeriesReaderType::OutputTransformType TransformType;
60 
61  typedef itk::ImageFileReader <ImageType> ReaderType;
62  typedef itk::ImageFileWriter <ImageType> WriterType;
63 
64  ReaderType::Pointer reader = ReaderType::New();
65  reader->SetFileName(inArg.getValue());
66  reader->Update();
67 
68  itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(geomArg.getValue().c_str(),
69  itk::ImageIOFactory::ReadMode);
70 
71  if( !imageIO )
72  {
73  std::cerr << "Itk could not find suitable IO factory for the input" << std::endl;
74  return EXIT_FAILURE;
75  }
76 
77  // Now that we found the appropriate ImageIO class, ask it to read the meta data from the image file.
78  imageIO->SetFileName(geomArg.getValue());
79  imageIO->ReadImageInformation();
80 
81  TransformSeriesReaderType *trReader = new TransformSeriesReaderType;
82  trReader->SetInput(trArg.getValue());
83  trReader->SetInvertTransform(invertArg.isSet());
84  trReader->SetExponentiationOrder(expOrderArg.getValue());
85  trReader->SetNumberOfWorkUnits(nbpArg.getValue());
86 
87  try
88  {
89  trReader->Update();
90  }
91  catch (itk::ExceptionObject &e)
92  {
93  std::cerr << e << std::endl;
94  return EXIT_FAILURE;
95  }
96 
97  TransformType::Pointer trsf = trReader->GetOutputTransform();
98 
99  itk::InterpolateImageFunction <ImageType>::Pointer interpolator;
100 
101  if (nearestArg.isSet())
102  interpolator = itk::NearestNeighborInterpolateImageFunction<ImageType>::New();
103  else
105 
106  typedef anima::TensorResampleImageFilter <ImageType, double> ResampleFilterType;
107 
108  ResampleFilterType::Pointer resample = ResampleFilterType::New();
109 
110  resample->SetTransform(trsf);
111  resample->SetFiniteStrainReorientation(!ppdArg.isSet());
112  resample->SetInterpolator(interpolator.GetPointer());
113  resample->SetNumberOfWorkUnits(nbpArg.getValue());
114 
115  ImageType::DirectionType directionMatrix;
116  ImageType::PointType origin;
117  ImageType::SpacingType spacing;
118  ImageType::RegionType largestRegion;
119 
120  for (unsigned int i = 0;i < Dimension;++i)
121  {
122  origin[i] = imageIO->GetOrigin(i);
123  spacing[i] = imageIO->GetSpacing(i);
124  largestRegion.SetIndex(i,0);
125  largestRegion.SetSize(i,imageIO->GetDimensions(i));
126 
127  for (unsigned int j = 0;j < Dimension;++j)
128  directionMatrix(i,j) = imageIO->GetDirection(j)[i];
129  }
130 
131  resample->SetOutputLargestPossibleRegion(largestRegion);
132  resample->SetOutputOrigin(origin);
133  resample->SetOutputSpacing(spacing);
134  resample->SetOutputDirection(directionMatrix);
135 
136  typedef anima::LogTensorImageFilter <PixelType,Dimension> LogTensorFilterType;
137  LogTensorFilterType::Pointer tensorLogger = LogTensorFilterType::New();
138 
139  tensorLogger->SetInput(reader->GetOutput());
140  tensorLogger->SetScaleNonDiagonal(true);
141  tensorLogger->SetNumberOfWorkUnits(nbpArg.getValue());
142 
143  std::cout << "Logging input... " << std::flush;
144  tensorLogger->Update();
145  std::cout << "Done..." << std::endl;
146 
147  ImageType::Pointer tmpImage = tensorLogger->GetOutput();
148  tmpImage->DisconnectPipeline();
149 
150  resample->SetInput(tmpImage);
151 
152  std::cout << "Applying transform... " << std::flush;
153  resample->Update();
154  std::cout << "Done..." << std::endl;
155 
156  tmpImage = resample->GetOutput();
157  tmpImage->DisconnectPipeline();
158 
159  typedef anima::ExpTensorImageFilter <PixelType,Dimension> ExpTensorFilterType;
160  ExpTensorFilterType::Pointer tensorExper = ExpTensorFilterType::New();
161 
162  tensorExper->SetInput(tmpImage);
163  tensorExper->SetScaleNonDiagonal(true);
164  tensorExper->SetNumberOfWorkUnits(nbpArg.getValue());
165 
166  std::cout << "Exping output... " << std::flush;
167  tensorExper->Update();
168  std::cout << "Done..." << std::endl;
169 
170  WriterType::Pointer writer = WriterType::New();
171 
172  writer->SetUseCompression(true);
173 
174  tmpImage = tensorExper->GetOutput();
175  tmpImage->DisconnectPipeline();
176 
177  writer->SetInput(tmpImage);
178 
179  writer->SetFileName(outArg.getValue());
180 
181  writer->Update();
182 
183  return EXIT_SUCCESS;
184 }
int main(int ac, const char **av)