Shapeworks Studio  2.1
Shape analysis software suite
itkPSMProcrustesRegistration.cxx
1 /*=========================================================================
2  Program: ShapeWorks: Particle-based Shape Correspondence & Visualization
3  Module: $RCSfile: itkPSMProcrustesRegistration.cxx,v $
4  Date: $Date: 2011/03/24 01:17:33 $
5  Version: $Revision: 1.5 $
6  Author: $Author: wmartin $
7 
8  Copyright (c) 2009 Scientific Computing and Imaging Institute.
9  See ShapeWorksLicense.txt for details.
10 
11  This software is distributed WITHOUT ANY WARRANTY; without even
12  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13  PURPOSE. See the above copyright notices for more information.
14 =========================================================================*/
15 #include "itkPSMProcrustesRegistration.h"
16 
17 namespace itk {
18 
19 template<unsigned int VDimension>
20 void
21 PSMProcrustesRegistration<VDimension>
22 ::RunRegistration(int d)
23 {
24  // Assume all domains have the same number of particles.
25  const int totalDomains = m_PSMParticleSystem->GetNumberOfDomains();
26  const int numPoints = m_PSMParticleSystem->GetNumberOfParticles(0);
27  const int numShapes = totalDomains / m_DomainsPerShape;
28  //PSMProcrustesFunctionType typedefs
29  ShapeListType shapelist;
30  ShapeType shapevector;
31  PointType point;
32 
33  // Read input shapes from file list
34  for (int i = d % m_DomainsPerShape; i < totalDomains; i+=m_DomainsPerShape)
35  {
36  int j = 0;
37  shapevector.clear();
38  for (j = 0; j < numPoints; j++)
39  {
40  for (unsigned int k = 0; k < VDimension; k++)
41  {
42  point(k) = m_PSMParticleSystem->GetPosition(j,i)[k];
43  }
44  shapevector.push_back(point);
45  }
46  shapelist.push_back(shapevector);
47  }
48 
49  // Run alignment
50  SimilarityTransformListType transforms;
51 
52  typename PSMProcrustesFunctionType::Pointer procrustes = PSMProcrustesFunctionType::New();
53  procrustes->RunGeneralizedProcrustes(transforms, shapelist);
54  // Construct transform matrices for each particle system.
55  int k = d % m_DomainsPerShape;
56  for (int i = 0; i < numShapes; i++, k += m_DomainsPerShape)
57  {
58  // Transform from Configuration space to Procrustes space. Translation
59  // followed by rotation and scaling.
60  TransformType R; //PSMParticleSystemType typedef
61  if( VDimension == 3 )
62  {
63  if (m_Scaling == true)
64  {
65  R(0,0) = transforms[i].rotation(0,0) * transforms[i].scale;
66  R(1,0) = transforms[i].rotation(1,0) * transforms[i].scale;
67  R(2,0) = transforms[i].rotation(2,0) * transforms[i].scale;
68  R(3,0) = 0.0;
69 
70  R(0,1) = transforms[i].rotation(0,1) * transforms[i].scale;
71  R(1,1) = transforms[i].rotation(1,1) * transforms[i].scale;
72  R(2,1) = transforms[i].rotation(2,1) * transforms[i].scale;
73  R(3,1) = 0.0;
74 
75  R(0,2) = transforms[i].rotation(0,2) * transforms[i].scale;
76  R(1,2) = transforms[i].rotation(1,2) * transforms[i].scale;
77  R(2,2) = transforms[i].rotation(2,2) * transforms[i].scale;
78  R(3,2) = 0.0;
79 
80  R(0,3) = transforms[i].translation(0) * R(0,0) + transforms[i].translation(1) * R(0,1) + transforms[i].translation(2) * R(0,2);
81  R(1,3) = transforms[i].translation(0) * R(1,0) + transforms[i].translation(1) * R(1,1) + transforms[i].translation(2) * R(1,2);
82  R(2,3) = transforms[i].translation(0) * R(2,0) + transforms[i].translation(1) * R(2,1) + transforms[i].translation(2) * R(2,2);
83  R(3,3) = 1.0;
84  }
85  else // do not do scaling
86  {
87  R(0,0) = transforms[i].rotation(0,0);
88  R(1,0) = transforms[i].rotation(1,0);
89  R(2,0) = transforms[i].rotation(2,0);
90  R(3,0) = 0.0;
91 
92  R(0,1) = transforms[i].rotation(0,1);
93  R(1,1) = transforms[i].rotation(1,1);
94  R(2,1) = transforms[i].rotation(2,1);
95  R(3,1) = 0.0;
96 
97  R(0,2) = transforms[i].rotation(0,2);
98  R(1,2) = transforms[i].rotation(1,2);
99  R(2,2) = transforms[i].rotation(2,2);
100  R(3,2) = 0.0;
101 
102  R(0,3) = transforms[i].translation(0) * R(0,0) + transforms[i].translation(1) * R(0,1) + transforms[i].translation(2) * R(0,2);
103  R(1,3) = transforms[i].translation(0) * R(1,0) + transforms[i].translation(1) * R(1,1) + transforms[i].translation(2) * R(1,2);
104  R(2,3) = transforms[i].translation(0) * R(2,0) + transforms[i].translation(1) * R(2,1) + transforms[i].translation(2) * R(2,2);
105  R(3,3) = 1.0;
106  }
107 
108  m_PSMParticleSystem->SetTransform(k, R);
109  std::cout << "R" << std::endl;
110  std::cout << R << std::endl;
111  std::cout << std::endl;
112  }
113  else if( VDimension == 2 )
114  {
115  if (m_Scaling == true)
116  {
117  R(0,0) = transforms[i].rotation(0,0) * transforms[i].scale;
118  R(1,0) = transforms[i].rotation(1,0) * transforms[i].scale;
119  R(2,0) = 0.0;
120 
121  R(0,1) = transforms[i].rotation(0,1) * transforms[i].scale;
122  R(1,1) = transforms[i].rotation(1,1) * transforms[i].scale;
123  R(2,1) = 0.0;
124 
125  R(0,2) = transforms[i].translation(0) * R(0,0) + transforms[i].translation(1) * R(0,1);
126  R(1,2) = transforms[i].translation(0) * R(1,0) + transforms[i].translation(1) * R(1,1);
127  R(2,2) = 1.0;
128  }
129  else // do not do scaling
130  {
131  R(0,0) = transforms[i].rotation(0,0);
132  R(1,0) = transforms[i].rotation(1,0);
133  R(2,0) = 0.0;
134 
135  R(0,1) = transforms[i].rotation(0,1);
136  R(1,1) = transforms[i].rotation(1,1);
137  R(2,1) = 0.0;
138 
139  R(0,2) = transforms[i].translation(0) * R(0,0) + transforms[i].translation(1) * R(0,1);
140  R(1,2) = transforms[i].translation(0) * R(1,0) + transforms[i].translation(1) * R(1,1);
141  R(2,2) = 1.0;
142  }
143 
144  m_PSMParticleSystem->SetTransform(k, R);
145  std::cout << "R" << std::endl;
146  std::cout << R << std::endl;
147  std::cout << std::endl;
148  }
149  } // end for loop
150 } // end RunRegistration
151  // Explicitly instantiate the function for 3D and 2D
154 } // end namespace itk
This class interfaces with the PSMProcrustesFunction class to register a list of point sets...