1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ======================================================================-====*/
19 #ifndef CLITKTRANSFORMUTILITIES_H
20 #define CLITKTRANSFORMUTILITIES_H
21 #include "itkMatrix.h"
24 #include "clitkImageCommon.h"
25 #include "clitkCommon.h"
30 //============================================================================
32 //============================================================================
33 itk::Matrix<double, 3, 3> GetForwardAffineMatrix2D(itk::Array<double> transformParameters);
34 itk::Matrix<double, 4, 4> GetForwardAffineMatrix3D(itk::Array<double> transformParameters);
36 itk::Matrix<double, 3, 3> GetBackwardAffineMatrix2D(itk::Array<double> transformParameters);
37 itk::Matrix<double, 4, 4> GetBackwardAffineMatrix3D(itk::Array<double> transformParameters);
38 template <unsigned int Dimension > itk::Matrix<double, Dimension+1, Dimension+1> GetBackwardAffineMatrix(itk::Array<double> transformParameters);
40 itk::Matrix<double, 3, 3> GetRotationMatrix3D(itk::Array<double> rotationParameters);
41 itk::Point<double, 3> GetRotatedPoint3D(itk::Array<double> rotationParameters, itk::Point<double, 3> input);
42 itk::Matrix<double, 4, 4> GetCenteredRotationMatrix3D(itk::Array<double> rotationParameters,itk::Point<double,3> centerOfRotation);
43 // itk::Matrix<double, 4, 4> GetComposedMatrix3D(itk::Matrix<double, 4, 4> firstTransform, itk::Matrix<double, 4, 4> secondTransform);
45 itk::Matrix<double, 5, 5> ReadMatrix4D(std::string fileName);
46 itk::Matrix<double, 4, 4> ReadMatrix3D(std::string fileName);
47 itk::Matrix<double, 3, 3> ReadMatrix2D(std::string fileName);
48 template <unsigned int Dimension > itk::Matrix<double, Dimension+1 , Dimension+1> ReadMatrix(std::string fileName);
50 itk::Matrix<double, 3, 3> GetRotationalPartMatrix3D(itk::Matrix<double, 4, 4> input);
51 itk::Matrix<double, 3, 3> GetRotationalPartMatrix(itk::Matrix<double, 4, 4> input);
52 itk::Matrix<double, 2, 2> GetRotationalPartMatrix2D(itk::Matrix<double, 3, 3> input);
53 itk::Matrix<double, 2, 2> GetRotationalPartMatrix(itk::Matrix<double, 3, 3> input);
55 itk::Vector<double,3> GetTranslationPartMatrix3D(itk::Matrix<double, 4, 4> input);
56 itk::Vector<double,3> GetTranslationPartMatrix(itk::Matrix<double, 4, 4> input);
57 itk::Vector<double,2> GetTranslationPartMatrix2D(itk::Matrix<double, 3, 3> input);
58 itk::Vector<double,2> GetTranslationPartMatrix(itk::Matrix<double, 3, 3> input);
61 //============================================================================
62 //Inline functions definition in header file, otherwise linker errors
63 //============================================================================
65 //========================================================================================
66 inline itk::Matrix<double, 3, 3> GetForwardAffineMatrix2D(itk::Array<double> transformParameters)
68 itk::Matrix<double, 3, 3> matrix;
70 matrix[0][0]=cos(transformParameters[0]);
71 matrix[0][1]=-sin(transformParameters[0]);
72 matrix[1][0]=sin(transformParameters[0]);
73 matrix[1][1]=cos(transformParameters[0]);
75 matrix[0][2]=transformParameters[1];
76 matrix[1][2]=transformParameters[2];
84 inline itk::Matrix<double, 4, 4> GetForwardAffineMatrix3D(itk::Array<double> transformParameters)
86 itk::Matrix<double, 4, 4> matrix;
88 matrix[0][0]= cos(transformParameters[1])*cos(transformParameters[2]);
89 matrix[0][1]= sin(transformParameters[0])*sin(transformParameters[1])*cos(transformParameters[2])+ sin(transformParameters[2])*cos(transformParameters[0]);
90 matrix[0][2]= -cos(transformParameters[0])*sin(transformParameters[1])*cos(transformParameters[2])+sin(transformParameters[0])*sin(transformParameters[2]);
91 matrix[1][0]= -cos(transformParameters[1])*sin(transformParameters[2]);
92 matrix[1][1]= -sin(transformParameters[0])*sin(transformParameters[1])*sin(transformParameters[2])+cos(transformParameters[0])*cos(transformParameters[2]);
93 matrix[1][2]= cos(transformParameters[0])*sin(transformParameters[1])*sin(transformParameters[2])+sin(transformParameters[0])*cos(transformParameters[2]);
94 matrix[2][0]= sin(transformParameters[1]);
95 matrix[2][1]= -sin(transformParameters[0])*cos(transformParameters[1]);
96 matrix[2][2]= cos(transformParameters[0])*cos(transformParameters[1]);
98 matrix[0][3]=transformParameters[3];
99 matrix[1][3]=transformParameters[4];
100 matrix[2][3]=transformParameters[5];
110 inline itk::Matrix<double, 3, 3> GetBackwardAffineMatrix2D(itk::Array<double> transformParameters)
112 itk::Matrix<double, 3, 3> matrix;
114 matrix[0][0]=cos(transformParameters[0]);
115 matrix[0][1]=sin(transformParameters[0]);
116 matrix[1][0]=-sin(transformParameters[0]);
117 matrix[1][1]=cos(transformParameters[0]);
119 matrix[0][2]=transformParameters[1];
120 matrix[1][2]=transformParameters[2];
129 inline itk::Matrix<double, 4, 4> GetBackwardAffineMatrix3D(itk::Array<double> transformParameters)
131 itk::Matrix<double, 4, 4> matrix;
133 matrix[0][0]= cos(transformParameters[1])*cos(transformParameters[2]);
134 matrix[0][1]= sin(transformParameters[0])*sin(transformParameters[1])*cos(transformParameters[2])- sin(transformParameters[2])*cos(transformParameters[0]);
135 matrix[0][2]= cos(transformParameters[0])*sin(transformParameters[1])*cos(transformParameters[2])+sin(transformParameters[0])*sin(transformParameters[2]);
136 matrix[1][0]= cos(transformParameters[1])*sin(transformParameters[2]);
137 matrix[1][1]= sin(transformParameters[0])*sin(transformParameters[1])*sin(transformParameters[2])+cos(transformParameters[0])*cos(transformParameters[2]);
138 matrix[1][2]= cos(transformParameters[0])*sin(transformParameters[1])*sin(transformParameters[2])-sin(transformParameters[0])*cos(transformParameters[2]);
139 matrix[2][0]= -sin(transformParameters[1]);
140 matrix[2][1]= sin(transformParameters[0])*cos(transformParameters[1]);
141 matrix[2][2]= cos(transformParameters[0])*cos(transformParameters[1]);
143 matrix[0][3]=transformParameters[3];
144 matrix[1][3]=transformParameters[4];
145 matrix[2][3]=transformParameters[5];
154 template <unsigned int Dimension >
155 inline itk::Matrix<double, Dimension+1, Dimension+1>
156 GetBackwardAffineMatrix(itk::Array<double> transformParameters)
160 inline itk::Matrix<double, 3, 3> GetRotationMatrix3D(itk::Array<double> rotationParameters)
162 itk::Matrix<double, 3, 3> matrix;
164 matrix[0][0]= cos(rotationParameters[1])*cos(rotationParameters[2]);
165 matrix[0][1]= sin(rotationParameters[0])*sin(rotationParameters[1])*cos(rotationParameters[2])+ sin(rotationParameters[2])*cos(rotationParameters[0]);
166 matrix[0][2]= -cos(rotationParameters[0])*sin(rotationParameters[1])*cos(rotationParameters[2])+sin(rotationParameters[0])*sin(rotationParameters[2]);
167 matrix[1][0]= -cos(rotationParameters[1])*sin(rotationParameters[2]);
168 matrix[1][1]= -sin(rotationParameters[0])*sin(rotationParameters[1])*sin(rotationParameters[2])+cos(rotationParameters[0])*cos(rotationParameters[2]);
169 matrix[1][2]= cos(rotationParameters[0])*sin(rotationParameters[1])*sin(rotationParameters[2])+sin(rotationParameters[0])*cos(rotationParameters[2]);
170 matrix[2][0]= sin(rotationParameters[1]);
171 matrix[2][1]= -sin(rotationParameters[0])*cos(rotationParameters[1]);
172 matrix[2][2]= cos(rotationParameters[0])*cos(rotationParameters[1]);
178 //========================================================================================
179 inline itk::Point<double, 3> GetRotatedPoint3D(itk::Array<double> rotationParameters, itk::Point<double, 3> input)
181 itk::Matrix<double, 3, 3> matrix = GetRotationMatrix3D(rotationParameters);
182 itk::Point<double, 3> output;
183 for (unsigned int i=0;i<3;i++)
186 for (unsigned int j=0;j<3;j++)
187 output[i]+=matrix(i,j)*input[j];
193 inline itk::Matrix<double, 4, 4> GetCenteredRotationMatrix3D(itk::Array<double> rotationParameters,itk::Point<double,3> centerOfRotation )
195 //rotational part is identical as affine matrix, translations change
196 itk::Array<double> parameters(6);
197 for(unsigned int i=0; i<3;i++) parameters[i]=rotationParameters[i];
198 for(unsigned int i=3; i<6;i++) parameters[i]=centerOfRotation[i-3];
199 itk::Matrix<double, 4, 4> matrix=GetForwardAffineMatrix3D(parameters);
201 //Get the rotation of the centerOfRotation
202 itk::Matrix<double,3,3> rotation = GetRotationalPartMatrix3D(matrix);
203 itk::Point<double,3> rotatedCenter=rotation*centerOfRotation; //GetRotatedPoint3D(rotationParameters, centerOfRotation);
205 //Substract this point to the translational part
206 matrix(0,3)-=rotatedCenter[0];
207 matrix(1,3)-=rotatedCenter[1];
208 matrix(2,3)-=rotatedCenter[2];
213 // inline itk::Matrix<double, 4, 4> GetComposedMatrix3D(itk::Matrix<double, 4, 4> firstAppliedTransform, itk::Matrix<double, 4, 4> secondAppliedTransform)
215 // itk::Matrix<double, 4, 4> matrix;
216 // for (unsigned int i=0;i<4;i++)
217 // for (unsigned int j=0;j<4;j++)
220 // for (unsigned int k=0;k<4;k++)
221 // matrix[i][j]+=firstAppliedTransform[i][k]*secondAppliedTransform[k][j];
227 //========================================================================================
228 inline itk::Matrix<double, 5, 5> ReadMatrix4D(std::string fileName)
232 openFileForReading(is, fileName);
233 std::vector<double> nb;
243 //copy it to the matrix
244 itk::Matrix<double, 5, 5> matrix;
245 unsigned int index=0;
246 for (unsigned int i=0;i<5;i++)
247 for (unsigned int j=0;j<5;j++)
248 matrix[i][j]=nb[index++];
252 inline itk::Matrix<double, 4, 4> ReadMatrix3D(std::string fileName)
256 openFileForReading(is, fileName);
257 std::vector<double> nb;
267 //copy it to the matrix
268 itk::Matrix<double, 4, 4> matrix;
269 unsigned int index=0;
270 for (unsigned int i=0;i<4;i++)
271 for (unsigned int j=0;j<4;j++)
272 matrix[i][j]=nb[index++];
276 inline itk::Matrix<double, 3, 3> ReadMatrix2D(std::string fileName)
280 openFileForReading(is, fileName);
281 std::vector<double> nb;
291 //copy it to the matrix
292 itk::Matrix<double, 3, 3> matrix;
293 unsigned int index=0;
294 for (unsigned int i=0;i<3;i++)
295 for (unsigned int j=0;j<3;j++)
296 matrix[i][j]=nb[index++];
300 template <unsigned int Dimension > inline itk::Matrix<double, Dimension+1 , Dimension+1> ReadMatrix(std::string fileName)
305 openFileForReading(is, fileName);
306 std::vector<double> nb;
316 //copy it to the matrix
317 itk::Matrix<double, Dimension+1, Dimension+1> matrix;
318 unsigned int index=0;
319 for (unsigned int i=0;i<Dimension+1;i++)
320 for (unsigned int j=0;j<Dimension+1;j++)
321 matrix[i][j]=nb[index++];
326 // template<> inline itk::Matrix<double, 3, 3> ReadMatrix<2> (std::string fileName)
328 // return ReadMatrix2D(fileName);
330 // template<> inline itk::Matrix<double, 4, 4> ReadMatrix<3> (std::string fileName)
332 // return ReadMatrix3D(fileName);
334 // template<> inline itk::Matrix<double, 5, 5> ReadMatrix<4> (std::string fileName)
336 // return ReadMatrix4D(fileName);
340 //========================================================================================
341 inline itk::Matrix<double, 4, 4> GetRotationalPartMatrix4D(itk::Matrix<double, 5, 5> input)
343 itk::Matrix<double,4,4> matrix;
344 matrix[0][0]= input[0][0];
345 matrix[0][1]= input[0][1];
346 matrix[0][2]= input[0][2];
347 matrix[0][3]= input[0][3];
348 matrix[1][0]= input[1][0];
349 matrix[1][1]= input[1][1];
350 matrix[1][2]= input[1][2];
351 matrix[1][3]= input[1][3];
352 matrix[2][0]= input[2][0];
353 matrix[2][1]= input[2][1];
354 matrix[2][2]= input[2][2];
355 matrix[2][2]= input[2][2];
356 matrix[2][3]= input[2][3];
357 matrix[3][0]= input[3][0];
358 matrix[3][1]= input[3][1];
359 matrix[3][2]= input[3][2];
360 matrix[3][2]= input[3][2];
361 matrix[3][3]= input[3][3];
367 inline itk::Matrix<double, 3, 3> GetRotationalPartMatrix3D(itk::Matrix<double, 4, 4> input)
369 itk::Matrix<double,3,3> matrix;
370 matrix[0][0]= input[0][0];
371 matrix[0][1]= input[0][1];
372 matrix[0][2]= input[0][2];
373 matrix[1][0]= input[1][0];
374 matrix[1][1]= input[1][1];
375 matrix[1][2]= input[1][2];
376 matrix[2][0]= input[2][0];
377 matrix[2][1]= input[2][1];
378 matrix[2][2]= input[2][2];
382 inline itk::Matrix<double, 2, 2> GetRotationalPartMatrix2D(itk::Matrix<double, 3, 3> input)
384 itk::Matrix<double,2,2> matrix;
385 matrix[0][0]= input[0][0];
386 matrix[0][1]= input[0][1];
387 matrix[0][2]= input[0][2];
388 matrix[1][0]= input[1][0];
389 matrix[1][1]= input[1][1];
393 inline itk::Matrix<double, 4, 4> GetRotationalPartMatrix(itk::Matrix<double, 5, 5> input)
395 return GetRotationalPartMatrix4D(input);
398 inline itk::Matrix<double, 3, 3> GetRotationalPartMatrix(itk::Matrix<double, 4, 4> input)
400 return GetRotationalPartMatrix3D(input);
403 inline itk::Matrix<double, 2, 2> GetRotationalPartMatrix(itk::Matrix<double, 3, 3> input)
405 return GetRotationalPartMatrix2D(input);
409 //========================================================================================
410 inline itk::Vector<double,4> GetTranslationPartMatrix4D(itk::Matrix<double, 5, 5> input)
412 itk::Vector<double,4> vec;
421 inline itk::Vector<double,3> GetTranslationPartMatrix3D(itk::Matrix<double, 4, 4> input)
423 itk::Vector<double,3> vec;
430 inline itk::Vector<double,2> GetTranslationPartMatrix2D(itk::Matrix<double, 3, 3> input)
432 itk::Vector<double,2> vec;
439 inline itk::Vector<double,4> GetTranslationPartMatrix(itk::Matrix<double, 5, 5> input)
442 return GetTranslationPartMatrix4D(input);
445 inline itk::Vector<double,3> GetTranslationPartMatrix(itk::Matrix<double, 4, 4> input)
448 return GetTranslationPartMatrix3D(input);
451 inline itk::Vector<double,2> GetTranslationPartMatrix(itk::Matrix<double, 3, 3> input)
454 return GetTranslationPartMatrix2D(input);
458 #endif //#define CLITKTRANSFORMUTILITIES_H