]> Creatis software - clitk.git/blob - common/clitkElastix.h
7452bb5634ade92a0b3d4c3b34b854eb064d5e04
[clitk.git] / common / clitkElastix.h
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to:
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
8
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.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
18
19 #ifndef clitkElastix_h
20 #define clitkElastix_h
21
22 #include <itkEuler3DTransform.h>
23
24 //--------------------------------------------------------------------
25 namespace clitk {
26
27 //-------------------------------------------------------------------
28 bool
29 GetElastixValueFromTag(std::ifstream & is,
30                        std::string tag,
31                        std::string & value)
32 {
33   std::string line;
34   is.seekg (0, is.beg);
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());
41       return true;
42     }
43   }
44   return false;
45 }
46 //-------------------------------------------------------------------
47
48
49 //-------------------------------------------------------------------
50 void
51 GetValuesFromValue(const std::string & s,
52                    std::vector<std::string> & values)
53 {
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);
58   values.clear();
59   values.resize(results.size());
60   for(uint i=0; i<results.size(); i++) values[i] = results[i];
61 }
62 //-------------------------------------------------------------------
63
64
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) {
69   if (Dimension != 3) {
70     FATAL("Only 3D yet" << std::endl);
71   }
72   typename itk::Matrix<double, Dimension+1, Dimension+1> matrix;
73
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++) {
77
78     // Open file
79     if (verbose) std::cout << "Read elastix parameters in " << filename[j] << std::endl;
80     std::ifstream is;
81     clitk::openFileForReading(is, filename[j]);
82
83     // Check Transform
84     std::string s;
85     bool b = GetElastixValueFromTag(is, "Transform ", s);
86     if (!b) {
87       FATAL("Error must read 'Transform' in " << filename[j] << std::endl);
88     }
89     if (s != "EulerTransform") {
90       FATAL("Sorry only 'EulerTransform'" << std::endl);
91     }
92
93     // FIXME check
94     //    (InitialTransformParametersFilename[j] "NoInitialTransform")
95
96     // Get CenterOfRotationPoint
97     GetElastixValueFromTag(is, "CenterOfRotationPoint ", s); // space is needed
98     if (!b) {
99       FATAL("Error must read 'CenterOfRotationPoint' in " << filename[j] << std::endl);
100     }
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());
106     mat->SetCenter(c);
107
108     // Get Transformparameters
109     GetElastixValueFromTag(is, "ComputeZYX ", s); // space is needed
110     mat->SetComputeZYX( s==std::string("true") );
111
112     // Get Transformparameters
113     GetElastixValueFromTag(is, "TransformParameters ", s); // space is needed
114     if (!b) {
115       FATAL("Error must read 'TransformParameters' in " << filename[j] << std::endl);
116     }
117     std::vector<std::string> results;
118     GetValuesFromValue(s, results);
119
120     // construct a stream from the string
121     itk::Euler3DTransform<double>::ParametersType p;
122     p.SetSize(6);
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);
128
129     if (verbose) {
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;
133     }
134
135     // Compose with previous if needed
136     if (j!=0) {
137       mat->Compose(previous);
138       if (verbose) {
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;
142       }
143     }
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());
149   }
150
151   mat = previous;
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];
159   matrix[3][3] = 1;
160
161   return matrix;
162 }
163 }
164 //-------------------------------------------------------------------
165
166 #endif