ANIMA  4.0
animaLinearTransformArithmetic.cxx
Go to the documentation of this file.
1 #include <tclap/CmdLine.h>
2 
3 #include <itkTransformFileReader.h>
4 #include <itkTransformFileWriter.h>
5 #include <itkAffineTransform.h>
6 #include <animaMatrixLogExp.h>
7 
8 int main(int argc, char **argv)
9 {
10  std::string descriptionMessage = "Performs very basic mathematical operations on images: performs (I * M / D) * c + a - s\n";
11  descriptionMessage += "INRIA / IRISA - VisAGeS/Empenn Team";
12 
13  TCLAP::CmdLine cmd(descriptionMessage, ' ',ANIMA_VERSION);
14 
15  TCLAP::ValueArg<std::string> inArg("i","input","Input transform",true,"","input transform",cmd);
16  TCLAP::ValueArg<std::string> outArg("o","output","output transform",true,"","output transform",cmd);
17 
18  TCLAP::ValueArg<std::string> composeTrsfArg("c","compose-trsf","compose transform",false,"","compose transform",cmd);
19  TCLAP::ValueArg<std::string> addTrsfArg("a","add-trsf","add transform (log-Euclidean add)",false,"","add transform",cmd);
20  TCLAP::ValueArg<std::string> subtractTrsfArg("s","sub-trsf","subtract transform (log-Euclidean subtract)",false,"","subtract transform",cmd);
21 
22  TCLAP::ValueArg<double> multiplyConstantArg("M","multiply-constant","multiply constant value (log-Euclidean multiply)",false,1.0,"multiply constant value",cmd);
23  TCLAP::ValueArg<double> divideConstantArg("D","divide-constant","divide constant value (log-Euclidean divide)",false,1.0,"divide constant value",cmd);
24 
25  try
26  {
27  cmd.parse(argc,argv);
28  }
29  catch (TCLAP::ArgException& e)
30  {
31  std::cerr << "Error: " << e.error() << "for argument " << e.argId() << std::endl;
32  return EXIT_FAILURE;
33  }
34 
35  typedef double PrecisionType;
36  const unsigned int Dimension = 3;
37  typedef itk::AffineTransform <PrecisionType,Dimension> MatrixTransformType;
38  typedef MatrixTransformType::Pointer MatrixTransformPointer;
39  typedef vnl_matrix <double> MatrixType;
40 
41  itk::TransformFileReader::Pointer trReader = itk::TransformFileReader::New();
42  trReader->SetFileName(inArg.getValue());
43 
44  try
45  {
46  trReader->Update();
47  }
48  catch (itk::ExceptionObject &e)
49  {
50  std::cerr << "Problem reading transform file " << inArg.getValue() << ", exiting" << std::endl;
51  return EXIT_FAILURE;
52  }
53 
54  itk::TransformFileReader::TransformListType trsfList = *(trReader->GetTransformList());
55  itk::TransformFileReader::TransformListType::iterator tr_it = trsfList.begin();
56 
57  MatrixTransformType *trsf = dynamic_cast <MatrixTransformType *> ((*tr_it).GetPointer());
58 
59  if (trsf == NULL)
60  {
61  std::cerr << "Problem converting transform file to linear file " << inArg.getValue() << ", exiting" << std::endl;
62  return EXIT_FAILURE;
63  }
64 
65  MatrixType workMatrix(Dimension+1,Dimension+1), logWorkMatrix(Dimension+1,Dimension+1);
66  logWorkMatrix.fill(0);
67 
68  workMatrix.set_identity();
69  for (unsigned int i = 0;i < Dimension;++i)
70  {
71  workMatrix(i,Dimension) = trsf->GetOffset()[i];
72  for (unsigned int j = 0;j < Dimension;++j)
73  workMatrix(i,j) = trsf->GetMatrix()(i,j);
74  }
75 
76  logWorkMatrix = anima::GetLogarithm(workMatrix);
77 
78  logWorkMatrix *= multiplyConstantArg.getValue();
79  if (divideConstantArg.getValue() != 0)
80  logWorkMatrix /= divideConstantArg.getValue();
81 
82  if (composeTrsfArg.getValue() != "")
83  {
84  itk::TransformFileReader::Pointer reader = itk::TransformFileReader::New();
85  reader->SetFileName(composeTrsfArg.getValue());
86 
87  try
88  {
89  reader->Update();
90  }
91  catch (itk::ExceptionObject &e)
92  {
93  std::cerr << "Problem reading transform file " << composeTrsfArg.getValue() << ", exiting" << std::endl;
94  return EXIT_FAILURE;
95  }
96 
97  itk::TransformFileReader::TransformListType composeTrsfList = *(reader->GetTransformList());
98  itk::TransformFileReader::TransformListType::iterator composeTr_it = composeTrsfList.begin();
99 
100  MatrixTransformType *composeTrsf = dynamic_cast <MatrixTransformType *> ((*composeTr_it).GetPointer());
101 
102  MatrixType composeMatrix(Dimension+1,Dimension+1);
103  composeMatrix.set_identity();
104  for (unsigned int i = 0;i < Dimension;++i)
105  {
106  composeMatrix(i,Dimension) = composeTrsf->GetOffset()[i];
107  for (unsigned int j = 0;j < Dimension;++j)
108  composeMatrix(i,j) = composeTrsf->GetMatrix()(i,j);
109  }
110 
111  workMatrix = anima::GetExponential(logWorkMatrix);
112  workMatrix *= composeMatrix;
113  logWorkMatrix = anima::GetLogarithm(workMatrix);
114  }
115 
116  if (addTrsfArg.getValue() != "")
117  {
118  itk::TransformFileReader::Pointer reader = itk::TransformFileReader::New();
119  reader->SetFileName(addTrsfArg.getValue());
120 
121  try
122  {
123  reader->Update();
124  }
125  catch (itk::ExceptionObject &e)
126  {
127  std::cerr << "Problem reading transform file " << addTrsfArg.getValue() << ", exiting" << std::endl;
128  return EXIT_FAILURE;
129  }
130 
131  itk::TransformFileReader::TransformListType addTrsfList = *(reader->GetTransformList());
132  itk::TransformFileReader::TransformListType::iterator addTr_it = addTrsfList.begin();
133 
134  MatrixTransformType *addTrsf = dynamic_cast <MatrixTransformType *> ((*addTr_it).GetPointer());
135 
136  if (addTrsf == NULL)
137  {
138  std::cerr << "Problem converting transform file to linear file " << addTrsfArg.getValue() << ", exiting" << std::endl;
139  return EXIT_FAILURE;
140  }
141 
142  MatrixType addMatrix(Dimension+1,Dimension+1), logAddMatrix(Dimension+1,Dimension+1);
143  addMatrix.set_identity();
144  for (unsigned int i = 0;i < Dimension;++i)
145  {
146  addMatrix(i,Dimension) = addTrsf->GetOffset()[i];
147  for (unsigned int j = 0;j < Dimension;++j)
148  addMatrix(i,j) = addTrsf->GetMatrix()(i,j);
149  }
150 
151  logAddMatrix = anima::GetLogarithm(addMatrix);
152  logWorkMatrix += logAddMatrix;
153  }
154 
155  if (subtractTrsfArg.getValue() != "")
156  {
157  itk::TransformFileReader::Pointer reader = itk::TransformFileReader::New();
158  reader->SetFileName(subtractTrsfArg.getValue());
159 
160  try
161  {
162  reader->Update();
163  }
164  catch (itk::ExceptionObject &e)
165  {
166  std::cerr << "Problem reading transform file " << subtractTrsfArg.getValue() << ", exiting" << std::endl;
167  return EXIT_FAILURE;
168  }
169 
170  itk::TransformFileReader::TransformListType subTrsfList = *(reader->GetTransformList());
171  itk::TransformFileReader::TransformListType::iterator subTr_it = subTrsfList.begin();
172 
173  MatrixTransformType *subTrsf = dynamic_cast <MatrixTransformType *> ((*subTr_it).GetPointer());
174 
175  if (subTrsf == NULL)
176  {
177  std::cerr << "Problem converting transform file to linear file " << subtractTrsfArg.getValue() << ", exiting" << std::endl;
178  return EXIT_FAILURE;
179  }
180 
181  MatrixType subMatrix(Dimension+1,Dimension+1), logSubMatrix(Dimension+1,Dimension+1);
182  subMatrix.set_identity();
183  for (unsigned int i = 0;i < Dimension;++i)
184  {
185  subMatrix(i,Dimension) = subTrsf->GetOffset()[i];
186  for (unsigned int j = 0;j < Dimension;++j)
187  subMatrix(i,j) = subTrsf->GetMatrix()(i,j);
188  }
189 
190  logSubMatrix = anima::GetLogarithm(subMatrix);
191  logWorkMatrix -= logSubMatrix;
192  }
193 
194  workMatrix = anima::GetExponential(logWorkMatrix);
195 
196  MatrixTransformPointer outTrsf = MatrixTransformType::New();
197  outTrsf->SetIdentity();
198 
199  MatrixTransformType::OffsetType outOffset;
200  MatrixTransformType::MatrixType outMatrix;
201 
202  for (unsigned int i = 0;i < Dimension;++i)
203  {
204  outOffset[i] = workMatrix(i,Dimension);
205  for (unsigned int j = 0;j < Dimension;++j)
206  outMatrix(i,j) = workMatrix(i,j);
207  }
208 
209  outTrsf->SetMatrix(outMatrix);
210  outTrsf->SetOffset(outOffset);
211 
212  itk::TransformFileWriter::Pointer trWriter = itk::TransformFileWriter::New();
213  trWriter->SetInput(outTrsf);
214  trWriter->SetFileName(outArg.getValue());
215 
216  trWriter->Update();
217 
218  return EXIT_SUCCESS;
219 }
int main(int argc, char **argv)
vnl_matrix< T > GetExponential(const vnl_matrix< T > &m, const int numApprox=1)
Computation of the matrix exponential. Algo: classical scaling and squaring, as in Matlab...
vnl_matrix< T > GetLogarithm(const vnl_matrix< T > &m, const double precision=0.00000000001, const int numApprox=1)
Computation of the matrix logarithm. Algo: inverse scaling and squaring, variant proposed by Cheng et...