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