Shapeworks Studio  2.1
Shape analysis software suite
itkPSMProcrustesFunction2DTest.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 itkPSMProcrustesFunction2DTest( int argc, char* argv[] )
26 {
27  bool passed = true;
28  double value1, value2, value3;
29  itk::PSMProcrustesFunction<2>::PointType pt;
30  std::string errstring = "";
31  std::string output_path = "";
32  std::string input_path_prefix = "";
33  itk::PSMProcrustesFunction<2>::ShapeType s;
34  itk::PSMProcrustesFunction<2>::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  s.push_back(pt);
90  }
91  // This algorithm pushes the last point twice
92  s.pop_back();
93 
94  // Store the shape in the list
95  sl.push_back(s);
96  in.close();
97  std::cout << " " << pt_files[i] << std::endl;
98  }
99 
100  std::cout << "Done!" << std::endl;
101 
102  itk::PSMProcrustesFunction<2>::SimilarityTransformListType transforms;
103  itk::PSMProcrustesFunction<2>::Pointer procrustes = itk::PSMProcrustesFunction<2>::New();
104  procrustes->RunGeneralizedProcrustes(transforms, sl);
105 
106  // Check whether shapes are correctly registered by checking each point.
107  // Reference shape is chosen to be the first shape in the list.
108  itk::PSMProcrustesFunction<2>::ShapeType reference_shape;
109  itk::PSMProcrustesFunction<2>::ShapeIteratorType it_ref;
110  itk::PSMProcrustesFunction<2>::ShapeIteratorType it;
111  reference_shape = sl[0];
112  for (unsigned int i = 1; i < pt_files.size(); i++)
113  {
114  s = sl[i];
115  for(it = s.begin(),it_ref = reference_shape.begin();it != s.end(),it_ref != reference_shape.end(); it++,it_ref++)
116  {
117  itk::PSMProcrustesFunction<2>::PointType & point1 = (*it_ref);
118  itk::PSMProcrustesFunction<2>::PointType & point2 = (*it);
119  // Subtract value of each point from the reference points
120  for(int j = 0; j<2; j++)
121  {
122  float diff = point1[j] - point2[j];
123  if(diff > 1e-6)
124  {
125  passed = false;
126  break;
127  }
128  }
129  }
130  }
131 
132  // Print out the outputs
133  // Load the output model names
134  const std::vector<std::string> &out_files = project->GetModel(std::string("optimized"));
135 
136  for (unsigned int i = 0; i < out_files.size(); i++)
137  {
138  // Open the output file.
139  std::string fname = output_path + out_files[i];
140  std::ofstream out;
141  out.open( fname.c_str() );
142  s = sl[i];
143  if ( !out )
144  {
145  errstring += "Could not open point file for output: ";
146  }
147  else
148  {
149  for(itk::PSMProcrustesFunction<2>::ShapeIteratorType it = s.begin(); it != s.end(); it++)
150  {
151  itk::PSMProcrustesFunction<2>::PointType & point = (*it);
152  // Extra point printed to allow visualizing shape in SWViewer.
153  out << point[0] << " " << point[1] << " " << 0.0 << std::endl;
154  }
155  out.close();
156  }
157  }
158  passed = true;
159  // TODO: How to check if shapes have been registered correctly?
160  }
161 
162  catch(itk::ExceptionObject &e)
163  {
164  errstring = "ITK exception with description: " + std::string(e.GetDescription())
165  + std::string("\n at location:") + std::string(e.GetLocation())
166  + std::string("\n in file:") + std::string(e.GetFile());
167  passed = false;
168  }
169  catch(...)
170  {
171  errstring = "Unknown exception thrown";
172  passed = false;
173  }
174 
175  if (passed)
176  {
177  std::cout << "All tests passed" << std::endl;
178  return EXIT_SUCCESS;
179  }
180  else
181  {
182  std::cout << "Test failed with the following error:" << std::endl;
183  std::cout << errstring << std::endl;
184  return EXIT_FAILURE;
185  }
186 }
Generalized Procrustes Analysis is the rigid registration between different input shapes represented ...
void RunGeneralizedProcrustes(SimilarityTransformListType &transform, ShapeListType &shapes)