Orfeo Toolbox  3.16
itkSimilarity2DTransform.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkSimilarity2DTransform.txx,v $
5  Language: C++
6  Date: $Date: 2010-03-30 15:20:02 $
7  Version: $Revision: 1.27 $
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 __itkSimilarity2DTransform_txx
18 #define __itkSimilarity2DTransform_txx
19 
21 #include "vnl/vnl_math.h"
22 
23 namespace itk
24 {
25 
26 // Constructor with default arguments
27 template <class TScalarType>
29 ::Similarity2DTransform():Superclass(OutputSpaceDimension, ParametersDimension)
30 {
31  m_Scale = 1.0f;
32 }
33 
34 // Constructor with arguments
35 template<class TScalarType>
37 Similarity2DTransform( unsigned int spaceDimension,
38  unsigned int parametersDimension):
39  Superclass(spaceDimension,parametersDimension)
40 {
41  m_Scale = 1.0f;
42 
43 }
44 
45 // Set Parameters
46 template <class TScalarType>
47 void
49 ::SetParameters( const ParametersType & parameters )
50 {
51  itkDebugMacro( << "Setting parameters " << parameters );
52 
53  // Set scale
54  const TScalarType scale = parameters[0];
55  this->SetVarScale( scale );
56 
57  // Set angle
58  const TScalarType angle = parameters[1];
59  this->SetVarAngle( angle );
60 
61  // Set translation
62  OffsetType translation;
63  for(unsigned int i=0; i < SpaceDimension; i++)
64  {
65  translation[i] = parameters[i+2];
66  }
67  this->SetVarTranslation( translation );
68 
69  this->ComputeMatrix();
70  this->ComputeOffset();
71 
72  // Modified is always called since we just have a pointer to the
73  // parameters and cannot know if the parameters have changed.
74  this->Modified();
75 
76  itkDebugMacro(<<"After setting parameters ");
77 }
78 
79 
80 // Get Parameters
81 template <class TScalarType>
84 ::GetParameters( void ) const
85 {
86  itkDebugMacro( << "Getting parameters ");
87 
88  this->m_Parameters[0] = this->GetScale();
89  this->m_Parameters[1] = this->GetAngle();
90 
91  // Get the translation
92  OffsetType translation = this->GetTranslation();
93  for(unsigned int i=0; i < SpaceDimension; i++)
94  {
95  this->m_Parameters[i+2] = translation[i];
96  }
97 
98  itkDebugMacro(<<"After getting parameters " << this->m_Parameters );
99 
100  return this->m_Parameters;
101 }
102 
103 // Set Scale Part
104 template <class TScalarType>
105 void
108 {
109  m_Scale = scale;
110  this->ComputeMatrix();
111  this->ComputeOffset();
112 }
113 
114 
115 // Compute the matrix
116 template <class TScalarType>
117 void
120 {
121  const double angle = this->GetAngle();
122 
123  const double cc = vcl_cos(angle );
124  const double ss = vcl_sin(angle );
125 
126  const MatrixValueType ca = cc * m_Scale;
127  const MatrixValueType sa = ss * m_Scale;
128 
129  MatrixType matrix;
130  matrix[0][0]= ca; matrix[0][1]=-sa;
131  matrix[1][0]= sa; matrix[1][1]= ca;
132 
133  this->SetVarMatrix( matrix );
134 
135 }
136 
138 template <class TScalarType>
139 void
142 {
143  m_Scale = vcl_sqrt(vnl_math_sqr( this->GetMatrix()[0][0] ) +
144  vnl_math_sqr( this->GetMatrix()[0][1] ) );
145 
146  this->SetVarAngle( vcl_acos(this->GetMatrix()[0][0] / m_Scale ) );
147 
148  if(this->GetMatrix()[1][0]<0.0)
149  {
150  this->SetVarAngle( -this->GetAngle() );
151  }
152 
153  if( ( this->GetMatrix()[1][0] / m_Scale ) - vcl_sin(this->GetAngle()) > 0.000001)
154  {
155  std::cout << "Bad Rotation Matrix" << std::endl;
156  }
157 }
158 
159 
160 // Compute the transformation Jacobian
161 template<class TScalarType>
164 GetJacobian( const InputPointType & p ) const
165 {
166  const double angle = this->GetAngle();
167  const double ca = vcl_cos(angle );
168  const double sa = vcl_sin(angle );
169 
170  this->m_Jacobian.Fill(0.0);
171 
172  const InputPointType center = this->GetCenter();
173  const double cx = center[0];
174  const double cy = center[1];
175 
176  const OutputVectorType translation = this->GetTranslation();
177 
178  // derivatives with respect to the scale
179  this->m_Jacobian[0][0] = ca * ( p[0] - cx ) - sa * ( p[1] - cy );
180  this->m_Jacobian[1][0] = sa * ( p[0] - cx ) + ca * ( p[1] - cy );
181 
182  // derivatives with respect to the angle
183  this->m_Jacobian[0][1] = ( -sa * ( p[0] - cx ) - ca * ( p[1] - cy ) ) * m_Scale;
184  this->m_Jacobian[1][1] = ( ca * ( p[0] - cx ) - sa * ( p[1] - cy ) ) * m_Scale;
185 
186  // compute derivatives with respect to the translation part
187  // first with respect to tx
188  this->m_Jacobian[0][2] = 1.0;
189  this->m_Jacobian[1][2] = 0.0;
190  // first with respect to ty
191  this->m_Jacobian[0][3] = 0.0;
192  this->m_Jacobian[1][3] = 1.0;
193 
194  return this->m_Jacobian;
195 
196 }
197 
198 
199 // Set Identity
200 template <class TScalarType>
201 void
204 {
205  this->Superclass::SetIdentity();
206  m_Scale = static_cast< TScalarType >( 1.0f );
207 }
208 
209 // Print self
210 template<class TScalarType>
211 void
213 PrintSelf(std::ostream &os, Indent indent) const
214 {
215  Superclass::PrintSelf(os,indent);
216  os << indent << "Scale =" << m_Scale << std::endl;
217 }
218 
219 // Create and return an inverse transformation
220 template<class TScalarType>
221 void
223 CloneInverseTo( Pointer & result ) const
224 {
225  result = New();
226  this->GetInverse(result.GetPointer());
227 }
228 
229 // return an inverse transformation
230 template<class TScalarType>
231 bool
233 GetInverse( Self* inverse) const
234 {
235  if(!inverse)
236  {
237  return false;
238  }
239 
240  inverse->SetCenter( this->GetCenter() ); // inverse have the same center
241  inverse->SetScale( NumericTraits<double>::One / this->GetScale() );
242  inverse->SetAngle( -this->GetAngle() );
243  inverse->SetTranslation( -( this->GetInverseMatrix() * this->GetTranslation() ) );
244 
245  return true;
246 }
247 
248 // Return an inverse of this transform
249 template<class TScalarType>
253 {
254  Pointer inv = New();
255  if( this->GetInverse(inv) )
256  {
257  return inv.GetPointer();
258  }
259  return NULL;
260 }
261 
262 // Create and return a clone of the transformation
263 template<class TScalarType>
264 void
266 CloneTo( Pointer & result ) const
267 {
268  result = New();
269  result->SetCenter( this->GetCenter() );
270  result->SetScale( this->GetScale() );
271  result->SetAngle( this->GetAngle() );
272  result->SetTranslation( this->GetTranslation() );
273 }
274 
275 // Set the similarity matrix
276 template<class TScalarType>
277 void
279 SetMatrix(const MatrixType & matrix )
280 {
281  itkDebugMacro("setting m_Matrix to " << matrix );
282 
283  typename MatrixType::InternalMatrixType test =
284  matrix.GetVnlMatrix() * matrix.GetTranspose();
285 
286  test /= test[0][0]; // factor out the scale
287 
288  const double tolerance = 1e-10;
289  if( !test.is_identity( tolerance ) )
290  {
291  itk::ExceptionObject ex(__FILE__,__LINE__,"Attempt to set a Non-Orthogonal matrix",ITK_LOCATION);
292  throw ex;
293  }
294 
295  this->SetVarMatrix( matrix );
296  this->ComputeOffset();
297  this->ComputeMatrixParameters();
298  this->Modified();
299 
300 }
301 
302 } // namespace
303 
304 #endif

Generated at Sun Feb 3 2013 00:07:05 for Orfeo Toolbox with doxygen 1.8.1.1