Shapeworks Studio  2.1
Shape analysis software suite
itkPSMProcrustesFunctionTest.cxx
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 
19 #include <iostream>
20 #include <fstream>
21 #include "itkPSMProcrustesFunction.h"
22 #include "itkCommand.h"
23 #include "itkPSMProjectReader.h"
24 
25 int itkPSMProcrustesFunctionTest( int argc, char* argv[] )
26 {
27  bool passed = true;
28  double value1, value2, value3;
29  itk::PSMProcrustesFunction<3>::PointType pt;
30  std::string errstring = "";
31  std::string output_path = "";
32  std::string input_path_prefix = "";
33  itk::PSMProcrustesFunction<3>::ShapeType s;
34  itk::PSMProcrustesFunction<3>::ShapeListType sl;
35 
36  // Check for proper arguments
37  if (argc < 2)
38  {
39  std::cout << "Wrong number of arguments. \nUse: "
40  << "itkPSMProcrustesFunctionTest parameter_file [output_path] [input_path]\n"
41  << "See itk::PSMParameterFileReader for documentation on the parameter file format.\n"
42  <<" Note that input_path will be prefixed to any file names and paths in the xml parameter file.\n"
43  << std::endl;
44  return EXIT_FAILURE;
45  }
46 
47  if (argc >2)
48  {
49  output_path = std::string(argv[2]);
50  }
51 
52  if (argc >3)
53  {
54  input_path_prefix = std::string(argv[3]);
55  }
56 
57  try
58  {
59  // Read the project parameters
60  itk::PSMProjectReader::Pointer xmlreader = itk::PSMProjectReader::New();
61  xmlreader->SetFileName(argv[1]);
62  xmlreader->Update();
63 
64  itk::PSMProject::Pointer project = xmlreader->GetOutput();
65 
66  // Load the point files
67  const std::vector<std::string> &pt_files = project->GetModel(std::string("initialization"));
68  std::cout << "Reading the point files to be registered ..." << std::endl;
69  for (unsigned int i = 0; i < pt_files.size(); i++)
70  {
71  // Read the points for this file and add as a list
72  s.clear();
73  // Open the ascii file.
74  std::ifstream in;
75  in.open( (input_path_prefix + pt_files[i]).c_str() );
76  if ( !in )
77  {
78  errstring += "Could not open point file for input.";
79  passed = false;
80  break;
81  }
82 
83  // Read all of the points, one point per line.
84  while (in)
85  {
86  in>>value1>>value2>>value3;
87  pt[0] = value1;
88  pt[1] = value2;
89  pt[2] = value3;
90  s.push_back(pt);
91  }
92  // This algorithm pushes the last point twice
93  s.pop_back();
94 
95  // Store the shape in the list
96  sl.push_back(s);
97  in.close();
98  std::cout << " " << pt_files[i] << std::endl;
99  }
100 
101  std::cout << "Done!" << std::endl;
102 
103  itk::PSMProcrustesFunction<3>::SimilarityTransformListType transforms;
104  itk::PSMProcrustesFunction<3>::Pointer procrustes = itk::PSMProcrustesFunction<3>::New();
105  procrustes->RunGeneralizedProcrustes(transforms, sl);
106 
107  // Check whether shapes are correctly registered by checking each point.
108  // Reference shape is chosen to be the first shape in the list.
109  itk::PSMProcrustesFunction<3>::ShapeType reference_shape;
110  itk::PSMProcrustesFunction<3>::ShapeIteratorType it_ref;
111  itk::PSMProcrustesFunction<3>::ShapeIteratorType it;
112  reference_shape = sl[0];
113  for (unsigned int i = 1; i < pt_files.size(); i++)
114  {
115  s = sl[i];
116  for(it = s.begin(),it_ref = reference_shape.begin();it != s.end(),it_ref != reference_shape.end(); it++,it_ref++)
117  {
118  itk::PSMProcrustesFunction<3>::PointType & point1 = (*it_ref);
119  itk::PSMProcrustesFunction<3>::PointType & point2 = (*it);
120  // Subtract value of each point from the reference points
121  for(int j = 0; j<3; j++)
122  {
123  float diff = point1[j] - point2[j];
124  if(diff > 1e-6)
125  {
126  passed = false;
127  break;
128  }
129  }
130  }
131  }
132 
133  // Print out the outputs
134  // Load the output model names
135  const std::vector<std::string> &out_files = project->GetModel(std::string("optimized"));
136 
137  for (unsigned int i = 0; i < out_files.size(); i++)
138  {
139  // Open the output file.
140  std::string fname = output_path + out_files[i];
141  std::ofstream out;
142  out.open( fname.c_str() );
143  s = sl[i];
144  if ( !out )
145  {
146  errstring += "Could not open point file for output: ";
147  }
148  else
149  {
150  for(itk::PSMProcrustesFunction<3>::ShapeIteratorType it = s.begin(); it != s.end(); it++)
151  {
152  itk::PSMProcrustesFunction<3>::PointType & point = (*it);
153  out << point[0] << " " << point[1] << " " << point[2] << std::endl;
154  }
155  out.close();
156  }
157  }
158  passed = true;
159  }
160 
161  catch(itk::ExceptionObject &e)
162  {
163  errstring = "ITK exception with description: " + std::string(e.GetDescription())
164  + std::string("\n at location:") + std::string(e.GetLocation())
165  + std::string("\n in file:") + std::string(e.GetFile());
166  passed = false;
167  }
168  catch(...)
169  {
170  errstring = "Unknown exception thrown";
171  passed = false;
172  }
173 
174  if (passed)
175  {
176  std::cout << "All tests passed" << std::endl;
177  return EXIT_SUCCESS;
178  }
179  else
180  {
181  std::cout << "Test failed with the following error:" << std::endl;
182  std::cout << errstring << std::endl;
183  return EXIT_FAILURE;
184  }
185 }
Generalized Procrustes Analysis is the rigid registration between different input shapes represented ...
void RunGeneralizedProcrustes(SimilarityTransformListType &transform, ShapeListType &shapes)