AffineTransformation.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2008-2015 Imperial College London
5  * Copyright 2008-2013 Daniel Rueckert, Julia Schnabel
6  * Copyright 2013-2015 Andreas Schuh
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef MIRTK_AffineTransformation_H
22 #define MIRTK_AffineTransformation_H
23 
24 #include "mirtk/SimilarityTransformation.h"
25 
26 #include "mirtk/Matrix.h"
27 
28 #include <cstdlib>
29 #include <iostream>
30 
31 
32 namespace mirtk {
33 
34 
35 /**
36  * Class for affine transformations.
37  *
38  * This class defines and implements affine transformations. In addition to
39  * the rigid body transformation parameters, affine transformations are
40  * parameterized by three scaling and and six skewing parameters. The three
41  * scaling parameters define the scaling along the axis of the coordinate
42  * transformations. The six skewing parameters define the skewing angles in
43  * different planes. Note that the six skewing parameters are not independent.
44  */
46 {
47  mirtkTransformationMacro(AffineTransformation);
48 
49  // Wrapper class used for inverse consistent affine registration
50  // which depends on the same parameters as the affine transformation
51  friend class InverseAffineTransformation;
52 
53  // ---------------------------------------------------------------------------
54  // Data members
55 
56 protected:
57 
58  /// Tangent of shear angle sxy
59  double _tansxy;
60 
61  /// Tangent of shear angle sxz
62  double _tansxz;
63 
64  /// Tangent of shear angle syz
65  double _tansyz;
66 
67  /// Update cached tangents of shearing angles
68  void UpdateShearingTangent();
69 
70  // ---------------------------------------------------------------------------
71  // Construction/Destruction
72 
73  /// Default constructor with given number of parameters
75 
76  /// Copy constructor with given number of parameters
78 
79  /// Copy constructor with given number of parameters
81 
82  /// Copy constructor with given number of parameters
84 
85 public:
86 
87  /// Default constructor
89 
90  /// Copy constructor
92 
93  /// Copy constructor
95 
96  /// Copy constructor
98 
99  /// Destructor
100  virtual ~AffineTransformation();
101 
102  // ---------------------------------------------------------------------------
103  // Approximation
104 
105  /// Approximate displacements: This function takes a set of points and a set
106  /// of displacements and finds !new! parameters such that the resulting
107  /// transformation approximates the displacements as good as possible.
108  virtual void ApproximateDOFs(const double *, const double *, const double *, const double *,
109  const double *, const double *, const double *, int);
110 
111  // ---------------------------------------------------------------------------
112  // Parameters (non-DoFs)
113 
115 
116  /// Set named (non-DoF) parameter from value as string
117  virtual bool Set(const char *, const char *);
118 
119  /// Get (non-DoF) parameters as key/value as string map
120  virtual ParameterList Parameter() const;
121 
122  // ---------------------------------------------------------------------------
123  // Transformation parameters
124 
125  /// Construct transformation matrix based on parameters
126  static Matrix DOFs2Matrix(const double *);
127 
128  /// Extract parameters from transformation matrix
129  static void Matrix2DOFs(const Matrix &, double *);
130 
131  /// Update transformation matrix after change of parameter
132  virtual void UpdateMatrix();
133 
134  /// Update transformation parameters after change of matrix
135  virtual void UpdateDOFs();
136 
137  /// Copy active transformation parameters (DoFs) from given
138  /// transformation if possible and return \c false, otherwise
139  virtual bool CopyFrom(const Transformation *);
140 
141  /// Puts global scaling factor
142  void PutScale(double);
143 
144  /// Not supported for affine transformation!
145  double GetScale() const;
146 
147  /// Puts scaling factor along the x-axis
148  void PutScaleX(double);
149 
150  /// Gets scaling factor along the x-axis
151  double GetScaleX() const;
152 
153  /// Puts scaling factor along the y-axis
154  void PutScaleY(double);
155 
156  /// Gets scaling factor along the y-axis
157  double GetScaleY() const;
158 
159  /// Puts scaling factor along the z-axis
160  void PutScaleZ(double);
161 
162  /// Gets scaling factor along the z-axis
163  double GetScaleZ() const;
164 
165  /// Puts y-dependent skewing angle in the x direction (in degrees)
166  void PutShearXY(double);
167 
168  /// Gets y-dependent skewing angle in the x direction (in degrees)
169  double GetShearXY() const;
170 
171  /// Puts z-dependent skewing angle in the y direction (in degrees)
172  void PutShearYZ(double);
173 
174  /// Gets z-dependent skewing angle in the y direction (in degrees)
175  double GetShearYZ() const;
176 
177  /// Puts z-dependent skewing angle in the x direction (in degrees)
178  void PutShearXZ(double);
179 
180  /// Gets z-dependent skewing angle in the x direction (in degrees)
181  double GetShearXZ() const;
182 
183  /// Set status of translation parameters to active/passive
184  void AllowTranslations(bool);
185 
186  /// Whether all translation parameters are active
187  bool AllowTranslations() const;
188 
189  /// Set status of rotation parameters to active/passive
190  void AllowRotations(bool);
191 
192  /// Whether all rotation parameters are active
193  bool AllowRotations() const;
194 
195  /// Set status of scaling parameters to active/passive
196  void AllowScaling(bool);
197 
198  /// Whether all scaling parameters are active
199  bool AllowScaling() const;
200 
201  /// Set status of shearing parameters to active/passive
202  void AllowShearing(bool);
203 
204  /// Whether all shearing parameters are active
205  bool AllowShearing() const;
206 
207  // ---------------------------------------------------------------------------
208  // Derivatives
210 
211  /// Calculates the Jacobian of the transformation w.r.t the parameters
212  virtual void JacobianDOFs(double [3], int, double, double, double, double = 0, double = -1) const;
213 
214  /// Calculates the derivative of the Jacobian of the transformation (w.r.t. world coordinates) w.r.t. a transformation parameter
215  virtual void DeriveJacobianWrtDOF(Matrix &, int, double, double, double, double = 0, double = -1) const;
216 
217  // ---------------------------------------------------------------------------
218  // I/O
219 
220  // Do not hide methods of base class
223 
224  /// Prints the parameters of the transformation
225  virtual void Print(ostream &, Indent = 0) const;
226 
227  /// Whether this transformation can read a file of specified type (i.e. format)
228  virtual bool CanRead(TransformationType) const;
229 
230  /// Writes a transformation to a file stream
231  virtual Cofstream &Write(Cofstream &) const;
232 
233 protected:
234 
235  /// Reads a transformation from a file stream
237 
238 };
239 
240 ////////////////////////////////////////////////////////////////////////////////
241 // Inline definitions
242 ////////////////////////////////////////////////////////////////////////////////
243 
244 // =============================================================================
245 // Transformation parameters
246 // =============================================================================
247 
248 // -----------------------------------------------------------------------------
249 inline void AffineTransformation::PutScaleX(double sx)
250 {
251  Put(SX, sx);
252 }
253 
254 // -----------------------------------------------------------------------------
255 inline double AffineTransformation::GetScaleX() const
256 {
257  return Get(SX);
258 }
259 
260 // -----------------------------------------------------------------------------
261 inline void AffineTransformation::PutScaleY(double sy)
262 {
263  Put(SY, sy);
264 }
265 
266 // -----------------------------------------------------------------------------
267 inline double AffineTransformation::GetScaleY() const
268 {
269  return Get(SY);
270 }
271 
272 // -----------------------------------------------------------------------------
273 inline void AffineTransformation::PutScaleZ(double sz)
274 {
275  Put(SZ, sz);
276 }
277 
278 // -----------------------------------------------------------------------------
279 inline double AffineTransformation::GetScaleZ() const
280 {
281  return Get(SZ);
282 }
283 
284 // -----------------------------------------------------------------------------
285 inline void AffineTransformation::PutScale(double s)
286 {
287  _Param[SX] = _Param[SY] = _Param[SZ] = s;
288  this->Update(MATRIX);
289 }
290 
291 // -----------------------------------------------------------------------------
292 inline double AffineTransformation::GetScale() const
293 {
294  cerr << this->NameOfClass() << "::GetScale: Use GetScaleX, GetScaleY, and/or GetScaleZ!" << endl;
295  exit(1);
296 }
297 
298 // -----------------------------------------------------------------------------
299 inline void AffineTransformation::PutShearXY(double sxy)
300 {
301  Put(SXY, sxy);
302 }
303 
304 // -----------------------------------------------------------------------------
305 inline double AffineTransformation::GetShearXY() const
306 {
307  return Get(SXZ);
308 }
309 
310 // -----------------------------------------------------------------------------
311 inline void AffineTransformation::PutShearYZ(double syz)
312 {
313  Put(SYZ, syz);
314 }
315 
316 // -----------------------------------------------------------------------------
317 inline double AffineTransformation::GetShearYZ() const
318 {
319  return Get(SYZ);
320 }
321 
322 // -----------------------------------------------------------------------------
323 inline void AffineTransformation::PutShearXZ(double sxz)
324 {
325  Put(SXZ, sxz);
326 }
327 
328 // -----------------------------------------------------------------------------
329 inline double AffineTransformation::GetShearXZ() const
330 {
331  return Get(SXZ);
332 }
333 
334 // -----------------------------------------------------------------------------
336 {
337  _Status[TX] = _Status[TY] = _Status[TZ] = (b ? Active : Passive);
338 }
339 
340 // -----------------------------------------------------------------------------
342 {
343  return _Status[TX] == Active && _Status[TY] == Active && _Status[TZ] == Active;
344 }
345 
346 // -----------------------------------------------------------------------------
348 {
349  _Status[RX] = _Status[RY] = _Status[RZ] = (b ? Active : Passive);
350 }
351 
352 // -----------------------------------------------------------------------------
354 {
355  return _Status[RX] == Active && _Status[RY] == Active && _Status[RZ] == Active;
356 }
357 
358 // -----------------------------------------------------------------------------
360 {
361  _Status[SX] = _Status[SY] = _Status[SZ] = (b ? Active : Passive);
362 }
363 
364 // -----------------------------------------------------------------------------
366 {
367  return _Status[SX] == Active && _Status[SY] == Active && _Status[SZ] == Active;
368 }
369 
370 // -----------------------------------------------------------------------------
372 {
373  _Status[SXY] = _Status[SYZ] = _Status[SXZ] = (b ? Active : Passive);
374 }
375 
376 // -----------------------------------------------------------------------------
378 {
379  return _Status[SXY] == Active && _Status[SYZ] == Active && _Status[SXZ] == Active;
380 }
381 
382 
383 } // namespace mirtk
384 
385 #endif // MIRTK_AffineTransformation_H
static Matrix DOFs2Matrix(const double *)
Construct transformation matrix based on parameters.
virtual ParameterList Parameter() const
Get (non-DoF) parameters as key/value as string map.
void PutScaleY(double)
Puts scaling factor along the y-axis.
void PutScale(double)
Puts global scaling factor.
virtual Cifstream & ReadDOFs(Cifstream &, TransformationType)
Reads a transformation from a file stream.
double GetShearXZ() const
Gets z-dependent skewing angle in the x direction (in degrees)
double GetScaleY() const
Gets scaling factor along the y-axis.
void PutScaleX(double)
Puts scaling factor along the x-axis.
double GetShearXY() const
Gets y-dependent skewing angle in the x direction (in degrees)
virtual void UpdateDOFs()
Update transformation parameters after change of matrix.
double _tansxz
Tangent of shear angle sxz.
double GetScaleZ() const
Gets scaling factor along the z-axis.
virtual void JacobianDOFs(double [3], int, double, double, double, double=0, double=NaN) const
Calculates the Jacobian of the transformation w.r.t a transformation parameter.
bool AllowScaling() const
Whether all scaling parameters are active.
double GetScaleX() const
Gets scaling factor along the x-axis.
virtual bool Set(const char *, const char *)
Set named (non-DoF) parameter from value as string.
double GetShearYZ() const
Gets z-dependent skewing angle in the y direction (in degrees)
virtual void Put(int, DOFValue)
Puts a transformation parameter.
DOFStatus * _Status
Status of each transformation parameter (Active or Passive)
Array< Pair< string, string > > ParameterList
Ordered list of parameter name/value pairs.
Definition: Object.h:38
virtual bool CanRead(TransformationType) const
Whether this transformation can read a file of specified type (i.e. format)
AffineTransformation()
Default constructor.
virtual void Print(ostream &, Indent=0) const
Prints the parameters of the transformation.
void PutScaleZ(double)
Puts scaling factor along the z-axis.
Definition: IOConfig.h:41
bool AllowRotations() const
Whether all rotation parameters are active.
virtual bool CopyFrom(const Transformation *)
virtual void JacobianDOFs(double [3], int, double, double, double, double=0, double=-1) const
Calculates the Jacobian of the transformation w.r.t the parameters.
virtual ~AffineTransformation()
Destructor.
double GetScale() const
Not supported for affine transformation!
DOFValue * _Param
Value of each transformation parameter.
void PutShearXZ(double)
Puts z-dependent skewing angle in the x direction (in degrees)
void PutShearXY(double)
Puts y-dependent skewing angle in the x direction (in degrees)
virtual void DeriveJacobianWrtDOF(Matrix &, int, double, double, double, double=0, double=-1) const
Calculates the derivative of the Jacobian of the transformation (w.r.t. world coordinates) w...
virtual Cofstream & Write(Cofstream &) const
Writes a transformation to a file stream.
void UpdateShearingTangent()
Update cached tangents of shearing angles.
double _tansyz
Tangent of shear angle syz.
virtual void Print(ostream &, Indent=0) const
Prints the parameters of the transformation.
void Update(AttributeSelector)
Update transformation parameters and/or matrices.
virtual const char * NameOfClass() const =0
Get name of class, which this object is an instance of.
static void Matrix2DOFs(const Matrix &, double *)
Extract parameters from transformation matrix.
virtual Cofstream & Write(Cofstream &) const
Writes transformation to a file stream.
bool AllowTranslations() const
Whether all translation parameters are active.
virtual void ApproximateDOFs(const double *, const double *, const double *, const double *, const double *, const double *, const double *, int)
virtual ParameterList Parameter() const
Get (non-DoF) parameters as key/value as string map.
bool AllowShearing() const
Whether all shearing parameters are active.
virtual double Get(int) const
Get value of transformation parameter.
void PutShearYZ(double)
Puts z-dependent skewing angle in the y direction (in degrees)
virtual void UpdateMatrix()
Update transformation matrix after change of parameter.
double _tansxy
Tangent of shear angle sxy.