Orfeo Toolbox  3.16
itkRigid2DTransform.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkRigid2DTransform.txx,v $
5  Language: C++
6  Date: $Date: 2010-03-30 15:20:02 $
7  Version: $Revision: 1.30 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
17 #ifndef __itkRigid2DTransform_txx
18 #define __itkRigid2DTransform_txx
19 
20 #include "itkRigid2DTransform.h"
21 #include "vnl/algo/vnl_svd.h"
22 
23 
24 namespace itk
25 {
26 
27 // Constructor with default arguments
28 template<class TScalarType>
31  Superclass(OutputSpaceDimension, ParametersDimension)
32 {
33  m_Angle = NumericTraits< TScalarType >::Zero;
34 }
35 
36 
37 // Constructor with arguments
38 template<class TScalarType>
40 Rigid2DTransform( unsigned int spaceDimension,
41  unsigned int parametersDimension):
42  Superclass(spaceDimension,parametersDimension)
43 {
44  m_Angle = NumericTraits< TScalarType >::Zero;
45 }
46 
47 
48 // Destructor
49 template<class TScalarType>
52 {
53 }
54 
55 
56 // Print self
57 template<class TScalarType>
58 void
60 PrintSelf(std::ostream &os, Indent indent) const
61 {
62  Superclass::PrintSelf(os,indent);
63  os << indent << "Angle = " << m_Angle << std::endl;
64 }
65 
66 
67 // Set the rotation matrix
68 template<class TScalarType>
69 void
71 SetMatrix(const MatrixType & matrix )
72 {
73  itkDebugMacro("setting m_Matrix to " << matrix );
74  // The matrix must be orthogonal otherwise it is not
75  // representing a valid rotaion in 2D space
76  typename MatrixType::InternalMatrixType test =
77  matrix.GetVnlMatrix() * matrix.GetTranspose();
78 
79  const double tolerance = 1e-10;
80  if( !test.is_identity( tolerance ) )
81  {
82  itk::ExceptionObject ex(__FILE__,__LINE__,"Attempt to set a Non-Orthogonal matrix",ITK_LOCATION);
83  throw ex;
84  }
85 
86  this->SetVarMatrix( matrix );
87  this->ComputeOffset();
88  this->ComputeMatrixParameters();
89  this->Modified();
90 
91 }
92 
93 
95 template <class TScalarType>
96 void
99 {
100  // Extract the orthogonal part of the matrix
101  //
102  vnl_matrix<TScalarType> p(2, 2);
103  p = this->GetMatrix().GetVnlMatrix();
104  vnl_svd<TScalarType> svd(p);
105  vnl_matrix<TScalarType> r(2, 2);
106  r = svd.U() * svd.V().transpose();
107 
108  m_Angle = vcl_acos(r[0][0]);
109 
110  if(r[1][0]<0.0)
111  {
112  m_Angle = -m_Angle;
113  }
114 
115  if(r[1][0]-vcl_sin(m_Angle) > 0.000001)
116  {
117  itkWarningMacro("Bad Rotation Matrix " << this->GetMatrix() );
118  }
119 }
120 
121 
122 // Compose with a translation
123 template<class TScalarType>
124 void
126 Translate(const OffsetType &offset, bool)
127 {
128  OutputVectorType newOffset = this->GetOffset();
129  newOffset += offset;
130  this->SetOffset(newOffset);
131  this->ComputeTranslation();
132 }
133 
134 
135 // Create and return an inverse transformation
136 template<class TScalarType>
137 void
139 CloneInverseTo( Pointer & result ) const
140 {
141  result = New();
142  this->GetInverse(result.GetPointer());
143 }
144 
145 // return an inverse transformation
146 template<class TScalarType>
147 bool
149 GetInverse( Self* inverse) const
150 {
151  if(!inverse)
152  {
153  return false;
154  }
155 
156  inverse->SetCenter( this->GetCenter() ); // inverse have the same center
157  inverse->SetAngle( -this->GetAngle() );
158  inverse->SetTranslation( -( this->GetInverseMatrix() * this->GetTranslation() ) );
159 
160  return true;
161 }
162 
163 // Return an inverse of this transform
164 template<class TScalarType>
168 {
169  Pointer inv = New();
170  return GetInverse(inv) ? inv.GetPointer() : NULL;
171 }
172 
173 // Create and return a clone of the transformation
174 template<class TScalarType>
175 void
177 CloneTo( Pointer & result ) const
178 {
179  result = New();
180  result->SetCenter( this->GetCenter() );
181  result->SetAngle( this->GetAngle() );
182  result->SetTranslation( this->GetTranslation() );
183 }
184 
185 
186 // Reset the transform to an identity transform
187 template<class TScalarType >
188 void
190 SetIdentity( void )
191 {
192  this->Superclass::SetIdentity();
193  m_Angle = NumericTraits< TScalarType >::Zero;
194 }
195 
196 // Set the angle of rotation
197 template <class TScalarType>
198 void
200 ::SetAngle(TScalarType angle)
201 {
202  m_Angle = angle;
203  this->ComputeMatrix();
204  this->ComputeOffset();
205  this->Modified();
206 }
207 
208 
209 // Set the angle of rotation
210 template <class TScalarType>
211 void
213 ::SetAngleInDegrees(TScalarType angle)
214 {
215  const TScalarType angleInRadians = angle * vcl_atan(1.0) / 45.0;
216  this->SetAngle( angleInRadians );
217 }
218 
219 // Compute the matrix from the angle
220 template <class TScalarType>
221 void
224 {
225  const MatrixValueType ca = vcl_cos(m_Angle);
226  const MatrixValueType sa = vcl_sin(m_Angle);
227 
228  MatrixType rotationMatrix;
229  rotationMatrix[0][0]= ca; rotationMatrix[0][1]=-sa;
230  rotationMatrix[1][0]= sa; rotationMatrix[1][1]= ca;
231 
232  this->SetVarMatrix( rotationMatrix );
233 
234 }
235 
236 // Set Parameters
237 template <class TScalarType>
238 void
240 SetParameters( const ParametersType & parameters )
241 {
242  itkDebugMacro( << "Setting parameters " << parameters );
243 
244  // Set angle
245  const TScalarType angle = parameters[0];
246  this->SetVarAngle( angle );
247 
248  // Set translation
249  OutputVectorType translation;
250 
251  for(unsigned int i=0; i < OutputSpaceDimension; i++)
252  {
253  translation[i] = parameters[i+1];
254  }
255  this->SetVarTranslation( translation );
256 
257  // Update matrix and offset
258  this->ComputeMatrix();
259  this->ComputeOffset();
260 
261  // Modified is always called since we just have a pointer to the
262  // parameters and cannot know if the parameters have changed.
263  this->Modified();
264 
265  itkDebugMacro(<<"After setting parameters ");
266 }
267 
268 // Get Parameters
269 template <class TScalarType>
272 GetParameters( void ) const
273 {
274  itkDebugMacro( << "Getting parameters ");
275 
276  // Get the angle
277  this->m_Parameters[0] = this->GetAngle();
278 
279  // Get the translation
280  for(unsigned int i=0; i < OutputSpaceDimension; i++)
281  {
282  this->m_Parameters[i+1] = this->GetTranslation()[i];
283  }
284 
285  itkDebugMacro(<<"After getting parameters " << this->m_Parameters );
286 
287  return this->m_Parameters;
288 }
289 
290 // Compute transformation Jacobian
291 template<class TScalarType>
294 GetJacobian( const InputPointType & p ) const
295 {
296 
297  const double ca = vcl_cos(this->GetAngle() );
298  const double sa = vcl_sin(this->GetAngle() );
299 
300  this->m_Jacobian.Fill(0.0);
301 
302  const double cx = this->GetCenter()[0];
303  const double cy = this->GetCenter()[1];
304 
305  // derivatives with respect to the angle
306  this->m_Jacobian[0][0] = -sa * ( p[0] - cx ) - ca * ( p[1] - cy );
307  this->m_Jacobian[1][0] = ca * ( p[0] - cx ) - sa * ( p[1] - cy );
308 
309  // compute derivatives for the translation part
310  unsigned int blockOffset = 1;
311  for(unsigned int dim=0; dim < OutputSpaceDimension; dim++ )
312  {
313  this->m_Jacobian[ dim ][ blockOffset + dim ] = 1.0;
314  }
315 
316  return this->m_Jacobian;
317 
318 }
319 
320 
321 } // namespace
322 
323 #endif

Generated at Sun Feb 3 2013 00:03:30 for Orfeo Toolbox with doxygen 1.8.1.1