]> Creatis software - clitk.git/blob - common/clitkElastix.h
Merge branch 'master' into extentSimon
[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 #include <iterator>
24
25 //--------------------------------------------------------------------
26 namespace clitk {
27
28 //-------------------------------------------------------------------
29 bool
30 GetElastixValueFromTag(std::ifstream & is,
31                        std::string tag,
32                        std::string & value)
33 {
34   std::string line;
35   is.seekg (0, is.beg);
36   while(std::getline(is, line))   {
37     unsigned pos = line.find(tag);
38     if (pos<line.size()) {
39       value=line.substr(pos+tag.size(),line.size()-2);// remove last ')'
40       value.erase (std::remove (value.begin(), value.end(), '"'), value.end());
41       value.erase (std::remove (value.begin(), value.end(), ')'), value.end());
42       return true;
43     }
44   }
45   return false;
46 }
47 //-------------------------------------------------------------------
48
49
50 //-------------------------------------------------------------------
51 void
52 GetValuesFromValue(const std::string & s,
53                    std::vector<std::string> & values)
54 {
55   std::stringstream strstr(s);
56   std::istream_iterator<std::string> it(strstr);
57   std::istream_iterator<std::string> end;
58   std::vector<std::string> results(it, end);
59   values.clear();
60   values.resize(results.size());
61   for(uint i=0; i<results.size(); i++) values[i] = results[i];
62 }
63 //-------------------------------------------------------------------
64
65
66 //-------------------------------------------------------------------
67 template<unsigned int Dimension>
68 typename itk::Matrix<double, Dimension+1, Dimension+1>
69 createMatrixFromElastixFile(std::string& filename, bool verbose=true) {
70   if (Dimension != 3) {
71     FATAL("Only 3D yet" << std::endl);
72   }
73   typename itk::Matrix<double, Dimension+1, Dimension+1> matrix, init;
74
75   itk::Euler3DTransform<double>::Pointer mat = itk::Euler3DTransform<double>::New();
76   itk::Euler3DTransform<double>::Pointer previous;
77
78   // Open file
79   if (verbose) std::cout << "Read elastix parameters in " << filename << std::endl;
80   std::ifstream is;
81   clitk::openFileForReading(is, filename);
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 << std::endl);
88   }
89   if (s != "EulerTransform") {
90     FATAL("Sorry only 'EulerTransform'" << std::endl);
91   }
92
93   // Get previous
94   b = GetElastixValueFromTag(is, "InitialTransformParametersFileName ", s);
95   if(s == "NoInitialTransform")
96     init.SetIdentity();
97   else
98     init = createMatrixFromElastixFile<Dimension>(s, verbose);
99
100   // Get CenterOfRotationPoint
101   GetElastixValueFromTag(is, "CenterOfRotationPoint ", s); // space is needed
102   if (!b) {
103     FATAL("Error must read 'CenterOfRotationPoint' in " << filename << std::endl);
104   }
105   std::vector<std::string> cor;
106   GetValuesFromValue(s, cor);
107   itk::Euler3DTransform<double>::CenterType c;
108   for(uint i=0; i<3; i++)
109     c[i] = atof(cor[i].c_str());
110   mat->SetCenter(c);
111
112   // Get Transformparameters
113   GetElastixValueFromTag(is, "ComputeZYX ", s); // space is needed
114   mat->SetComputeZYX( s==std::string("true") );
115
116   // Get Transformparameters
117   GetElastixValueFromTag(is, "TransformParameters ", s); // space is needed
118   if (!b) {
119     FATAL("Error must read 'TransformParameters' in " << filename << std::endl);
120   }
121   std::vector<std::string> results;
122   GetValuesFromValue(s, results);
123
124   // construct a stream from the string
125   itk::Euler3DTransform<double>::ParametersType p;
126   p.SetSize(6);
127   for(uint i=0; i<3; i++)
128     p[i] = atof(results[i].c_str()); // Rotation
129   for(uint i=0; i<3; i++)
130     p[i+3] = atof(results[i+3].c_str()); // Translation
131   mat->SetParameters(p);
132
133   if (verbose) {
134     std::cout << "Rotation      (deg) : " << rad2deg(p[0]) << " " << rad2deg(p[1]) << " " << rad2deg(p[2]) << std::endl;
135     std::cout << "Center of rot (phy) : " << c[0] << " " << c[1] << " " << c[2] << std::endl;
136     std::cout << "Translation   (phy) : " << p[3] << " " << p[4] << " " << p[5] << std::endl;
137   }
138
139   previous = itk::Euler3DTransform<double>::New();
140   previous->SetParameters(mat->GetParameters());
141   previous->SetCenter(c);
142   previous->SetComputeZYX(mat->GetComputeZYX());
143
144   mat = previous;
145   for(uint i=0; i<3; i++)
146     for(uint j=0; j<3; j++)
147       matrix[i][j] = mat->GetMatrix()[i][j];
148   // Offset is -Rc + t + c
149   matrix[0][3] = mat->GetOffset()[0];
150   matrix[1][3] = mat->GetOffset()[1];
151   matrix[2][3] = mat->GetOffset()[2];
152   matrix[3][3] = 1;
153
154   return matrix*init;
155 }
156 }
157 //-------------------------------------------------------------------
158
159 #endif