/*========================================================================= Program: vv http://www.creatis.insa-lyon.fr/rio/vv Authors belong to: - University of LYON http://www.universite-lyon.fr/ - Léon Bérard cancer center http://www.centreleonberard.fr - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the copyright notices for more information. It is distributed under dual licence - BSD See included LICENSE.txt file - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html ===========================================================================**/ #ifndef CLITKTRANSFORMUTILITIES_H #define CLITKTRANSFORMUTILITIES_H #include "itkMatrix.h" #include "itkArray.h" #include "itkPoint.h" #include "clitkImageCommon.h" #include "clitkCommon.h" #define VTK_EXCLUDE_STRSTREAM_HEADERS #include #include namespace clitk { //============================================================================ //Declarations //============================================================================ itk::Matrix GetForwardAffineMatrix2D(itk::Array transformParameters); itk::Matrix GetForwardAffineMatrix3D(itk::Array transformParameters); template itk::Matrix GetForwardAffineMatrix(itk::Array transformParameters); itk::Matrix GetBackwardAffineMatrix2D(itk::Array transformParameters); itk::Matrix GetBackwardAffineMatrix3D(itk::Array transformParameters); template itk::Matrix GetBackwardAffineMatrix(itk::Array transformParameters); itk::Matrix GetRotationMatrix3D(itk::Array rotationParameters); itk::Matrix GetRotationMatrix2D(itk::Array rotationParameters); template itk::Matrix GetRotationMatrix(itk::Array rotationParameters); itk::Point GetRotatedPoint3D(itk::Array rotationParameters, itk::Point input); itk::Matrix GetCenteredRotationMatrix3D(itk::Array rotationParameters,itk::Point centerOfRotation); // itk::Matrix GetComposedMatrix3D(itk::Matrix firstTransform, itk::Matrix secondTransform); itk::Matrix ReadMatrix4D(std::string fileName); itk::Matrix ReadMatrix3D(std::string fileName); itk::Matrix ReadMatrix2D(std::string fileName); template itk::Matrix ReadMatrix(std::string fileName); itk::Matrix GetRotationalPartMatrix3D(itk::Matrix input); itk::Matrix GetRotationalPartMatrix(itk::Matrix input); itk::Matrix GetRotationalPartMatrix2D(itk::Matrix input); itk::Matrix GetRotationalPartMatrix(itk::Matrix input); itk::Vector GetTranslationPartMatrix3D(itk::Matrix input); itk::Vector GetTranslationPartMatrix(itk::Matrix input); itk::Vector GetTranslationPartMatrix2D(itk::Matrix input); itk::Vector GetTranslationPartMatrix(itk::Matrix input); //============================================================================ //Inline functions definition in header file, otherwise linker errors //============================================================================ //======================================================================================== inline itk::Matrix GetForwardAffineMatrix2D(itk::Array transformParameters) { itk::Matrix matrix; //rotation part matrix[0][0]=cos(transformParameters[0]); matrix[0][1]=-sin(transformParameters[0]); matrix[1][0]=sin(transformParameters[0]); matrix[1][1]=cos(transformParameters[0]); //translation part matrix[0][2]=transformParameters[1]; matrix[1][2]=transformParameters[2]; //homogenize matrix[2][0]=0.; matrix[2][1]=0.; matrix[2][2]=1.; return matrix; } inline itk::Matrix GetForwardAffineMatrix3D(itk::Array transformParameters) { itk::Matrix matrix; //rotational part matrix[0][0]= cos(transformParameters[1])*cos(transformParameters[2]); matrix[0][1]= sin(transformParameters[0])*sin(transformParameters[1])*cos(transformParameters[2])+ sin(transformParameters[2])*cos(transformParameters[0]); matrix[0][2]= -cos(transformParameters[0])*sin(transformParameters[1])*cos(transformParameters[2])+sin(transformParameters[0])*sin(transformParameters[2]); matrix[1][0]= -cos(transformParameters[1])*sin(transformParameters[2]); matrix[1][1]= -sin(transformParameters[0])*sin(transformParameters[1])*sin(transformParameters[2])+cos(transformParameters[0])*cos(transformParameters[2]); matrix[1][2]= cos(transformParameters[0])*sin(transformParameters[1])*sin(transformParameters[2])+sin(transformParameters[0])*cos(transformParameters[2]); matrix[2][0]= sin(transformParameters[1]); matrix[2][1]= -sin(transformParameters[0])*cos(transformParameters[1]); matrix[2][2]= cos(transformParameters[0])*cos(transformParameters[1]); //translational part matrix[0][3]=transformParameters[3]; matrix[1][3]=transformParameters[4]; matrix[2][3]=transformParameters[5]; //homogenize matrix[3][0]=0.; matrix[3][1]=0.; matrix[3][2]=0.; matrix[3][3]=1.; return matrix; } inline itk::Matrix GetBackwardAffineMatrix2D(itk::Array transformParameters) { itk::Matrix matrix; //rotation part matrix[0][0]=cos(transformParameters[0]); matrix[0][1]=sin(transformParameters[0]); matrix[1][0]=-sin(transformParameters[0]); matrix[1][1]=cos(transformParameters[0]); //translation part matrix[0][2]=transformParameters[1]; matrix[1][2]=transformParameters[2]; //homogenize matrix[2][0]=0.; matrix[2][1]=0.; matrix[2][2]=1.; return matrix; } inline itk::Matrix GetBackwardAffineMatrix3D(itk::Array transformParameters) { itk::Matrix matrix; //rotational part matrix[0][0]= cos(transformParameters[1])*cos(transformParameters[2]); matrix[0][1]= sin(transformParameters[0])*sin(transformParameters[1])*cos(transformParameters[2])- sin(transformParameters[2])*cos(transformParameters[0]); matrix[0][2]= cos(transformParameters[0])*sin(transformParameters[1])*cos(transformParameters[2])+sin(transformParameters[0])*sin(transformParameters[2]); matrix[1][0]= cos(transformParameters[1])*sin(transformParameters[2]); matrix[1][1]= sin(transformParameters[0])*sin(transformParameters[1])*sin(transformParameters[2])+cos(transformParameters[0])*cos(transformParameters[2]); matrix[1][2]= cos(transformParameters[0])*sin(transformParameters[1])*sin(transformParameters[2])-sin(transformParameters[0])*cos(transformParameters[2]); matrix[2][0]= -sin(transformParameters[1]); matrix[2][1]= sin(transformParameters[0])*cos(transformParameters[1]); matrix[2][2]= cos(transformParameters[0])*cos(transformParameters[1]); //translational part matrix[0][3]=transformParameters[3]; matrix[1][3]=transformParameters[4]; matrix[2][3]=transformParameters[5]; //homogenize matrix[3][0]=0.; matrix[3][1]=0.; matrix[3][2]=0.; matrix[3][3]=1.; return matrix; } inline itk::Matrix GetRotationMatrix3D(itk::Array rotationParameters) { itk::Matrix matrix; //rotational part matrix[0][0]= cos(rotationParameters[1])*cos(rotationParameters[2]); matrix[0][1]= sin(rotationParameters[0])*sin(rotationParameters[1])*cos(rotationParameters[2])+ sin(rotationParameters[2])*cos(rotationParameters[0]); matrix[0][2]= -cos(rotationParameters[0])*sin(rotationParameters[1])*cos(rotationParameters[2])+sin(rotationParameters[0])*sin(rotationParameters[2]); matrix[1][0]= -cos(rotationParameters[1])*sin(rotationParameters[2]); matrix[1][1]= -sin(rotationParameters[0])*sin(rotationParameters[1])*sin(rotationParameters[2])+cos(rotationParameters[0])*cos(rotationParameters[2]); matrix[1][2]= cos(rotationParameters[0])*sin(rotationParameters[1])*sin(rotationParameters[2])+sin(rotationParameters[0])*cos(rotationParameters[2]); matrix[2][0]= sin(rotationParameters[1]); matrix[2][1]= -sin(rotationParameters[0])*cos(rotationParameters[1]); matrix[2][2]= cos(rotationParameters[0])*cos(rotationParameters[1]); return matrix; } inline itk::Matrix GetRotationMatrix2D(itk::Array rotationParameters) { itk::Matrix matrix; matrix[0][0] = cos(rotationParameters[0]); matrix[1][0] = sin(rotationParameters[0]); matrix[0][1] = -matrix[1][0]; matrix[1][1] = matrix[0][0]; return matrix; } //======================================================================================== inline itk::Point GetRotatedPoint3D(itk::Array rotationParameters, itk::Point input) { itk::Matrix matrix = GetRotationMatrix3D(rotationParameters); itk::Point output; for (unsigned int i=0;i<3;i++) { output[i]=0.0; for (unsigned int j=0;j<3;j++) output[i]+=matrix(i,j)*input[j]; } return output; } inline itk::Matrix GetCenteredRotationMatrix3D(itk::Array rotationParameters,itk::Point centerOfRotation ) { //rotational part is identical as affine matrix, translations change itk::Array parameters(6); for(unsigned int i=0; i<3;i++) parameters[i]=rotationParameters[i]; for(unsigned int i=3; i<6;i++) parameters[i]=centerOfRotation[i-3]; itk::Matrix matrix=GetForwardAffineMatrix3D(parameters); //Get the rotation of the centerOfRotation itk::Matrix rotation = GetRotationalPartMatrix3D(matrix); itk::Point rotatedCenter=rotation*centerOfRotation; //GetRotatedPoint3D(rotationParameters, centerOfRotation); //Substract this point to the translational part matrix(0,3)-=rotatedCenter[0]; matrix(1,3)-=rotatedCenter[1]; matrix(2,3)-=rotatedCenter[2]; return matrix; } // inline itk::Matrix GetComposedMatrix3D(itk::Matrix firstAppliedTransform, itk::Matrix secondAppliedTransform) // { // itk::Matrix matrix; // for (unsigned int i=0;i<4;i++) // for (unsigned int j=0;j<4;j++) // { // matrix[i][j]=0.0; // for (unsigned int k=0;k<4;k++) // matrix[i][j]+=firstAppliedTransform[i][k]*secondAppliedTransform[k][j]; // } // return matrix; // } //======================================================================================== inline itk::Matrix ReadMatrix4D(std::string fileName) { // read input matrix std::ifstream is; openFileForReading(is, fileName); std::vector nb; double x; skipComment(is); is >> x; while (!is.eof()) { nb.push_back(x); skipComment(is); is >> x; } //copy it to the matrix itk::Matrix matrix; unsigned int index=0; for (unsigned int i=0;i<5;i++) for (unsigned int j=0;j<5;j++) matrix[i][j]=nb[index++]; return matrix; } itk::Matrix ReadMatrix3D(std::string fileName); inline vtkMatrix4x4* ReadVTKMatrix3D(std::string fileName) { // read input matrix std::ifstream is; openFileForReading(is, fileName); std::vector nb; double x; skipComment(is); is >> x; while (!is.eof()) { nb.push_back(x); skipComment(is); is >> x; } vtkSmartPointer matrix = vtkSmartPointer::New(); unsigned int index=0; for (unsigned int i=0;i<4;i++) for (unsigned int j=0;j<4;j++) matrix->SetElement(i,j, nb[index++]); return matrix; } inline itk::Matrix ReadMatrix2D(std::string fileName) { // read input matrix std::ifstream is; openFileForReading(is, fileName); std::vector nb; double x; skipComment(is); is >> x; while (!is.eof()) { nb.push_back(x); skipComment(is); is >> x; } //copy it to the matrix itk::Matrix matrix; unsigned int index=0; for (unsigned int i=0;i<3;i++) for (unsigned int j=0;j<3;j++) matrix[i][j]=nb[index++]; return matrix; } template inline itk::Matrix ReadMatrix(std::string fileName) { // read input matrix std::ifstream is; openFileForReading(is, fileName); std::vector nb; double x; skipComment(is); is >> x; while (!is.eof()) { nb.push_back(x); skipComment(is); is >> x; } //copy it to the matrix itk::Matrix matrix; unsigned int index=0; for (unsigned int i=0;i inline itk::Matrix ReadMatrix<2> (std::string fileName) // { // return ReadMatrix2D(fileName); // } // template<> inline itk::Matrix ReadMatrix<3> (std::string fileName) // { // return ReadMatrix3D(fileName); // } // template<> inline itk::Matrix ReadMatrix<4> (std::string fileName) // { // return ReadMatrix4D(fileName); // } //======================================================================================== inline itk::Matrix GetRotationalPartMatrix4D(itk::Matrix input) { itk::Matrix matrix; matrix[0][0]= input[0][0]; matrix[0][1]= input[0][1]; matrix[0][2]= input[0][2]; matrix[0][3]= input[0][3]; matrix[1][0]= input[1][0]; matrix[1][1]= input[1][1]; matrix[1][2]= input[1][2]; matrix[1][3]= input[1][3]; matrix[2][0]= input[2][0]; matrix[2][1]= input[2][1]; matrix[2][2]= input[2][2]; matrix[2][2]= input[2][2]; matrix[2][3]= input[2][3]; matrix[3][0]= input[3][0]; matrix[3][1]= input[3][1]; matrix[3][2]= input[3][2]; matrix[3][2]= input[3][2]; matrix[3][3]= input[3][3]; return matrix; } inline itk::Matrix GetRotationalPartMatrix3D(itk::Matrix input) { itk::Matrix matrix; matrix[0][0]= input[0][0]; matrix[0][1]= input[0][1]; matrix[0][2]= input[0][2]; matrix[1][0]= input[1][0]; matrix[1][1]= input[1][1]; matrix[1][2]= input[1][2]; matrix[2][0]= input[2][0]; matrix[2][1]= input[2][1]; matrix[2][2]= input[2][2]; return matrix; } inline itk::Matrix GetRotationalPartMatrix2D(itk::Matrix input) { itk::Matrix matrix; matrix[0][0]= input[0][0]; matrix[0][1]= input[0][1]; matrix[0][2]= input[0][2]; matrix[1][0]= input[1][0]; matrix[1][1]= input[1][1]; return matrix; } inline itk::Matrix GetRotationalPartMatrix(itk::Matrix input) { return GetRotationalPartMatrix4D(input); } inline itk::Matrix GetRotationalPartMatrix(itk::Matrix input) { return GetRotationalPartMatrix3D(input); } inline itk::Matrix GetRotationalPartMatrix(itk::Matrix input) { return GetRotationalPartMatrix2D(input); } //======================================================================================== inline itk::Vector GetTranslationPartMatrix4D(itk::Matrix input) { itk::Vector vec; vec[0]= input[0][4]; vec[1]= input[1][4]; vec[2]= input[2][4]; vec[3]= input[3][4]; return vec; } inline itk::Vector GetTranslationPartMatrix3D(itk::Matrix input) { itk::Vector vec; vec[0]= input[0][3]; vec[1]= input[1][3]; vec[2]= input[2][3]; return vec; } inline itk::Vector GetTranslationPartMatrix2D(itk::Matrix input) { itk::Vector vec; vec[0]= input[0][2]; vec[1]= input[1][2]; return vec; } inline itk::Vector GetTranslationPartMatrix(itk::Matrix input) { return GetTranslationPartMatrix4D(input); } inline itk::Vector GetTranslationPartMatrix(itk::Matrix input) { return GetTranslationPartMatrix3D(input); } inline itk::Vector GetTranslationPartMatrix(itk::Matrix input) { return GetTranslationPartMatrix2D(input); } } #endif //#define CLITKTRANSFORMUTILITIES_H