NifTK  16.4.1 - 0798f20
CMIC's Translational Medical Imaging Platform
itkSwitchableAffineTransform.h
Go to the documentation of this file.
1 /*=============================================================================
2 
3  NifTK: A software platform for medical image computing.
4 
5  Copyright (c) University College London (UCL). All rights reserved.
6 
7  This software is distributed WITHOUT ANY WARRANTY; without even
8  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
9  PURPOSE.
10 
11  See LICENSE.txt in the top level directory for details.
12 
13 =============================================================================*/
14 
15 #ifndef itkSwitchableAffineTransform_h
16 #define itkSwitchableAffineTransform_h
17 
18 #include <iostream>
19 #include <itkMatrix.h>
20 #include "itkUCLBaseTransform.h"
21 #include <itkExceptionObject.h>
22 #include <itkMacro.h>
23 #include <itkAffineTransform.h>
25 
26 namespace itk
27 {
28 
54 template <
55  class TScalarType=double, // Data type for scalars
56  unsigned int NInputDimensions=3, // Number of dimensions in the input space
57  unsigned int NOutputDimensions=3> // Number of dimensions in the output space
58 class ITK_EXPORT SwitchableAffineTransform
59  : public UCLBaseTransform< TScalarType, NInputDimensions, NOutputDimensions >
60 {
61 public:
63  typedef SwitchableAffineTransform<TScalarType,
64  NInputDimensions,
65  NInputDimensions> Self;
66  typedef UCLBaseTransform< TScalarType,
67  NInputDimensions,
68  NOutputDimensions > Superclass;
69  typedef SmartPointer<Self> Pointer;
70  typedef SmartPointer<const Self> ConstPointer;
71 
74 
76  itkStaticConstMacro(InputSpaceDimension, unsigned int, NInputDimensions);
77  itkStaticConstMacro(OutputSpaceDimension, unsigned int, NOutputDimensions);
78  itkStaticConstMacro(ParametersDimension, unsigned int, (NInputDimensions+1 * NOutputDimensions+1)-1);
79 
81  typedef typename Superclass::ParametersType ParametersType;
82 
85 
87  typedef typename Superclass::ScalarType ScalarType;
88 
90  typedef Vector<TScalarType,
91  itkGetStaticConstMacro(InputSpaceDimension)> InputVectorType;
92  typedef Vector<TScalarType,
93  itkGetStaticConstMacro(OutputSpaceDimension)> OutputVectorType;
94 
96  typedef CovariantVector<TScalarType,
97  itkGetStaticConstMacro(InputSpaceDimension)>
99  typedef CovariantVector<TScalarType,
100  itkGetStaticConstMacro(OutputSpaceDimension)>
102 
104  typedef vnl_vector_fixed<TScalarType,
105  itkGetStaticConstMacro(InputSpaceDimension)>
107  typedef vnl_vector_fixed<TScalarType,
108  itkGetStaticConstMacro(OutputSpaceDimension)>
110 
112  typedef Point<TScalarType,
113  itkGetStaticConstMacro(InputSpaceDimension)>
115  typedef Point<TScalarType,
116  itkGetStaticConstMacro(OutputSpaceDimension)>
118 
120  typedef Matrix<TScalarType, itkGetStaticConstMacro(OutputSpaceDimension),
121  itkGetStaticConstMacro(InputSpaceDimension)>
123 
125  typedef Matrix<TScalarType, itkGetStaticConstMacro(InputSpaceDimension),
126  itkGetStaticConstMacro(OutputSpaceDimension)>
128 
130  typedef Matrix<TScalarType, NOutputDimensions+1, NInputDimensions+1> FullAffineMatrixType;
131  typedef AffineTransform<TScalarType, NInputDimensions> FullAffineTransformType;
132  typedef typename FullAffineTransformType::Pointer FullAffineTransformPointer;
133 
135 
136  typedef Array<double> TranslationType;
137 
138  typedef Array<double> RotationType;
139 
140  typedef Array<double> ScaleType;
141 
142  typedef Array<double> SkewType;
143 
144  typedef Array<double> RelativeParameterWeightingType;
145 
149  void SetIdentity( void );
150 
154  const MatrixType & GetMatrix() const { return m_Matrix; }
155 
159  const OutputVectorType & GetOffset(void) const { return m_Offset; }
160 
164  FullAffineTransformType* GetFullAffineTransform()
165  {
166  ParametersType parameters;
167  parameters.SetSize((NInputDimensions+1)*(NInputDimensions+1));
168 
169  FullAffineMatrixType matrix = GetFullAffineMatrix();
170  unsigned int counter = 0;
171 
172  for (unsigned int i = 0; i < NOutputDimensions+1; i++)
173  {
174  for (unsigned int j = 0; j < NInputDimensions+1; j++)
175  {
176  parameters.SetElement(counter, matrix(i,j));
177  counter++;
178  //std::cout << "Matt: matrix[" << i << "," << j << "]" << "=" << matrix(i,j) << ", parameter=" << parameters.GetElement(counter) << std::endl;
179  }
180  }
181 
182  m_AffineMatrixTransform->SetParameters(parameters);
183  return m_AffineMatrixTransform.GetPointer();
184  }
185 
189  FullAffineMatrixType GetFullAffineMatrix() const
190  {
191  FullAffineMatrixType fullAffineMatrix;
192 
193  fullAffineMatrix.SetIdentity();
194  for (unsigned int i = 0; i < NOutputDimensions; i++)
195  {
196  for (unsigned int j = 0; j < NInputDimensions; j++)
197  {
198  fullAffineMatrix(i,j) = this->m_Matrix(i,j);
199  }
200  }
201  for (unsigned int i = 0; i < NOutputDimensions; i++)
202  {
203  fullAffineMatrix(i,NInputDimensions) = this->m_Offset[i];
204  }
205  return fullAffineMatrix;
206  }
207 
211  void SetFullAffineMatrix(const FullAffineMatrixType& fullAffineMatrix)
212  {
213  this->m_Matrix.SetIdentity();
214  for (unsigned int i = 0; i < NOutputDimensions; i++)
215  {
216  for (unsigned int j = 0; j < NInputDimensions; j++)
217  {
218  this->m_Matrix(i,j) = fullAffineMatrix(i,j);
219  }
220  }
221  for (unsigned int i = 0; i < NOutputDimensions; i++)
222  {
223  this->m_Offset[i] = fullAffineMatrix(i,NInputDimensions);
224  }
225  this->m_MatrixMTime.Modified();
226  }
227 
232  {
233  FullAffineMatrixType fullAffineMatrix = GetFullAffineMatrix();
234 
235  FullAffineMatrixType sqaureRoot(MatrixLinearCombinationFunctions<typename FullAffineMatrixType::InternalMatrixType>::ComputeMatrixSquareRoot(fullAffineMatrix.GetVnlMatrix(), 0.001));
236 
237  SetFullAffineMatrix(sqaureRoot);
238  }
239 
243  void SetCenter(const InputPointType & center)
244  { m_Center = center;
245  this->ComputeMatrixAndOffset();
246  this->Modified();
247  return;
248  }
249 
253  const InputPointType & GetCenter() const
254  { return m_Center; }
255 
259  void SetTranslation(const TranslationType & translation)
260  { m_Translation = translation;
261  this->ComputeMatrixAndOffset();
262  this->Modified();
263  return; }
264 
268  const TranslationType & GetTranslation(void) const
269  { return m_Translation; }
270 
274  void SetRotation(const RotationType & rotation)
275  { m_Rotation = rotation;
276  this->ComputeMatrixAndOffset();
277  this->Modified();
278  return; }
279 
283  const RotationType & GetRotation(void) const
284  { return m_Rotation; }
285 
289  void SetScale(const ScaleType & scale)
290  { m_Scale = scale;
291  this->ComputeMatrixAndOffset();
292  this->Modified();
293  return; }
294 
298  const ScaleType & GetScale(void) const
299  { return m_Scale; }
300 
304  void SetSkew(const SkewType & skew)
305  { m_Skew = skew;
306  this->ComputeMatrixAndOffset();
307  this->Modified();
308  return; }
309 
313  const SkewType & GetSkew(void) const
314  { return m_Skew; }
315 
319  void SetTranslationRelativeWeighting(const RelativeParameterWeightingType &weighting)
320  {
321  m_TranslationRelativeWeighting = weighting;
322  }
326  void SetTranslationRelativeWeighting(const double &weighting)
327  {
328  m_TranslationRelativeWeighting.Fill( weighting );
329  }
330 
334  void SetRotationRelativeWeighting(const RelativeParameterWeightingType &weighting)
335  {
336  m_RotationRelativeWeighting = weighting;
337  }
341  void SetRotationRelativeWeighting(const double &weighting)
342  {
343  m_RotationRelativeWeighting.Fill( weighting );
344  }
348  void SetScaleRelativeWeighting(const RelativeParameterWeightingType &weighting)
349  {
350  m_ScaleRelativeWeighting = weighting;
351  }
355  void SetScaleRelativeWeighting(const double &weighting)
356  {
357  m_ScaleRelativeWeighting.Fill( weighting );
358  }
362  void SetSkewRelativeWeighting(const RelativeParameterWeightingType &weighting)
363  {
364  m_SkewRelativeWeighting = weighting;
365  }
369  void SetSkewRelativeWeighting(const double &weighting)
370  {
371  m_SkewRelativeWeighting.Fill( weighting );
372  }
373 
374 
375 
383  void SetParameters( const ParametersType & parameters );
384 
401  const ParametersType& GetParameters(void) const;
402 
409  void SetFixedParameters(const ParametersType& parameters)
410  {
411  if (parameters.GetSize() != 1+NInputDimensions)
412  itkExceptionMacro("SwitchableAffineTransform: number of expected fixed parameters does not match.");
413  SetNumberOfDOF(static_cast<int>(parameters.GetElement(0)));
414  for (unsigned int d = 0; d < NInputDimensions; d++)
415  {
416  this->m_Center[d] = parameters.GetElement(1+d);
417  }
418  }
419 
426  const ParametersType& GetFixedParameters() const
427  {
428  // Store the dof and centre of the transformation.
429  this->m_FixedParameters.SetSize(1+NInputDimensions);
430 
431  this->m_FixedParameters.SetElement(0, this->GetNumberOfDOF());
432  for (unsigned int d = 0; d < NInputDimensions; d++)
433  {
434  this->m_FixedParameters.SetElement(d+1, this->m_Center[d]);
435  }
436  return this->m_FixedParameters;
437  }
438 
442  const RelativeParameterWeightingType& GetRelativeParameterWeightingFactors();
443 
452  OutputPointType TransformPoint(const InputPointType & point) const;
453  OutputVectorType TransformVector(const InputVectorType & vector) const;
454  OutputVnlVectorType TransformVector(const InputVnlVectorType & vector) const;
455  OutputCovariantVectorType TransformCovariantVector(const InputCovariantVectorType &vector) const;
456 
457  itkSetMacro( OptimiseRotation, bool );
458  itkGetConstMacro( OptimiseRotation, bool );
459  itkBooleanMacro( OptimiseRotation );
460 
461  itkSetMacro( OptimiseTranslation, bool );
462  itkGetConstMacro( OptimiseTranslation, bool );
463  itkBooleanMacro( OptimiseTranslation );
464 
465  itkSetMacro( OptimiseScale, bool );
466  itkGetConstMacro( OptimiseScale, bool );
467  itkBooleanMacro( OptimiseScale );
468 
469  itkSetMacro( OptimiseSkew, bool );
470  itkGetConstMacro( OptimiseSkew, bool );
471  itkBooleanMacro( OptimiseSkew );
472 
476  virtual itk::TransformBase::NumberOfParametersType GetNumberOfParameters() const
477  {
478  return this->GetNumberOfDOF();
479  }
480 
484  unsigned int GetNumberOfDOF() const;
485 
489  void SetNumberOfDOF(int number);
490 
494  void SetRigid()
495  {
496  OptimiseRotationOn();
497  OptimiseTranslationOn();
498  OptimiseScaleOff();
499  OptimiseSkewOff();
500  this->Modified();
501  }
502 
507  {
508  OptimiseRotationOn();
509  OptimiseTranslationOn();
510  OptimiseScaleOn();
511  OptimiseSkewOff();
512  this->Modified();
513  }
514 
519  {
520  OptimiseRotationOn();
521  OptimiseTranslationOn();
522  OptimiseScaleOn();
523  OptimiseSkewOn();
524  this->Modified();
525  }
526 
531  {
532  OptimiseRotationOff();
533  OptimiseTranslationOff();
534  OptimiseScaleOn();
535  OptimiseSkewOff();
536  this->Modified();
537  }
538 
543  {
544  OptimiseRotationOn();
545  OptimiseTranslationOff();
546  OptimiseScaleOff();
547  OptimiseSkewOff();
548  this->Modified();
549  }
550 
555  {
556  OptimiseRotationOff();
557  OptimiseTranslationOn();
558  OptimiseScaleOff();
559  OptimiseSkewOff();
560  this->Modified();
561  }
562 
573  virtual const JacobianType GetJacobian(const InputPointType & point ) const = 0;
574 
581  bool GetInverse(Self* inverse) const;
582 
584  virtual void TransformPoint(const InputPointType &input, OutputPointType &output ) const;
585 
586 protected:
587 
588  SwitchableAffineTransform(unsigned int outputDims,
589  unsigned int paramDims);
591 
593  virtual ~SwitchableAffineTransform() = 0;
594 
596  void PrintSelf(std::ostream &s, Indent indent) const;
597 
599  virtual void ComputeMatrixAndOffset(void) {};
600 
603 
605  void SetDefaultRelativeParameterWeightings( void );
606 
610  const InverseMatrixType & GetInverseMatrix( void ) const;
611 
613  { return m_InverseMatrix; };
614 
616  { m_InverseMatrix = matrix; m_InverseMatrixMTime.Modified(); };
617 
618  bool InverseMatrixIsOld(void) const
619  { if(m_MatrixMTime != m_InverseMatrixMTime)
620  { return true; } else { return false; } };
621 
622  MatrixType m_Matrix; // Matrix of the transformation
623  OutputVectorType m_Offset; // Offset of the transformation
624 
625 private:
626 
627  SwitchableAffineTransform(const Self & other); // Purposely not implemented
628  const Self & operator=( const Self & ); // Purposely not implemented
629 
630  InputPointType m_Center;
631  TranslationType m_Translation;
632  RotationType m_Rotation;
633  ScaleType m_Scale;
634  SkewType m_Skew;
635  bool m_OptimiseRotation;
636  bool m_OptimiseTranslation;
637  bool m_OptimiseScale;
638  bool m_OptimiseSkew;
639 
640  RelativeParameterWeightingType m_TranslationRelativeWeighting;
641  RelativeParameterWeightingType m_RotationRelativeWeighting;
642  RelativeParameterWeightingType m_ScaleRelativeWeighting;
643  RelativeParameterWeightingType m_SkewRelativeWeighting;
644  RelativeParameterWeightingType m_AllRelativeWeightings;
645 
646  mutable InverseMatrixType m_InverseMatrix; // Inverse of the matrix
647  mutable bool m_Singular; // Is m_Inverse singular?
648 
649  FullAffineTransformPointer m_AffineMatrixTransform;
650 
652  TimeStamp m_MatrixMTime;
653  mutable TimeStamp m_InverseMatrixMTime;
654 
655 }; // class SwitchableAffineTransform
656 
657 } // namespace itk
658 
659 #ifndef ITK_MANUAL_INSTANTIATION
660 #include "itkSwitchableAffineTransform.txx"
661 #endif
662 
663 #endif /* __itkSwitchableAffineTransform_h */
Superclass::JacobianType JacobianType
Definition: itkSwitchableAffineTransform.h:84
GLuint counter
Definition: glew.h:2637
Array< double > ScaleType
Definition: itkSwitchableAffineTransform.h:140
Matrix< TScalarType, itkGetStaticConstMacro(InputSpaceDimension), itkGetStaticConstMacro(OutputSpaceDimension)> InverseMatrixType
Definition: itkSwitchableAffineTransform.h:127
GLenum GLenum GLenum GLenum GLenum scale
Definition: glew.h:12017
vnl_vector_fixed< TScalarType, itkGetStaticConstMacro(OutputSpaceDimension)> OutputVnlVectorType
Definition: itkSwitchableAffineTransform.h:109
void SetSkewRelativeWeighting(const RelativeParameterWeightingType &weighting)
Definition: itkSwitchableAffineTransform.h:362
virtual itk::TransformBase::NumberOfParametersType GetNumberOfParameters() const
Definition: itkSwitchableAffineTransform.h:476
const TranslationType & GetTranslation(void) const
Definition: itkSwitchableAffineTransform.h:268
void SetRigidPlusScale()
Definition: itkSwitchableAffineTransform.h:506
void SetCenter(const InputPointType &center)
Definition: itkSwitchableAffineTransform.h:243
GLenum GLenum GLenum input
Definition: glew.h:12016
UCLBaseTransform< TScalarType, NInputDimensions, NOutputDimensions > Superclass
Definition: itkSwitchableAffineTransform.h:68
void SetVarInverseMatrix(const InverseMatrixType &matrix) const
Definition: itkSwitchableAffineTransform.h:615
FullAffineTransformType * GetFullAffineTransform()
Definition: itkSwitchableAffineTransform.h:164
void SetScaleRelativeWeighting(const double &weighting)
Definition: itkSwitchableAffineTransform.h:355
SwitchableAffineTransform< TScalarType, NInputDimensions, NInputDimensions > Self
Definition: itkSwitchableAffineTransform.h:65
Matrix< TScalarType, itkGetStaticConstMacro(OutputSpaceDimension), itkGetStaticConstMacro(InputSpaceDimension)> MatrixType
Definition: itkSwitchableAffineTransform.h:122
InputPointType CenterType
Definition: itkSwitchableAffineTransform.h:134
void SetRotationRelativeWeighting(const RelativeParameterWeightingType &weighting)
Definition: itkSwitchableAffineTransform.h:334
Definition: niftkITKAffineResampleImage.cxx:74
Superclass::ScalarType ScalarType
Definition: itkSwitchableAffineTransform.h:87
const OutputVectorType & GetOffset(void) const
Definition: itkSwitchableAffineTransform.h:159
virtual void ComputeParametersFromMatrixAndOffset(void)
Definition: itkSwitchableAffineTransform.h:602
itk::Point< double, 2 > InputPointType
Definition: EulerAffine2DJacobianTest.cxx:34
Matrix< TScalarType, NOutputDimensions+1, NInputDimensions+1 > FullAffineMatrixType
Definition: itkSwitchableAffineTransform.h:130
vnl_matrix< double > MatrixType
Definition: itkSuperEllipseFit.h:32
SmartPointer< Self > Pointer
Definition: itkSwitchableAffineTransform.h:69
Array< double > SkewType
Definition: itkSwitchableAffineTransform.h:142
void SetTranslationRelativeWeighting(const double &weighting)
Definition: itkSwitchableAffineTransform.h:326
Vector< TScalarType, itkGetStaticConstMacro(InputSpaceDimension)> InputVectorType
Definition: itkSwitchableAffineTransform.h:91
OutputVectorType m_Offset
Definition: itkSwitchableAffineTransform.h:623
void SetJustRotation()
Definition: itkSwitchableAffineTransform.h:542
void SetFixedParameters(const ParametersType &parameters)
Definition: itkSwitchableAffineTransform.h:409
const ScaleType & GetScale(void) const
Definition: itkSwitchableAffineTransform.h:298
Superclass::ParametersType ParametersType
Definition: itkSwitchableAffineTransform.h:81
Point< TScalarType, itkGetStaticConstMacro(OutputSpaceDimension)> OutputPointType
Definition: itkSwitchableAffineTransform.h:117
void SetRotationRelativeWeighting(const double &weighting)
Definition: itkSwitchableAffineTransform.h:341
FullAffineTransformType::Pointer FullAffineTransformPointer
Definition: itkSwitchableAffineTransform.h:132
Vector< TScalarType, itkGetStaticConstMacro(OutputSpaceDimension)> OutputVectorType
Definition: itkSwitchableAffineTransform.h:93
void SetTranslation(const TranslationType &translation)
Definition: itkSwitchableAffineTransform.h:259
const InputPointType & GetCenter() const
Definition: itkSwitchableAffineTransform.h:253
void SetFullAffineMatrix(const FullAffineMatrixType &fullAffineMatrix)
Definition: itkSwitchableAffineTransform.h:211
void SetScaleRelativeWeighting(const RelativeParameterWeightingType &weighting)
Definition: itkSwitchableAffineTransform.h:348
SmartPointer< const Self > ConstPointer
Definition: itkSwitchableAffineTransform.h:70
bool InverseMatrixIsOld(void) const
Definition: itkSwitchableAffineTransform.h:618
void SetTranslationRelativeWeighting(const RelativeParameterWeightingType &weighting)
Definition: itkSwitchableAffineTransform.h:319
void SetJustTranslation()
Definition: itkSwitchableAffineTransform.h:554
virtual void ComputeMatrixAndOffset(void)
Definition: itkSwitchableAffineTransform.h:599
GLuint GLenum matrix
Definition: glew.h:12775
Point< TScalarType, itkGetStaticConstMacro(InputSpaceDimension)> InputPointType
Definition: itkSwitchableAffineTransform.h:114
void SetRigid()
Definition: itkSwitchableAffineTransform.h:494
Array< double > RotationType
Definition: itkSwitchableAffineTransform.h:138
const ParametersType & GetFixedParameters() const
Definition: itkSwitchableAffineTransform.h:426
void SetRotation(const RotationType &rotation)
Definition: itkSwitchableAffineTransform.h:274
Superclass::JacobianType JacobianType
Definition: itkUCLBaseTransform.h:43
void SetScale(const ScaleType &scale)
Definition: itkSwitchableAffineTransform.h:289
void SetSkewRelativeWeighting(const double &weighting)
Definition: itkSwitchableAffineTransform.h:369
CovariantVector< TScalarType, itkGetStaticConstMacro(InputSpaceDimension)> InputCovariantVectorType
Definition: itkSwitchableAffineTransform.h:98
Array< double > TranslationType
Definition: itkSwitchableAffineTransform.h:136
void HalfTransformationMatrix()
Definition: itkSwitchableAffineTransform.h:231
Definition: itkMatrixLinearCombinationFunctions.h:24
Array< double > RelativeParameterWeightingType
Definition: itkSwitchableAffineTransform.h:144
const SkewType & GetSkew(void) const
Definition: itkSwitchableAffineTransform.h:313
void SetSkew(const SkewType &skew)
Definition: itkSwitchableAffineTransform.h:304
void SetJustScale()
Definition: itkSwitchableAffineTransform.h:530
const RotationType & GetRotation(void) const
Definition: itkSwitchableAffineTransform.h:283
Matrix transformations, with switchable Degrees Of Freedom.
Definition: itkSwitchableAffineTransform.h:58
Our base transform class. Cant think of a better name.
Definition: itkUCLBaseTransform.h:33
FullAffineMatrixType GetFullAffineMatrix() const
Definition: itkSwitchableAffineTransform.h:189
GLdouble s
Definition: glew.h:1374
itk::Point< double, 2 > OutputPointType
Definition: EulerAffine2DJacobianTest.cxx:35
const MatrixType & GetMatrix() const
Definition: itkSwitchableAffineTransform.h:154
CovariantVector< TScalarType, itkGetStaticConstMacro(OutputSpaceDimension)> OutputCovariantVectorType
Definition: itkSwitchableAffineTransform.h:101
vnl_vector_fixed< TScalarType, itkGetStaticConstMacro(InputSpaceDimension)> InputVnlVectorType
Definition: itkSwitchableAffineTransform.h:106
const InverseMatrixType & GetVarInverseMatrix(void) const
Definition: itkSwitchableAffineTransform.h:612
void SetFullAffine()
Definition: itkSwitchableAffineTransform.h:518
AffineTransform< TScalarType, NInputDimensions > FullAffineTransformType
Definition: itkSwitchableAffineTransform.h:131