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://www.centreleonberard.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 clitkElastix_h
20 #define clitkElastix_h
22 #include <itkEuler3DTransform.h>
24 //--------------------------------------------------------------------
27 //-------------------------------------------------------------------
29 GetElastixValueFromTag(std::ifstream & is,
35 while(std::getline(is, line)) {
36 unsigned pos = line.find(tag);
37 if (pos<line.size()) {
38 value=line.substr(pos+tag.size(),line.size()-2);// remove last ')'
39 value.erase (std::remove (value.begin(), value.end(), '"'), value.end());
40 value.erase (std::remove (value.begin(), value.end(), ')'), value.end());
46 //-------------------------------------------------------------------
49 //-------------------------------------------------------------------
51 GetValuesFromValue(const std::string & s,
52 std::vector<std::string> & values)
54 std::stringstream strstr(s);
55 std::istream_iterator<std::string> it(strstr);
56 std::istream_iterator<std::string> end;
57 std::vector<std::string> results(it, end);
59 values.resize(results.size());
60 for(uint i=0; i<results.size(); i++) values[i] = results[i];
62 //-------------------------------------------------------------------
65 //-------------------------------------------------------------------
66 template<unsigned int Dimension>
67 typename itk::Matrix<double, Dimension+1, Dimension+1>
68 createMatrixFromElastixFile(std::vector<std::string> & filename, bool verbose=true) {
70 FATAL("Only 3D yet" << std::endl);
72 typename itk::Matrix<double, Dimension+1, Dimension+1> matrix;
74 itk::Euler3DTransform<double>::Pointer mat = itk::Euler3DTransform<double>::New();
75 itk::Euler3DTransform<double>::Pointer previous;
76 for(uint j=0; j<filename.size(); j++) {
79 if (verbose) std::cout << "Read elastix parameters in " << filename[j] << std::endl;
81 clitk::openFileForReading(is, filename[j]);
85 bool b = GetElastixValueFromTag(is, "Transform ", s);
87 FATAL("Error must read 'Transform' in " << filename[j] << std::endl);
89 if (s != "EulerTransform") {
90 FATAL("Sorry only 'EulerTransform'" << std::endl);
94 // (InitialTransformParametersFilename[j] "NoInitialTransform")
96 // Get CenterOfRotationPoint
97 GetElastixValueFromTag(is, "CenterOfRotationPoint ", s); // space is needed
99 FATAL("Error must read 'CenterOfRotationPoint' in " << filename[j] << std::endl);
101 std::vector<std::string> cor;
102 GetValuesFromValue(s, cor);
103 itk::Euler3DTransform<double>::CenterType c;
104 for(uint i=0; i<3; i++)
105 c[i] = atof(cor[i].c_str());
108 // Get Transformparameters
109 GetElastixValueFromTag(is, "ComputeZYX ", s); // space is needed
110 mat->SetComputeZYX( s==std::string("true") );
112 // Get Transformparameters
113 GetElastixValueFromTag(is, "TransformParameters ", s); // space is needed
115 FATAL("Error must read 'TransformParameters' in " << filename[j] << std::endl);
117 std::vector<std::string> results;
118 GetValuesFromValue(s, results);
120 // construct a stream from the string
121 itk::Euler3DTransform<double>::ParametersType p;
123 for(uint i=0; i<3; i++)
124 p[i] = atof(results[i].c_str()); // Rotation
125 for(uint i=0; i<3; i++)
126 p[i+3] = atof(results[i+3].c_str()); // Translation
127 mat->SetParameters(p);
130 std::cout << "Rotation (deg) : " << rad2deg(p[0]) << " " << rad2deg(p[1]) << " " << rad2deg(p[2]) << std::endl;
131 std::cout << "Center of rot (phy) : " << c[0] << " " << c[1] << " " << c[2] << std::endl;
132 std::cout << "Translation (phy) : " << p[3] << " " << p[4] << " " << p[5] << std::endl;
135 // Compose with previous if needed
137 mat->Compose(previous);
139 std::cout << "Composed rotation (deg) : " << rad2deg(mat->GetAngleX()) << " " << rad2deg(mat->GetAngleY()) << " " << rad2deg(mat->GetAngleZ()) << std::endl;
140 std::cout << "Composed center of rot (phy) : " << mat->GetCenter() << std::endl;
141 std::cout << "Compsoed translation (phy) : " << mat->GetTranslation() << std::endl;
144 // previous = mat->Clone(); // ITK4
145 previous = itk::Euler3DTransform<double>::New();
146 previous->SetParameters(mat->GetParameters());
147 previous->SetCenter(c);
148 previous->SetComputeZYX(mat->GetComputeZYX());
152 for(uint i=0; i<3; i++)
153 for(uint j=0; j<3; j++)
154 matrix[i][j] = mat->GetMatrix()[i][j];
155 // Offset is -Rc + t + c
156 matrix[0][3] = mat->GetOffset()[0];
157 matrix[1][3] = mat->GetOffset()[1];
158 matrix[2][3] = mat->GetOffset()[2];
164 //-------------------------------------------------------------------