]> Creatis software - clitk.git/blob - tools/clitkTransformLandmarks.cxx
clitkTransformLandmarks
[clitk.git] / tools / clitkTransformLandmarks.cxx
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 #include "clitkTransformLandmarks_ggo.h"
19
20 #include "clitkTransformUtilities.h"
21 #include <string>
22 #include <vector>
23 #include <iostream>
24 #include <fstream>
25
26 typedef itk::Matrix<double, 4, 4> MatrixType;
27 typedef itk::Point<double, 4> PointType;
28 typedef std::vector<PointType> PointArrayType;
29 typedef itk::FixedArray<std::string, 2> TxtDataType;
30 typedef std::vector<TxtDataType> TxtDataArrayType;
31
32
33 void read_points_txt(const std::string& fileName, PointArrayType& points, TxtDataArrayType& data);
34 void write_points_txt(const std::string& fileName, const PointArrayType& points, const TxtDataArrayType& data);
35
36 void read_points_pts(const std::string& fileName, PointArrayType& points);
37 void write_points_pts(const std::string& fileName, const PointArrayType& points);
38
39 void apply_spacing(const PointArrayType& input, const double* spacing, PointArrayType& output);
40 void transform_points(const PointArrayType& input, const MatrixType& matrix, PointArrayType& output);
41
42
43 bool verbose = false;
44
45 int main(int argc, char** argv)
46 {
47   GGO(clitkTransformLandmarks, args_info);
48   verbose = args_info.verbose_flag;
49
50   TxtDataArrayType data;
51   PointArrayType inputPoints;
52   if (strcmp(args_info.type_arg, "txt") == 0) {
53     read_points_txt(args_info.input_arg, inputPoints, data);
54   }
55   else {
56     read_points_pts(args_info.input_arg, inputPoints);
57   }
58   
59   PointArrayType outputPoints;
60   PointArrayType spacingPoints;
61   PointArrayType* workingInputPoints = &inputPoints;
62   PointArrayType* workingOutputPoints = &outputPoints;
63   if (args_info.spacing_given) {
64     if (verbose) std::cout << "Processing spacing..." << std::endl;
65     
66     apply_spacing(*workingInputPoints, args_info.spacing_arg, spacingPoints);
67     workingInputPoints = &spacingPoints;
68     workingOutputPoints = &spacingPoints;
69   }
70
71   MatrixType matrix;
72   if (args_info.matrix_given) {
73     matrix = clitk::ReadMatrix3D(args_info.matrix_arg);
74     transform_points(*workingInputPoints, matrix, outputPoints);
75     workingOutputPoints = &outputPoints;
76   }
77
78   if (strcmp(args_info.type_arg, "txt") == 0) {
79     write_points_txt(args_info.output_arg, *workingOutputPoints, data);
80   }
81   else {
82     write_points_pts(args_info.output_arg, *workingOutputPoints);
83   }
84   
85   return 0;
86 }
87
88 void read_points_txt(const std::string& fileName, PointArrayType& points, TxtDataArrayType& data)
89 {
90   std::ifstream landmarksFile(fileName.c_str());
91   if (landmarksFile.fail()) {
92     std::cerr << "ERROR: could not open '" << fileName << "'" << std::endl;
93     exit(-2);
94   }
95   
96   std::string line;
97   std::getline(landmarksFile, line);
98   if (line.find("LANDMARKS") == std::string::npos) {
99     std::cerr << "ERROR: invalid landmarks file '" << fileName << "'" << std::endl;
100     exit(-3);
101   }
102   
103   PointType p;
104   p.Fill(1);
105   
106   TxtDataType d;
107   
108   while (!landmarksFile.eof()) {
109     // read id, x, y, z, d1, d2
110     landmarksFile >> d[0] >> p[0] >> p[1] >> p[2] >> d[1];// >> d[2];
111     if (landmarksFile.fail())
112       break;
113     
114     if (verbose){
115       std::cout << "point " << p << std::endl;
116       std::cout << "data " << " " << d[0] << " " << d[1] << std::endl;
117     }
118     
119     points.push_back(p);
120     data.push_back(d);
121   }
122 }
123
124 void write_points_txt(const std::string& fileName, const PointArrayType& points, const TxtDataArrayType& data) 
125 {
126   std::ofstream landmarksFile(fileName.c_str());
127   
128   landmarksFile << "LANDMARKS1" << std::endl;
129   for (size_t i = 0; i < points.size(); i++)
130     landmarksFile << data[i][0] << " " << points[i][0] << " " << points[i][1] << " " << points[i][2] << " " << data[i][1] << " " << std::endl;
131 }
132
133 void read_points_pts(const std::string& fileName, PointArrayType& points)
134 {
135   std::ifstream landmarksFile(fileName.c_str());
136   if (landmarksFile.fail()) {
137     std::cerr << "ERROR: could not open '" << fileName << "'" << std::endl;
138     exit(-2);
139   }
140   
141   std::string line;
142   std::getline(landmarksFile, line);
143   if (line.find("#X") != 0) {
144     std::cerr << "ERROR: invalid landmarks file '" << fileName << "'" << std::endl;
145     exit(-3);
146   }
147   
148   PointType p;
149   p.Fill(1);
150   
151   while (!landmarksFile.eof()) {
152     // read id, x, y, z, d1, d2
153     landmarksFile >> p[0] >> p[1] >> p[2];
154     if (landmarksFile.fail())
155       break;
156     
157     if (verbose){
158       std::cout << "point " << p << std::endl;
159     }
160     
161     points.push_back(p);
162   }
163 }
164
165 void write_points_pts(const std::string& fileName, const PointArrayType& points)
166 {
167   std::ofstream landmarksFile(fileName.c_str());
168   
169   landmarksFile << "#X\tY\tZ" << std::endl;
170   for (size_t i = 0; i < points.size(); i++)
171     landmarksFile << points[i][0] << "\t" << points[i][1] << "\t" << points[i][2] << "\t" << std::endl;
172 }
173
174 void apply_spacing(const PointArrayType& input, const double* spacing, PointArrayType& output)
175 {
176   PointType out;
177   out.Fill(1);
178   
179   for (size_t i = 0; i < input.size(); i++) {
180     out[0] = input[i][0] * spacing[0];
181     out[1] = input[i][1] * spacing[1];
182     out[2] = input[i][2] * spacing[2];
183     if (verbose){
184       std::cout << "output " << out << std::endl;
185     }
186     output.push_back(out);
187   }
188 }
189
190 void transform_points(const PointArrayType& input, const MatrixType& matrix, PointArrayType& output)
191 {
192   for (size_t i = 0; i < input.size(); i++) {
193     output.push_back(matrix * input[i]);
194   }
195 }
196