Shapeworks Studio  2.1
Shape analysis software suite
List of all members | Classes | Public Types | Public Member Functions
itk::PSMProcrustesFunction< VDimension > Class Template Reference

Generalized Procrustes Analysis is the rigid registration between different input shapes represented by point correspondences to produce an optimal mean shape. One transformation per shape is computed using the PSMProcrustesFunction. The point sets are registered by translation, rotation and uniform scaling. Scaling can be turned off if required. More...

#include <itkPSMProcrustesFunction.h>

+ Inheritance diagram for itk::PSMProcrustesFunction< VDimension >:
+ Collaboration diagram for itk::PSMProcrustesFunction< VDimension >:

Public Types

typedef double RealType
 
typedef vnl_vector_fixed< double, VDimension > PointType
 
typedef std::vector< PointType > ShapeType
 
typedef ShapeType::iterator ShapeIteratorType
 
typedef std::vector< ShapeType > ShapeListType
 
typedef ShapeListType::iterator ShapeListIteratorType
 
typedef std::vector< SimilarityTransform3D > SimilarityTransformListType
 
typedef SimilarityTransformListType::iterator SimilarityTransformListIteratorType
 
typedef PSMProcrustesFunction Self
 
typedef Object Superclass
 
typedef SmartPointer< SelfPointer
 
typedef SmartPointer< const SelfConstPointer
 

Public Member Functions

 itkNewMacro (Self)
 
 itkTypeMacro (PSMProcrustesFunction, Object)
 
void RunGeneralizedProcrustes (SimilarityTransformListType &transform, ShapeListType &shapes)
 
RealType ComputeSumOfSquares (ShapeListType &shapes)
 
ShapeType TransformShape (ShapeType shape, SimilarityTransform3D &transform)
 

Detailed Description

template<unsigned int VDimension>
class itk::PSMProcrustesFunction< VDimension >

Generalized Procrustes Analysis is the rigid registration between different input shapes represented by point correspondences to produce an optimal mean shape. One transformation per shape is computed using the PSMProcrustesFunction. The point sets are registered by translation, rotation and uniform scaling. Scaling can be turned off if required.

Definition at line 43 of file itkPSMProcrustesFunction.h.

Member Typedef Documentation

template<unsigned int VDimension>
typedef PSMProcrustesFunction itk::PSMProcrustesFunction< VDimension >::Self

Standard class typedefs.

Definition at line 65 of file itkPSMProcrustesFunction.h.

Member Function Documentation

template<unsigned int VDimension>
PSMProcrustesFunction< VDimension >::RealType itk::PSMProcrustesFunction< VDimension >::ComputeSumOfSquares ( ShapeListType &  shapes)

Calculate the sum of squares of the discrepancies between the registered input shapes and the reference shape points. This yields the maximum likelihood estimate.

Definition at line 368 of file itkPSMProcrustesFunction.cxx.

369 {
370  ShapeListIteratorType shapeIt1, shapeIt2;
371  ShapeIteratorType pointIt1, pointIt2;
372 
373  RealType sum = 0.0;
374 
375  for(shapeIt1 = shapes.begin(); shapeIt1 != shapes.end(); shapeIt1++)
376  {
377  for(shapeIt2 = shapes.begin(); shapeIt2 != shapes.end(); shapeIt2++)
378  {
379  ShapeType & shape1 = (*shapeIt1);
380  ShapeType & shape2 = (*shapeIt2);
381 
382  pointIt1 = shape1.begin();
383  pointIt2 = shape2.begin();
384  while(pointIt1 != shape1.end() && pointIt2 != shape2.end())
385  {
386  sum += ((*pointIt1) - (*pointIt2)).squared_magnitude();
387  pointIt1++;
388  pointIt2++;
389  }
390  }
391  }
392  return sum / static_cast<RealType>(shapes.size() * shapes[0].size());
393 }
template<unsigned int VDimension>
itk::PSMProcrustesFunction< VDimension >::itkNewMacro ( Self  )

Method for creation through the object factory.

template<unsigned int VDimension>
itk::PSMProcrustesFunction< VDimension >::itkTypeMacro ( PSMProcrustesFunction< VDimension >  ,
Object   
)

Run-time type information (and related methods).

template<unsigned int VDimension>
template void itk::PSMProcrustesFunction< VDimension >::RunGeneralizedProcrustes ( SimilarityTransformListType &  transform,
ShapeListType &  shapes 
)

Align a list of shapes using Generalized Procrustes Analysis

Definition at line 28 of file itkPSMProcrustesFunction.cxx.

30 {
31  ShapeListIteratorType leaveOutIt;
32  SimilarityTransformListIteratorType transformIt;
33  ShapeIteratorType shapeIt, meanIt;
34  ShapeType shape, mean;
35  SimilarityTransform3D transform;
36  PointType ssqShape, ssqMean;
37 
38  const RealType SOS_EPSILON = 0.1; //1.0e-8;
39 
40  int numOfShapes = shapes.size();
41  std::string errstring = "";
42  // Initialize transform structure
43  transform.rotation.set_identity();
44  transform.scale = 1.0;
45  transform.translation.fill(0.0);
46 
47  // Initialize transforms vector
48  transforms.clear();
49  transforms.reserve(shapes.size());
50  for(int i = 0; i<numOfShapes; i++)
51  {
52  transforms.push_back(transform);
53  }
54 
55  RealType sumOfSquares = ComputeSumOfSquares(shapes);
56  RealType newSumOfSquares, diff = 1e5; // 1e10;
57 
58  int counter = 0;
59  try
60  {
61  while(diff > SOS_EPSILON)
62  {
63  // Initialize ssqShape vector
64  ssqShape.fill(0.0);
65  // Initialize ssqMean vector
66  ssqMean.fill(0.0);
67  transformIt = transforms.begin();
68  //int count = 0;
69  for(leaveOutIt = shapes.begin(); leaveOutIt != shapes.end(); leaveOutIt++)
70  {
71  // Calculate mean of all shapes but one
72  LeaveOneOutMean(mean, shapes, leaveOutIt);
73  (*leaveOutIt) = RunProcrustes((*transformIt), mean, leaveOutIt);
74  transformIt++;
75  } // End shape list iteration
76 
77  // Fix scalings so geometric average = 1
78  RealType scaleAve = 0.0;
79  for(transformIt = transforms.begin(); transformIt != transforms.end(); transformIt++)
80  scaleAve += log((*transformIt).scale);
81 
82  scaleAve = exp(scaleAve / static_cast<RealType>(transforms.size()));
83 
84  SimilarityTransform3D scaleSim;
85  scaleSim.rotation.set_identity();
86  scaleSim.translation.fill(0.0);
87  scaleSim.scale = 1.0 / scaleAve;
88 
89  ShapeListIteratorType shapeListIt = shapes.begin();
90  transformIt = transforms.begin();
91  while(shapeListIt != shapes.end())
92  {
93  TransformShape((*shapeListIt), scaleSim);
94  (*transformIt).scale /= scaleAve;
95 
96  shapeListIt++;
97  transformIt++;
98  }
99  // Calculate the sum of squares of discrepancies between
100  // the shapes
101  newSumOfSquares = ComputeSumOfSquares(shapes);
102  diff = sumOfSquares - newSumOfSquares;
103 
104  sumOfSquares = newSumOfSquares;
105  counter++;
106  std::cout << "DIFF VALUE : " << diff << std::endl;
107  std::cout << "******PROCRUSTES FUNCTION COUNTER******: " << counter << std::endl;
108  if(counter >= 1000)
109  {
110  errstring = "Number of iterations on shapes is too high.";
111  ExceptionObject e( __FILE__, __LINE__ );
112  e.SetDescription( errstring.c_str() );
113  throw e;
114  }
115  } // End while loop
116  } // End try
117  catch(itk::ExceptionObject &e)
118  {
119  errstring = "ITK exception with description: " + std::string(e.GetDescription())
120  + std::string("\n at location:") + std::string(e.GetLocation())
121  + std::string("\n in file:") + std::string(e.GetFile());
122  }
123  catch(...)
124  {
125  errstring = "Unknown exception thrown";
126  }
127 }
RealType ComputeSumOfSquares(ShapeListType &shapes)
ShapeType TransformShape(ShapeType shape, SimilarityTransform3D &transform)
template<unsigned int VDimension>
PSMProcrustesFunction< VDimension >::ShapeType itk::PSMProcrustesFunction< VDimension >::TransformShape ( ShapeType  shape,
SimilarityTransform3D &  transform 
)

Helper function to transform a shape by a similarity transform

Definition at line 321 of file itkPSMProcrustesFunction.cxx.

322 {
323  int numPoints = shape.size();
324  ShapeIteratorType shapeIt;
325  shapeIt = shape.begin();
326 
327  // Multiply by scale
328  while(shapeIt != shape.end())
329  {
330  PointType & point = *shapeIt;
331  (*shapeIt) = transform.scale * point;
332  shapeIt++;
333  }
334 
335  ShapeType transformedShape;
336  vnl_vector_fixed<RealType, VDimension> vec;
337  vec.fill(0.0);
338  for(int i = 0; i < numPoints; i++)
339  transformedShape.push_back(vec);
340 
341  // Multiply by rotation
342  for(int i = 0; i<numPoints; i++)
343  {
344  for(int j = 0; j<VDimension; j++)
345  {
346  for(int k = 0; k<VDimension; k++)
347  {
348  transformedShape[i][j] += shape[i][k] * transform.rotation[k][j];
349  }
350  }
351  }
352 
353  shapeIt = transformedShape.begin();
354 
355  // Add translation
356  while(shapeIt != transformedShape.end())
357  {
358  PointType & point = (*shapeIt);
359  point += transform.translation;
360  shapeIt++;
361  }
362  return transformedShape;
363 }

The documentation for this class was generated from the following files: