MultiLevelTransformation.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_MultiLevelTransformation_H
22 #define MIRTK_MultiLevelTransformation_H
23 
24 #include "mirtk/Transformation.h"
25 #include "mirtk/RigidTransformation.h"
26 #include "mirtk/AffineTransformation.h"
27 #include "mirtk/FreeFormTransformation.h"
28 
29 #include <cstdlib>
30 #include <iostream>
31 
32 
33 namespace mirtk {
34 
35 
36 const int MAX_TRANS = 200;
37 
38 
39 /**
40  * Base class for multi-level transformations.
41  *
42  * This is the abstract base class which defines a common interface for all
43  * multi-level transformations. Each derived class has to implement at least
44  * the abstract methods and some of the virtual ones. Most other methods call
45  * these virtual methods and should not be required to be overridden in
46  * subclasses.
47  */
49 {
50  mirtkAbstractTransformationMacro(MultiLevelTransformation);
51 
52 public:
53 
54  /// Type of local transformation status
55  typedef Status FFDStatus;
56 
57 protected:
58 
59  // ---------------------------------------------------------------------------
60  // Data members
61 
62  /// Global transformation
64 
65  /// Local transformations
67 
68  /// Whether this class is responsible for destructing the local transformation
69  bool _LocalTransformationOwner[MAX_TRANS];
70 
71  /// Status of local transformations
72  FFDStatus _LocalTransformationStatus[MAX_TRANS];
73 
74  /// Number of local transformations
76 
77  // ---------------------------------------------------------------------------
78  // Construction/Destruction
79 
80  /// Default constructor
82 
83  /// Construct multi-level transformation given a rigid transformation
85 
86  /// Construct multi-level transformation given an affine transformation
88 
89  /// Copy constructor
91 
92 public:
93 
94  /// Destructor
95  virtual ~MultiLevelTransformation();
96 
97  // ---------------------------------------------------------------------------
98  // Approximation
99 
100  /// Approximate displacements: This function takes a set of points and a set
101  /// of displacements and finds a transformation which approximates these
102  /// displacements. After approximation, the displacements are replaced by the
103  /// residual displacement errors at the points.
104  ///
105  /// \note This function does not change the global transformation.
106  /// Use ApproximateAsNew to also approximate a new global transformation.
107  virtual double Approximate(const ImageAttributes &, double *, double *, double *,
108  int = 1, double = .0);
109 
110  /// Approximate displacements: This function takes a set of points and a set
111  /// of displacements and finds a transformation which approximates these
112  /// displacements. After approximation, the displacements are replaced by the
113  /// residual displacement errors at the points.
114  ///
115  /// \note This function does not change the global transformation.
116  /// Use ApproximateAsNew to also approximate a new global transformation.
117  virtual double Approximate(const double *, const double *, const double *,
118  double *, double *, double *, int,
119  int = 1, double = .0);
120 
121  /// Approximate displacements: This function takes a set of points and a set
122  /// of displacements and finds a transformation which approximates these
123  /// displacements. After approximation, the displacements are replaced by the
124  /// residual displacement errors at the points.
125  ///
126  /// \note This function does not change the global transformation.
127  /// Use ApproximateAsNew to also approximate a new global transformation.
128  virtual double Approximate(const double *, const double *, const double *, const double *,
129  double *, double *, double *, int,
130  int = 1, double = .0);
131 
132  /// Approximate displacements: This function takes a set of points and a set
133  /// of displacements and finds a !new! transformation which approximates these
134  /// displacements. After approximation, the displacements are replaced by the
135  /// residual displacement errors at the points.
136  ///
137  /// \note This function also modifies the global transformation.
138  /// Use Reset and Approximate instead if this is not desired.
139  virtual double ApproximateAsNew(const ImageAttributes &, double *, double *, double *,
140  int = 1, double = .0);
141 
142  /// Approximate displacements: This function takes a set of points and a set
143  /// of displacements and finds a !new! transformation which approximates these
144  /// displacements. After approximation, the displacements are replaced by the
145  /// residual displacement errors at the points.
146  ///
147  /// \note This function also modifies the global transformation.
148  /// Use Reset and Approximate instead if this is not desired.
149  virtual double ApproximateAsNew(const double *, const double *, const double *,
150  double *, double *, double *, int,
151  int = 1, double = .0);
152 
153  /// Approximate displacements: This function takes a set of points and a set
154  /// of displacements and finds a !new! transformation which approximates these
155  /// displacements. After approximation, the displacements are replaced by the
156  /// residual displacement errors at the points.
157  ///
158  /// \note This function also modifies the global transformation.
159  /// Use Reset and Approximate instead if this is not desired.
160  virtual double ApproximateAsNew(const double *, const double *, const double *, const double *,
161  double *, double *, double *, int,
162  int = 1, double = .0);
163 
164  /// Approximate displacements: This function takes a set of points and a set
165  /// of displacements and finds !new! parameters such that the resulting
166  /// transformation approximates the displacements as good as possible.
167  virtual void ApproximateDOFs(const double *, const double *, const double *, const double *,
168  const double *, const double *, const double *, int);
169 
170  /// Finds gradient of approximation error: This function takes a set of points
171  /// and a set of errors. It finds a gradient w.r.t. the transformation parameters
172  /// which minimizes the L2 norm of the approximation error and adds it to the
173  /// input gradient with the given weight.
174  virtual void ApproximateDOFsGradient(const double *, const double *, const double *, const double *,
175  const double *, const double *, const double *, int,
176  double *, double = 1.0) const;
177 
178  // ---------------------------------------------------------------------------
179  // Transformation parameters (DoFs)
180 
181  /// Copy active transformation parameters (DoFs) from given
182  /// transformation if possible and return \c false, otherwise
183  virtual bool CopyFrom(const Transformation *);
184 
185  /// Get norm of the gradient vector
186  virtual double DOFGradientNorm(const double *) const;
187 
188  /// Get number of transformation parameters
189  virtual int NumberOfDOFs() const;
190 
191  /// Put value of transformation parameter
192  virtual void Put(int, double);
193 
194  /// Put values of transformation parameters
195  virtual void Put(const DOFValue *);
196 
197  /// Add change to transformation parameters
198  virtual void Add(const DOFValue *);
199 
200  /// Update transformation parameters given parametric gradient
201  virtual double Update(const DOFValue *);
202 
203  /// Get value of transformation parameter
204  virtual double Get(int) const;
205 
206  /// Get values of transformation parameters
207  virtual void Get(DOFValue *) const;
208 
209  /// Put status of transformation parameter
210  virtual void PutStatus(int, DOFStatus);
211 
212  /// Get status of transformation parameter
213  virtual DOFStatus GetStatus(int) const;
214 
215  /// Checks whether transformation depends on the same vector of parameters
216  virtual bool HasSameDOFsAs(const Transformation *) const;
217 
218  /// Checks whether transformation is an identity mapping
219  virtual bool IsIdentity() const;
220 
221  /// Reset transformation (does not remove local transformations)
222  virtual void Reset();
223 
224  /// Reset transformation and remove all local transformations
225  virtual void Clear();
226 
227  // ---------------------------------------------------------------------------
228  // Parameters (non-DoFs)
229 
230  // Import other overloads
232 
233  /// Set named (non-DoF) parameter from value as string
234  virtual bool Set(const char *, const char *);
235 
236  /// Get (non-DoF) parameters as key/value as string map
237  virtual ParameterList Parameter() const;
238 
239  // ---------------------------------------------------------------------------
240  // Levels
241 
242  /// Returns the number of levels
243  virtual int NumberOfLevels() const;
244 
245  /// Returns the number of active levels
246  virtual int NumberOfActiveLevels() const;
247 
248  /// Returns the number of passive levels
249  virtual int NumberOfPassiveLevels() const;
250 
251  /// Returns the total number of control points
252  virtual int NumberOfCPs(bool = false) const;
253 
254  /// Returns the total number of active control points on all active levels
255  virtual int NumberOfActiveCPs() const;
256 
257  /// Gets global transformation
259 
260  /// Get global transformation
261  virtual const AffineTransformation *GetGlobalTransformation() const;
262 
263  /// Gets local transformation
265 
266  /// Gets local transformation
267  virtual const FreeFormTransformation *GetLocalTransformation(int) const;
268 
269  /// Put local transformation and return pointer to previous one (needs to be deleted if not used)
271 
272  /// Push local transformation on stack (append transformation)
273  virtual void PushLocalTransformation(FreeFormTransformation *, bool = true);
274 
275  /// Insert local transformation
276  virtual void InsertLocalTransformation(FreeFormTransformation *, int = 0, bool = true);
277 
278  /// Pop local transformation from stack (remove last transformation)
280 
281  /// Remove local transformation and return the pointer (need to be deleted if not used)
283 
284  /// Combine local transformations on stack
285  virtual void CombineLocalTransformation();
286 
287  /// Put status of local transformation
288  virtual void LocalTransformationStatus(int, FFDStatus);
289 
290  /// Get status of local transformation
291  virtual FFDStatus LocalTransformationStatus(int) const;
292 
293  /// Get whether local transformation is active
294  virtual bool LocalTransformationIsActive(int) const;
295 
296  /// Convert the global transformation from a matrix representation to a
297  /// FFD and incorporate it with any existing local transformation
298  virtual void MergeGlobalIntoLocalDisplacement();
299 
300 protected:
301 
302  /// Checks whether a given transformation is supported as local transformation
303  virtual void CheckTransformation(FreeFormTransformation *) const;
304 
305  /// Helper function for MergeGlobalIntoLocalDisplacement
307 
308 public:
309 
310  // ---------------------------------------------------------------------------
311  // Point transformation
312 
313  // Do not hide methods of base class
320 
321  /// Whether the caching of the transformation displacements is required
322  /// (or preferred) by this transformation. For some transformations such as
323  /// those parameterized by velocities, caching of the displacements for
324  /// each target voxel results in better performance or is needed for example
325  /// for the scaling and squaring method.
326  virtual bool RequiresCachingOfDisplacements() const;
327 
328  /// Transforms a single point using the global transformation component only
329  virtual void GlobalTransform(double &, double &, double &, double = 0, double = NaN) const;
330 
331  /// Transforms a single point using the local transformation component only
332  virtual void LocalTransform(int, int, double &, double &, double &, double = 0, double = NaN) const;
333 
334  /// Transforms a single point using the local transformation component only
335  virtual void LocalTransform(int, double &, double &, double &, double = 0, double = NaN) const;
336 
337  /// Transforms a single point using the local transformation component only
338  virtual void LocalTransform(double &, double &, double &, double = 0, double = NaN) const;
339 
340  /// Transforms a single point
341  virtual void Transform(int, int, double &, double &, double &, double = 0, double = NaN) const = 0;
342 
343  /// Transforms a single point
344  virtual void Transform(int, double &, double &, double &, double = 0, double = NaN) const;
345 
346  /// Transforms a single point
347  virtual void Transform(double &, double &, double &, double = 0, double = NaN) const;
348 
349  /// Transforms a single point
350  virtual void Transform(int, int, Point &, double = 0, double = NaN) const;
351 
352  /// Transforms a single point
353  virtual void Transform(int, Point &, double = 0, double = NaN) const;
354 
355  /// Transforms a set of points
356  virtual void Transform(int, int, PointSet &, double = 0, double = NaN) const;
357 
358  /// Transforms a set of points
359  virtual void Transform(int, PointSet &, double = 0, double = NaN) const;
360 
361  /// Calculates the displacement of a single point using the local transformation component only
362  virtual void LocalDisplacement(int, int, double &, double &, double &, double = 0, double = NaN) const;
363 
364  /// Calculates the displacement of a single point using the local transformation component only
365  virtual void LocalDisplacement(int, double &, double &, double &, double = 0, double = NaN) const;
366 
367  /// Calculates the displacement of a single point
368  virtual void Displacement(int, int, double &, double &, double &, double = 0, double = NaN) const;
369 
370  /// Calculates the displacement of a single point
371  virtual void Displacement(int, double &, double &, double &, double = 0, double = NaN) const;
372 
373  /// Calculates the displacement vectors for a whole image domain
374  virtual void Displacement(int, int, GenericImage<double> &, double = NaN, const WorldCoordsImage * = NULL) const;
375 
376  /// Calculates the displacement vectors for a whole image domain
377  virtual void Displacement(int, int, GenericImage<float> &, double = NaN, const WorldCoordsImage * = NULL) const;
378 
379  /// Calculates the displacement vectors for a whole image domain
380  virtual void Displacement(int, GenericImage<double> &, double = NaN, const WorldCoordsImage * = NULL) const;
381 
382  /// Calculates the displacement vectors for a whole image domain
383  virtual void Displacement(int, GenericImage<float> &, double = NaN, const WorldCoordsImage * = NULL) const;
384 
385  /// Calculates the displacement vectors for a whole image domain
386  ///
387  /// \attention The displacements are computed at the positions after applying the
388  /// current displacements at each voxel. These displacements are then
389  /// added to the current displacements. Therefore, set the input
390  /// displacements to zero if only interested in the displacements of
391  /// this transformation at the voxel positions.
392  virtual void Displacement(int, int, GenericImage<double> &, double, double = NaN, const WorldCoordsImage * = NULL) const;
393 
394  /// Calculates the displacement vectors for a whole image domain
395  ///
396  /// \attention The displacements are computed at the positions after applying the
397  /// current displacements at each voxel. These displacements are then
398  /// added to the current displacements. Therefore, set the input
399  /// displacements to zero if only interested in the displacements of
400  /// this transformation at the voxel positions.
401  virtual void Displacement(int, int, GenericImage<float> &, double, double = NaN, const WorldCoordsImage * = NULL) const;
402 
403  /// Calculates the displacement vectors for a whole image domain
404  ///
405  /// \attention The displacements are computed at the positions after applying the
406  /// current displacements at each voxel. These displacements are then
407  /// added to the current displacements. Therefore, set the input
408  /// displacements to zero if only interested in the displacements of
409  /// this transformation at the voxel positions.
410  virtual void Displacement(int, GenericImage<double> &, double, double = NaN, const WorldCoordsImage * = NULL) const;
411 
412  /// Calculates the displacement vectors for a whole image domain
413  ///
414  /// \attention The displacements are computed at the positions after applying the
415  /// current displacements at each voxel. These displacements are then
416  /// added to the current displacements. Therefore, set the input
417  /// displacements to zero if only interested in the displacements of
418  /// this transformation at the voxel positions.
419  virtual void Displacement(int, GenericImage<float> &, double, double = NaN, const WorldCoordsImage * = NULL) const;
420 
421  /// Calculates the displacement vectors for a whole image domain
422  ///
423  /// \attention The displacements are computed at the positions after applying the
424  /// current displacements at each voxel. These displacements are then
425  /// added to the current displacements. Therefore, set the input
426  /// displacements to zero if only interested in the displacements of
427  /// this transformation at the voxel positions.
428  virtual void Displacement(GenericImage<double> &, double, double = NaN, const WorldCoordsImage * = NULL) const;
429 
430  /// Calculates the displacement vectors for a whole image domain
431  ///
432  /// \attention The displacements are computed at the positions after applying the
433  /// current displacements at each voxel. These displacements are then
434  /// added to the current displacements. Therefore, set the input
435  /// displacements to zero if only interested in the displacements of
436  /// this transformation at the voxel positions.
437  virtual void Displacement(GenericImage<float> &, double, double = NaN, const WorldCoordsImage * = NULL) const;
438 
439  /// Transforms a single point using the inverse of the global transformation only
440  virtual void GlobalInverse(double &, double &, double &, double = 0, double = NaN) const;
441 
442  /// Transforms a single point using the inverse of the local transformation only
443  virtual bool LocalInverse(int, int, double &, double &, double &, double = 0, double = NaN) const;
444 
445  /// Transforms a single point using the inverse of the local transformation only
446  virtual bool LocalInverse(int, double &, double &, double &, double = 0, double = NaN) const;
447 
448  /// Transforms a single point using the inverse of the local transformation only
449  virtual bool LocalInverse(double &, double &, double &, double = 0, double = NaN) const;
450 
451  /// Transforms a single point using the inverse of the transformation
452  virtual bool Inverse(int, int, double &, double &, double &, double = 0, double = NaN) const;
453 
454  /// Transforms a single point using the inverse of the transformation
455  virtual bool Inverse(int, double &, double &, double &, double = 0, double = NaN) const;
456 
457  /// Transforms a single point using the inverse of the transformation
458  virtual bool Inverse(double &, double &, double &, double = 0, double = NaN) const;
459 
460  /// Calculates the displacement of a single point using the inverse of the local transformation only
461  virtual bool LocalInverseDisplacement(int, int, double &, double &, double &, double = 0, double = NaN) const;
462 
463  /// Calculates the displacement of a single point using the inverse of the local transformation only
464  virtual bool LocalInverseDisplacement(int, double &, double &, double &, double = 0, double = NaN) const;
465 
466  /// Calculates the displacement of a single point using the inverse of the transformation
467  virtual bool InverseDisplacement(int, int, double &, double &, double &, double = 0, double = NaN) const;
468 
469  /// Calculates the displacement of a single point using the inverse of the transformation
470  virtual bool InverseDisplacement(int, double &, double &, double &, double = 0, double = NaN) const;
471 
472  /// Calculates the inverse displacement vectors for a whole image domain
473  ///
474  /// \attention The displacements are computed at the positions after applying the
475  /// current displacements at each voxel. These displacements are then
476  /// added to the current displacements. Therefore, set the input
477  /// displacements to zero if only interested in the displacements of
478  /// this transformation at the voxel positions.
479  ///
480  /// \returns Number of points at which transformation is non-invertible.
481  virtual int InverseDisplacement(int, int, GenericImage<double> &, double, double = NaN, const WorldCoordsImage * = NULL) const;
482 
483  /// Calculates the inverse displacement vectors for a whole image domain
484  ///
485  /// \attention The displacements are computed at the positions after applying the
486  /// current displacements at each voxel. These displacements are then
487  /// added to the current displacements. Therefore, set the input
488  /// displacements to zero if only interested in the displacements of
489  /// this transformation at the voxel positions.
490  ///
491  /// \returns Number of points at which transformation is non-invertible.
492  virtual int InverseDisplacement(int, int, GenericImage<float> &, double, double = NaN, const WorldCoordsImage * = NULL) const;
493 
494  /// Calculates the inverse displacement vectors for a whole image domain
495  ///
496  /// \attention The displacements are computed at the positions after applying the
497  /// current displacements at each voxel. These displacements are then
498  /// added to the current displacements. Therefore, set the input
499  /// displacements to zero if only interested in the displacements of
500  /// this transformation at the voxel positions.
501  ///
502  /// \returns Number of points at which transformation is non-invertible.
503  virtual int InverseDisplacement(int, GenericImage<double> &, double, double = NaN, const WorldCoordsImage * = NULL) const;
504 
505  /// Calculates the inverse displacement vectors for a whole image domain
506  ///
507  /// \attention The displacements are computed at the positions after applying the
508  /// current displacements at each voxel. These displacements are then
509  /// added to the current displacements. Therefore, set the input
510  /// displacements to zero if only interested in the displacements of
511  /// this transformation at the voxel positions.
512  ///
513  /// \returns Number of points at which transformation is non-invertible.
514  virtual int InverseDisplacement(int, GenericImage<float> &, double, double = NaN, const WorldCoordsImage * = NULL) const;
515 
516  /// Calculates the inverse displacement vectors for a whole image domain
517  ///
518  /// \attention The displacements are computed at the positions after applying the
519  /// current displacements at each voxel. These displacements are then
520  /// added to the current displacements. Therefore, set the input
521  /// displacements to zero if only interested in the displacements of
522  /// this transformation at the voxel positions.
523  ///
524  /// \returns Number of points at which transformation is non-invertible.
525  virtual int InverseDisplacement(GenericImage<double> &, double, double = NaN, const WorldCoordsImage * = NULL) const;
526 
527  /// Calculates the inverse displacement vectors for a whole image domain
528  ///
529  /// \attention The displacements are computed at the positions after applying the
530  /// current displacements at each voxel. These displacements are then
531  /// added to the current displacements. Therefore, set the input
532  /// displacements to zero if only interested in the displacements of
533  /// this transformation at the voxel positions.
534  ///
535  /// \returns Number of points at which transformation is non-invertible.
536  virtual int InverseDisplacement(GenericImage<float> &, double, double = NaN, const WorldCoordsImage * = NULL) const;
537 
538  // ---------------------------------------------------------------------------
539  // Derivatives
540 
541  // Do not hide methods of base class
545 
546  /// Calculates the Jacobian of the global transformation w.r.t world coordinates
547  virtual void GlobalJacobian(Matrix &, double, double, double, double = 0, double = NaN) const;
548 
549  /// Calculates the Jacobian of the local transformation w.r.t world coordinates
550  virtual void LocalJacobian(int, Matrix &, double, double, double, double = 0, double = NaN) const;
551 
552  /// Calculates the Jacobian of the local transformation w.r.t world coordinates
553  virtual void LocalJacobian(Matrix &, double, double, double, double = 0, double = NaN) const;
554 
555  /// Calculates the Jacobian of the transformation w.r.t world coordinates
556  virtual void Jacobian(int, int, Matrix &, double, double, double, double = 0, double = NaN) const;
557 
558  /// Calculates the Jacobian of the transformation w.r.t world coordinates
559  virtual void Jacobian(int, Matrix &, double, double, double, double = 0, double = NaN) const;
560 
561  /// Calculates the Jacobian of the transformation w.r.t world coordinates
562  virtual void Jacobian(Matrix &, double, double, double, double = 0, double = NaN) const;
563 
564  /// Calculates the determinant of the Jacobian of the local transformation w.r.t world coordinates
565  virtual double LocalJacobian(int, double, double, double, double = 0, double = NaN) const;
566 
567  /// Calculates the determinant of the Jacobian of the transformation w.r.t world coordinates
568  virtual double Jacobian(int, int, double, double, double, double = 0, double = NaN) const;
569 
570  /// Calculates the determinant of the Jacobian of the transformation w.r.t world coordinates
571  virtual double Jacobian(int, double, double, double, double = 0, double = NaN) const;
572 
573  /// Calculates the Hessian for each component of the global transformation w.r.t world coordinates
574  virtual void GlobalHessian(Matrix [3], double, double, double, double = 0, double = NaN) const;
575 
576  /// Calculates the Hessian for each component of the local transformation w.r.t world coordinates
577  virtual void LocalHessian(int, Matrix [3], double, double, double, double = 0, double = NaN) const;
578 
579  /// Calculates the Hessian for each component of the local transformation w.r.t world coordinates
580  virtual void LocalHessian(Matrix [3], double, double, double, double = 0, double = NaN) const;
581 
582  /// Calculates the Hessian for each component of the transformation w.r.t world coordinates
583  virtual void Hessian(int, int, Matrix [3], double, double, double, double = 0, double = NaN) const;
584 
585  /// Calculates the Hessian for each component of the transformation w.r.t world coordinates
586  virtual void Hessian(int, Matrix [3], double, double, double, double = 0, double = NaN) const;
587 
588  /// Calculates the Hessian for each component of the transformation w.r.t world coordinates
589  virtual void Hessian(Matrix [3], double, double, double, double = 0, double = NaN) const;
590 
591  /// Calculates the Jacobian of the transformation w.r.t the transformation parameters
592  virtual void JacobianDOFs(double [3], int, double, double, double, double = 0, double = NaN) const;
593 
594  /// Calculates the derivative of the Jacobian of the transformation (w.r.t. world coordinates) w.r.t. a transformation parameter
595  virtual void DeriveJacobianWrtDOF(Matrix &, int, double, double, double, double = 0, double = NaN) const;
596 
597  // ---------------------------------------------------------------------------
598  // Properties
599 
600  /// Calculates the bending energy of the transformation
601  virtual double BendingEnergy(int, int, double, double, double, double = 0, double = NaN, bool = true) const;
602 
603  /// Calculates the bending energy of the transformation
604  virtual double BendingEnergy(int, double, double, double, double = 0, double = NaN, bool = true) const;
605 
606  /// Calculates the bending energy of the transformation
607  virtual double BendingEnergy(double, double, double, double = 0, double = NaN, bool = true) const;
608 
609  // ---------------------------------------------------------------------------
610  // I/O
611 
612  // Do not hide methods of base class
613  using Transformation::Print;
614 
615  /// Prints the parameters of the transformation
616  virtual void Print(ostream &, Indent = 0) const;
617 
618 protected:
619 
620  /// Reads transformation parameters from a file stream
622 
623  /// Writes transformation parameters to a file stream
624  virtual Cofstream &WriteDOFs(Cofstream &) const;
625 
626 };
627 
628 ////////////////////////////////////////////////////////////////////////////////
629 // Inline definitions
630 ////////////////////////////////////////////////////////////////////////////////
631 
632 // =============================================================================
633 // Transformation parameters
634 // =============================================================================
635 
636 // -----------------------------------------------------------------------------
637 inline int DOFIndexToLocalTransformation(const MultiLevelTransformation *mffd, int idx,
638  const FreeFormTransformation *&ffd, int &dof)
639 {
640  mirtkAssert(idx >= 0, "DoF index must be positive");
641  dof = idx;
642  for (int l = 0; l < mffd->NumberOfLevels(); ++l) {
643  if (!mffd->LocalTransformationIsActive(l)) continue;
644  ffd = mffd->GetLocalTransformation(l);
645  if (dof < ffd->NumberOfDOFs()) return l;
646  dof -= ffd->NumberOfDOFs();
647  }
648  ffd = NULL;
649  mirtkAssert(false, "DoF index out-of-bounds");
650  return -1;
651 }
652 
653 // -----------------------------------------------------------------------------
654 inline int DOFIndexToLocalTransformation(MultiLevelTransformation *mffd, int idx,
655  FreeFormTransformation *&ffd, int &dof)
656 {
657  mirtkAssert(idx >= 0, "DoF index must be positive");
658  dof = idx;
659  for (int l = 0; l < mffd->NumberOfLevels(); ++l) {
660  if (!mffd->LocalTransformationIsActive(l)) continue;
661  ffd = mffd->GetLocalTransformation(l);
662  if (dof < ffd->NumberOfDOFs()) return l;
663  dof -= ffd->NumberOfDOFs();
664  }
665  ffd = NULL;
666  mirtkAssert(false, "DoF index out-of-bounds");
667  return -1;
668 }
669 
670 // =============================================================================
671 // Levels
672 // =============================================================================
673 
674 // -----------------------------------------------------------------------------
676 {
677  return _NumberOfLevels;
678 }
679 
680 // -----------------------------------------------------------------------------
682 {
683  int n = 0;
684  for (int i = 0; i < _NumberOfLevels; ++i) {
685  if (_LocalTransformationStatus[i] == Active) ++n;
686  }
687  return n;
688 }
689 
690 // -----------------------------------------------------------------------------
692 {
693  return _NumberOfLevels - this->NumberOfActiveLevels();
694 }
695 
696 // -----------------------------------------------------------------------------
698 {
699  return &_GlobalTransformation;
700 }
701 
702 // -----------------------------------------------------------------------------
704 {
705  return &_GlobalTransformation;
706 }
707 
708 // -----------------------------------------------------------------------------
710 {
711  if (i < 0) i += _NumberOfLevels;
712  return (0 <= i && i < _NumberOfLevels) ? _LocalTransformation[i] : NULL;
713 }
714 
715 // -----------------------------------------------------------------------------
717 {
718  if (i < 0) i += _NumberOfLevels;
719  return (0 <= i && i < _NumberOfLevels) ? _LocalTransformation[i] : NULL;
720 }
721 
722 // -----------------------------------------------------------------------------
724 {
725  if (i < 0) i += _NumberOfLevels;
726  _LocalTransformationStatus[i] = status;
727 }
728 
729 // -----------------------------------------------------------------------------
732 {
733  if (i < 0) i += _NumberOfLevels;
734  return _LocalTransformationStatus[i];
735 }
736 
737 // -----------------------------------------------------------------------------
739 {
740  if (i < 0) i += _NumberOfLevels;
741  return (_LocalTransformationStatus[i] == Active);
742 }
743 
744 // =============================================================================
745 // Point transformation
746 // =============================================================================
747 
748 // -----------------------------------------------------------------------------
750 {
751  for (int i = 0; i < this->NumberOfLevels(); ++i) {
752  if (this->GetLocalTransformation(i)->RequiresCachingOfDisplacements()) return true;
753  }
754  return false;
755 }
756 
757 // -----------------------------------------------------------------------------
758 inline void MultiLevelTransformation::GlobalTransform(double &x, double &y, double &z, double t, double t0) const
759 {
760  this->GetGlobalTransformation()->Transform(x, y, z, t, t0);
761 }
762 
763 // -----------------------------------------------------------------------------
764 // Note: The Transformation interface requires that every transformation is
765 // the sum of global and local transformations, i.e., T = T_global + T_local.
766 // This allows a common interpretation of what LocalTransform does.
767 inline void MultiLevelTransformation::LocalTransform(int m, int n, double &x, double &y, double &z, double t, double t0) const
768 {
769  if (m < 0) {
770  // Compute y = x + (T(x) - T_global(x))
771  double x1 = x, y1 = y, z1 = z;
772  double x2 = x, y2 = y, z2 = z;
773  this->GetGlobalTransformation()->Transform(x1, y1, z1);
774  this->Transform(-1, n, x2, y2, z2, t, t0);
775  x += (x2 - x1);
776  y += (y2 - y1);
777  z += (z2 - z1);
778  } else {
779  this->Transform(m, n, x, y, z, t, t0);
780  }
781 }
782 
783 // -----------------------------------------------------------------------------
784 inline void MultiLevelTransformation::LocalTransform(int n, double &x, double &y, double &z, double t, double t0) const
785 {
786  this->LocalTransform(0, n, x, y, z, t, t0);
787 }
788 
789 // -----------------------------------------------------------------------------
790 inline void MultiLevelTransformation::LocalTransform(double &x, double &y, double &z, double t, double t0) const
791 {
792  this->LocalTransform(-1, x, y, z, t, t0);
793 }
794 
795 // -----------------------------------------------------------------------------
796 inline void MultiLevelTransformation::Transform(int n, double &x, double &y, double &z, double t, double t0) const
797 {
798  this->Transform(-1, n, x, y, z, t, t0);
799 }
800 
801 // -----------------------------------------------------------------------------
802 inline void MultiLevelTransformation::Transform(double &x, double &y, double &z, double t, double t0) const
803 {
804  this->Transform(-1, x, y, z, t, t0);
805 }
806 
807 // -----------------------------------------------------------------------------
808 inline void MultiLevelTransformation::Transform(int l, int n, Point &p, double t, double t0) const
809 {
810  this->Transform(l, n, p._x, p._y, p._z, t, t0);
811 }
812 
813 // -----------------------------------------------------------------------------
814 inline void MultiLevelTransformation::Transform(int n, Point &p, double t, double t0) const
815 {
816  this->Transform(0, n, p, t, t0);
817 }
818 
819 // -----------------------------------------------------------------------------
820 inline void MultiLevelTransformation::Transform(int l, int n, PointSet &pset, double t, double t0) const
821 {
822  for (int i = 0; i < pset.Size(); i++) this->Transform(l, n, pset(i), t, t0);
823 }
824 
825 // -----------------------------------------------------------------------------
826 inline void MultiLevelTransformation::Transform(int n, PointSet &pset, double t, double t0) const
827 {
828  this->Transform(0, n, pset, t, t0);
829 }
830 
831 // -----------------------------------------------------------------------------
832 inline void MultiLevelTransformation::LocalDisplacement(int l, int n, double &x, double &y, double &z, double t, double t0) const
833 {
834  const double u = x;
835  const double v = y;
836  const double w = z;
837 
838  this->LocalTransform(l, n, x, y, z, t, t0);
839 
840  x -= u;
841  y -= v;
842  z -= w;
843 }
844 
845 // -----------------------------------------------------------------------------
846 inline void MultiLevelTransformation::LocalDisplacement(int n, double &x, double &y, double &z, double t, double t0) const
847 {
848  this->LocalDisplacement(0, n, x, y, z, t, t0);
849 }
850 
851 // -----------------------------------------------------------------------------
852 inline void MultiLevelTransformation::Displacement(int l, int n, double &x, double &y, double &z, double t, double t0) const
853 {
854  const double u = x;
855  const double v = y;
856  const double w = z;
857 
858  this->Transform(l, n, x, y, z, t, t0);
859 
860  x -= u;
861  y -= v;
862  z -= w;
863 }
864 
865 // -----------------------------------------------------------------------------
866 inline void MultiLevelTransformation::Displacement(int n, double &x, double &y, double &z, double t, double t0) const
867 {
868  this->Displacement(-1, n, x, y, z, t, t0);
869 }
870 
871 // -----------------------------------------------------------------------------
872 inline void MultiLevelTransformation::Displacement(int l, int n, GenericImage<double> &disp, double t0, const WorldCoordsImage *i2w) const
873 {
874  disp = .0;
875  this->Displacement(l, n, disp, disp.GetTOrigin(), t0, i2w);
876 }
877 
878 // -----------------------------------------------------------------------------
879 inline void MultiLevelTransformation::Displacement(int l, int n, GenericImage<float> &disp, double t0, const WorldCoordsImage *i2w) const
880 {
881  disp = .0f;
882  this->Displacement(l, n, disp, disp.GetTOrigin(), t0, i2w);
883 }
884 
885 // -----------------------------------------------------------------------------
886 inline void MultiLevelTransformation::Displacement(int n, GenericImage<double> &disp, double t0, const WorldCoordsImage *i2w) const
887 {
888  this->Displacement(-1, n, disp, t0, i2w);
889 }
890 
891 // -----------------------------------------------------------------------------
892 inline void MultiLevelTransformation::Displacement(int n, GenericImage<float> &disp, double t0, const WorldCoordsImage *i2w) const
893 {
894  this->Displacement(-1, n, disp, t0, i2w);
895 }
896 
897 // -----------------------------------------------------------------------------
898 inline void MultiLevelTransformation::Displacement(int n, GenericImage<double> &disp, double t, double t0, const WorldCoordsImage *wc) const
899 {
900  this->Displacement(-1, n, disp, t, t0, wc);
901 }
902 
903 // -----------------------------------------------------------------------------
904 inline void MultiLevelTransformation::Displacement(int n, GenericImage<float> &disp, double t, double t0, const WorldCoordsImage *wc) const
905 {
906  this->Displacement(-1, n, disp, t, t0, wc);
907 }
908 
909 // -----------------------------------------------------------------------------
910 inline void MultiLevelTransformation::Displacement(GenericImage<double> &disp, double t, double t0, const WorldCoordsImage *wc) const
911 {
912  this->Displacement(-1, disp, t, t0, wc);
913 }
914 
915 // -----------------------------------------------------------------------------
916 inline void MultiLevelTransformation::Displacement(GenericImage<float> &disp, double t, double t0, const WorldCoordsImage *wc) const
917 {
918  this->Displacement(-1, disp, t, t0, wc);
919 }
920 
921 // -----------------------------------------------------------------------------
922 inline void MultiLevelTransformation::GlobalInverse(double &x, double &y, double &z, double t, double t0) const
923 {
924  this->GetGlobalTransformation()->Inverse(x, y, z, t, t0);
925 }
926 
927 // -----------------------------------------------------------------------------
928 // Note: The Transformation interface requires that every transformation is
929 // the sum of global and local transformations, i.e., T = T_global + T_local.
930 // This allows a common interpretation of what LocalTransform does.
931 inline bool MultiLevelTransformation::LocalInverse(int m, int n, double &x, double &y, double &z, double t, double t0) const
932 {
933  if (m < 0) {
934  // Compute y = x + (inv T(x) - inv T_global(x))
935  double x1 = x, y1 = y, z1 = z;
936  double x2 = x, y2 = y, z2 = z;
937  this->GetGlobalTransformation()->Inverse(x1, y1, z1);
938  bool ok = this->Inverse(-1, n, x2, y2, z2, t, t0);
939  x += (x2 - x1);
940  y += (y2 - y1);
941  z += (z2 - z1);
942  return ok;
943  } else {
944  return this->Inverse(m, n, x, y, z, t, t0);
945  }
946 }
947 
948 // -----------------------------------------------------------------------------
949 inline bool MultiLevelTransformation::LocalInverse(int n, double &x, double &y, double &z, double t, double t0) const
950 {
951  return this->LocalInverse(0, n, x, y, z, t, t0);
952 }
953 
954 // -----------------------------------------------------------------------------
955 inline bool MultiLevelTransformation::LocalInverse(double &x, double &y, double &z, double t, double t0) const
956 {
957  return this->LocalInverse(-1, x, y, z, t, t0);
958 }
959 
960 // -----------------------------------------------------------------------------
961 inline bool MultiLevelTransformation::Inverse(int n, double &x, double &y, double &z, double t, double t0) const
962 {
963  return this->Inverse(-1, n, x, y, z, t, t0);
964 }
965 
966 // -----------------------------------------------------------------------------
967 inline bool MultiLevelTransformation::Inverse(double &x, double &y, double &z, double t, double t0) const
968 {
969  return this->Inverse(-1, x, y, z, t, t0);
970 }
971 
972 // -----------------------------------------------------------------------------
973 inline bool MultiLevelTransformation::LocalInverseDisplacement(int l, int n, double &x, double &y, double &z, double t, double t0) const
974 {
975  const double u = x;
976  const double v = y;
977  const double w = z;
978 
979  bool ok = this->LocalInverse(l, n, x, y, z, t, t0);
980 
981  x -= u;
982  y -= v;
983  z -= w;
984 
985  return ok;
986 }
987 
988 // -----------------------------------------------------------------------------
989 inline bool MultiLevelTransformation::LocalInverseDisplacement(int n, double &x, double &y, double &z, double t, double t0) const
990 {
991  return this->LocalInverseDisplacement(0, n, x, y, z, t, t0);
992 }
993 
994 // -----------------------------------------------------------------------------
995 inline bool MultiLevelTransformation::InverseDisplacement(int l, int n, double &x, double &y, double &z, double t, double t0) const
996 {
997  const double u = x;
998  const double v = y;
999  const double w = z;
1000 
1001  bool ok = this->Inverse(l, n, x, y, z, t, t0);
1002 
1003  x -= u;
1004  y -= v;
1005  z -= w;
1006 
1007  return ok;
1008 }
1009 
1010 // -----------------------------------------------------------------------------
1011 inline bool MultiLevelTransformation::InverseDisplacement(int n, double &x, double &y, double &z, double t, double t0) const
1012 {
1013  return this->InverseDisplacement(-1, n, x, y, z, t, t0);
1014 }
1015 
1016 // -----------------------------------------------------------------------------
1017 inline int MultiLevelTransformation::InverseDisplacement(int n, GenericImage<double> &disp, double t, double t0, const WorldCoordsImage *wc) const
1018 {
1019  return this->InverseDisplacement(-1, n, disp, t, t0, wc);
1020 }
1021 
1022 // -----------------------------------------------------------------------------
1023 inline int MultiLevelTransformation::InverseDisplacement(int n, GenericImage<float> &disp, double t, double t0, const WorldCoordsImage *wc) const
1024 {
1025  return this->InverseDisplacement(-1, n, disp, t, t0, wc);
1026 }
1027 
1028 // -----------------------------------------------------------------------------
1029 inline int MultiLevelTransformation::InverseDisplacement(GenericImage<double> &disp, double t, double t0, const WorldCoordsImage *wc) const
1030 {
1031  return this->InverseDisplacement(-1, disp, t, t0, wc);
1032 }
1033 
1034 // -----------------------------------------------------------------------------
1035 inline int MultiLevelTransformation::InverseDisplacement(GenericImage<float> &disp, double t, double t0, const WorldCoordsImage *wc) const
1036 {
1037  return this->InverseDisplacement(-1, disp, t, t0, wc);
1038 }
1039 
1040 // =============================================================================
1041 // Derivatives
1042 // =============================================================================
1043 
1044 // -----------------------------------------------------------------------------
1045 inline void MultiLevelTransformation::Jacobian(int, int, Matrix &, double, double, double, double, double) const
1046 {
1047  cerr << this->NameOfClass() << "::Jacobian(int, int, ...): Not implemented" << endl;
1048  exit(1);
1049 }
1050 
1051 // -----------------------------------------------------------------------------
1052 inline void MultiLevelTransformation::Jacobian(int n, Matrix &jac, double x, double y, double z, double t, double t0) const
1053 {
1054  this->Jacobian(-1, n, jac, x, y, z, t, t0);
1055 }
1056 
1057 // -----------------------------------------------------------------------------
1058 inline void MultiLevelTransformation::Jacobian(Matrix &jac, double x, double y, double z, double t, double t0) const
1059 {
1060  this->Jacobian(-1, -1, jac, x, y, z, t, t0);
1061 }
1062 
1063 // -----------------------------------------------------------------------------
1064 inline void MultiLevelTransformation::GlobalJacobian(Matrix &jac, double x, double y, double z, double t, double t0) const
1065 {
1066  this->GetGlobalTransformation()->Jacobian(jac, x, y, z, t, t0);
1067 }
1068 
1069 // -----------------------------------------------------------------------------
1070 inline void MultiLevelTransformation::LocalJacobian(int n, Matrix &jac, double x, double y, double z, double t, double t0) const
1071 {
1072  this->Jacobian(0, n, jac, x, y, z, t, t0);
1073 }
1074 
1075 // -----------------------------------------------------------------------------
1076 inline void MultiLevelTransformation::LocalJacobian(Matrix &jac, double x, double y, double z, double t, double t0) const
1077 {
1078  this->Jacobian(0, -1, jac, x, y, z, t, t0);
1079 }
1080 
1081 // -----------------------------------------------------------------------------
1082 inline double MultiLevelTransformation::Jacobian(int m, int n, double x, double y, double z, double t, double t0) const
1083 {
1084  Matrix jac(3, 3);
1085  this->Jacobian(m, n, jac, x, y, z, t, t0);
1086  return jac.Det3x3();
1087 }
1088 
1089 // -----------------------------------------------------------------------------
1090 inline double MultiLevelTransformation::Jacobian(int n, double x, double y, double z, double t, double t0) const
1091 {
1092  return this->Jacobian(-1, n, x, y, z, t, t0);
1093 }
1094 
1095 // -----------------------------------------------------------------------------
1096 inline double MultiLevelTransformation::LocalJacobian(int n, double x, double y, double z, double t, double t0) const
1097 {
1098  return this->Jacobian(0, n, x, y, z, t, t0);
1099 }
1100 
1101 // -----------------------------------------------------------------------------
1102 inline void MultiLevelTransformation::Hessian(int, int, Matrix [3], double, double, double, double, double) const
1103 {
1104  cerr << this->NameOfClass() << "::Hessian(int, int,...): Not implemented" << endl;
1105  exit(1);
1106 }
1107 
1108 // -----------------------------------------------------------------------------
1109 inline void MultiLevelTransformation::Hessian(int n, Matrix hessian[3], double x, double y, double z, double t, double t0) const
1110 {
1111  this->Hessian(-1, n, hessian, x, y, z, t, t0);
1112 }
1113 
1114 // -----------------------------------------------------------------------------
1115 inline void MultiLevelTransformation::Hessian(Matrix hessian[3], double x, double y, double z, double t, double t0) const
1116 {
1117  this->Hessian(-1, -1, hessian, x, y, z, t, t0);
1118 }
1119 
1120 // -----------------------------------------------------------------------------
1121 inline void MultiLevelTransformation::GlobalHessian(Matrix hessian[3], double x, double y, double z, double t, double t0) const
1122 {
1123  this->GetGlobalTransformation()->Hessian(hessian, x, y, z, t, t0);
1124 }
1125 
1126 // -----------------------------------------------------------------------------
1127 inline void MultiLevelTransformation::LocalHessian(int n, Matrix hessian[3], double x, double y, double z, double t, double t0) const
1128 {
1129  this->Hessian(0, n, hessian, x, y, z, t, t0);
1130 }
1131 
1132 // -----------------------------------------------------------------------------
1133 inline void MultiLevelTransformation::LocalHessian(Matrix hessian[3], double x, double y, double z, double t, double t0) const
1134 {
1135  this->Hessian(0, -1, hessian, x, y, z, t, t0);
1136 }
1137 
1138 // -----------------------------------------------------------------------------
1139 inline void MultiLevelTransformation::DeriveJacobianWrtDOF(Matrix &jac, int dof, double x, double y, double z, double t, double t0) const
1140 {
1141  cerr << this->NameOfClass() << "::DeriveJacobianWrtDOF: Not implemented" << endl;
1142  exit(1);
1143 }
1144 
1145 // =============================================================================
1146 // Properties
1147 // =============================================================================
1148 
1149 // -----------------------------------------------------------------------------
1150 inline double MultiLevelTransformation::BendingEnergy(int m, int n, double x, double y, double z, double t, double t0, bool wrt_world) const
1151 {
1152  double bending = .0;
1153  const int l1 = (m < 0 ? 0 : m);
1154  const int l2 = (n < 0 || n > this->NumberOfLevels() ? this->NumberOfLevels() : n);
1155  for (int l = l1; l < l2; ++l) {
1156  bending += this->GetLocalTransformation(l)->BendingEnergy(x, y, z, t, t0, wrt_world);
1157  }
1158  return bending;
1159 }
1160 
1161 // -----------------------------------------------------------------------------
1162 inline double MultiLevelTransformation::BendingEnergy(int n, double x, double y, double z, double t, double t0, bool wrt_world) const
1163 {
1164  return this->BendingEnergy(0, n, x, y, z, t, t0, wrt_world);
1165 }
1166 
1167 // -----------------------------------------------------------------------------
1168 inline double MultiLevelTransformation::BendingEnergy(double x, double y, double z, double t, double t0, bool wrt_world) const
1169 {
1170  return this->BendingEnergy(0, -1, x, y, z, t, t0, wrt_world);
1171 }
1172 
1173 
1174 } // namespace mirtk
1175 
1176 #endif // MIRTK_MultiLevelTransformation_H
virtual DOFStatus GetStatus(int) const
Get status of transformation parameter.
virtual Cofstream & WriteDOFs(Cofstream &) const
Writes transformation parameters to a file stream.
virtual ParameterList Parameter() const
Get (non-DoF) parameters as key/value as string map.
virtual void LocalDisplacement(int, int, double &, double &, double &, double=0, double=NaN) const
Calculates the displacement of a single point using the local transformation component only...
virtual void LocalHessian(int, Matrix [3], double, double, double, double=0, double=NaN) const
Calculates the Hessian for each component of the local transformation w.r.t world coordinates...
virtual void Displacement(int, int, double &, double &, double &, double=0, double=NaN) const
Calculates the displacement of a single point.
virtual int NumberOfCPs(bool=false) const
Returns the total number of control points.
virtual FreeFormTransformation * PutLocalTransformation(FreeFormTransformation *, int, bool=true)
Put local transformation and return pointer to previous one (needs to be deleted if not used) ...
bool _LocalTransformationOwner[MAX_TRANS]
Whether this class is responsible for destructing the local transformation.
double Det3x3() const
Calculate determinant of a 3x3 matrix.
Definition: Matrix.h:1019
double DOFValue
Type of transformation parameter value.
virtual AffineTransformation * GetGlobalTransformation()
Gets global transformation.
virtual void GlobalJacobian(Matrix &, double, double, double, double=0, double=NaN) const
Calculates the Jacobian of the global transformation w.r.t world coordinates.
virtual void ApproximateDOFsGradient(const double *, const double *, const double *, const double *, const double *, const double *, const double *, int, double *, double=1.0) const
FFDStatus _LocalTransformationStatus[MAX_TRANS]
Status of local transformations.
virtual void MergeGlobalIntoLocalDisplacement()
virtual bool Set(const char *, const char *)
Set named (non-DoF) parameter from value as string.
virtual ParameterList Parameter() const
Get (non-DoF) parameters as key/value as string map.
virtual bool Inverse(double &, double &, double &, double=0, double=-1) const
Transforms a single point using the inverse of the transformation.
virtual bool RequiresCachingOfDisplacements() const
virtual void LocalJacobian(int, Matrix &, double, double, double, double=0, double=NaN) const
Calculates the Jacobian of the local transformation w.r.t world coordinates.
FreeFormTransformation * _LocalTransformation[MAX_TRANS]
Local transformations.
double _x
x coordinate of Point
Definition: Point.h:46
virtual bool LocalInverseDisplacement(double &, double &, double &, double=0, double=NaN) const
Calculates the displacement of a single point using the inverse of the local transformation only...
virtual int NumberOfDOFs() const
Get number of transformation parameters.
virtual double BendingEnergy(double, double, double, double=0, double=NaN, bool=true) const
Calculates the bending of the transformation.
virtual FreeFormTransformation * GetLocalTransformation(int)
Gets local transformation.
virtual void LocalDisplacement(double &, double &, double &, double=0, double=NaN) const
Calculates the displacement of a single point using the local transformation component only...
virtual void Hessian(int, int, Matrix [3], double, double, double, double=0, double=NaN) const
Calculates the Hessian for each component of the transformation w.r.t world coordinates.
virtual bool InverseDisplacement(int, int, double &, double &, double &, double=0, double=NaN) const
Calculates the displacement of a single point using the inverse of the transformation.
virtual bool CopyFrom(const Transformation *)
virtual bool IsIdentity() const
Checks whether transformation is an identity mapping.
virtual void CheckTransformation(FreeFormTransformation *) const
Checks whether a given transformation is supported as local transformation.
virtual bool LocalInverseDisplacement(int, int, double &, double &, double &, double=0, double=NaN) const
Calculates the displacement of a single point using the inverse of the local transformation only...
virtual bool InverseDisplacement(double &, double &, double &, double=0, double=NaN) const
Calculates the displacement of a single point using the inverse of the transformation.
Array< Pair< string, string > > ParameterList
Ordered list of parameter name/value pairs.
Definition: Object.h:38
virtual void InsertLocalTransformation(FreeFormTransformation *, int=0, bool=true)
Insert local transformation.
MultiLevelTransformation()
Default constructor.
virtual void GlobalHessian(Matrix [3], double, double, double, double=0, double=NaN) const
Calculates the Hessian for each component of the global transformation w.r.t world coordinates...
Status FFDStatus
Type of local transformation status.
Status
Enumeration of common states for entities such as objective function parameters.
Definition: Status.h:28
virtual void Clear()
Reset transformation and remove all local transformations.
Definition: IOConfig.h:41
virtual double Approximate(const ImageAttributes &, double *, double *, double *, int=1, double=.0)
void InterpolateGlobalDisplacement(FreeFormTransformation *)
Helper function for MergeGlobalIntoLocalDisplacement.
double GetTOrigin() const
Get temporal origin.
Definition: BaseImage.h:1082
virtual void Jacobian(Matrix &, double, double, double, double=0, double=NaN) const
Calculates the Jacobian of the transformation w.r.t world coordinates.
virtual void GlobalInverse(double &, double &, double &, double=0, double=NaN) const
Transforms a single point using the inverse of the global transformation only.
virtual bool HasSameDOFsAs(const Transformation *) const
Checks whether transformation depends on the same vector of parameters.
virtual int NumberOfActiveCPs() const
Returns the total number of active control points on all active levels.
virtual void Displacement(double &, double &, double &, double=0, double=NaN) const
Calculates the displacement of a single point.
virtual bool LocalTransformationIsActive(int) const
Get whether local transformation is active.
virtual double Update(const DOFValue *)
Update transformation parameters given parametric gradient.
virtual int NumberOfActiveLevels() const
Returns the number of active levels.
virtual double Get(int) const
Get value of transformation parameter.
virtual void Print(ostream &, Indent=0) const
Prints the parameters of the transformation.
virtual double BendingEnergy(int, int, double, double, double, double=0, double=NaN, bool=true) const
Calculates the bending energy of the transformation.
virtual void PutStatus(int, DOFStatus)
Put status of transformation parameter.
virtual Cifstream & ReadDOFs(Cifstream &, TransformationType)
Reads transformation parameters from a file stream.
virtual int NumberOfDOFs() const
Get number of transformation parameters.
virtual void ApproximateDOFs(const double *, const double *, const double *, const double *, const double *, const double *, const double *, int)
virtual bool LocalInverse(int, int, double &, double &, double &, double=0, double=NaN) const
Transforms a single point using the inverse of the local transformation only.
virtual void Transform(double &, double &, double &, double=0, double=NaN) const =0
Transforms a single point.
virtual int NumberOfLevels() const
Returns the number of levels.
virtual void PushLocalTransformation(FreeFormTransformation *, bool=true)
Push local transformation on stack (append transformation)
virtual void CombineLocalTransformation()
Combine local transformations on stack.
virtual const char * NameOfClass() const =0
Get name of class, which this object is an instance of.
void Size(int)
Definition: PointSet.h:434
virtual void Transform(double &, double &, double &, double=0, double=-1) const
Transforms a single point.
virtual int NumberOfPassiveLevels() const
Returns the number of passive levels.
virtual void JacobianDOFs(double [3], int, double, double, double, double=0, double=NaN) const
Calculates the Jacobian of the transformation w.r.t the transformation parameters.
virtual void Jacobian(int, int, Matrix &, double, double, double, double=0, double=NaN) const
Calculates the Jacobian of the transformation w.r.t world coordinates.
virtual bool RequiresCachingOfDisplacements() const
virtual ~MultiLevelTransformation()
Destructor.
virtual FreeFormTransformation * PopLocalTransformation()
Pop local transformation from stack (remove last transformation)
virtual double DOFGradientNorm(const double *) const
Get norm of the gradient vector.
virtual void Put(int, double)
Put value of transformation parameter.
int _NumberOfLevels
Number of local transformations.
virtual bool Inverse(int, int, double &, double &, double &, double=0, double=NaN) const
Transforms a single point using the inverse of the transformation.
double _z
z coordinate of Point
Definition: Point.h:48
virtual FreeFormTransformation * RemoveLocalTransformation(int=0)
Remove local transformation and return the pointer (need to be deleted if not used) ...
virtual bool Inverse(double &, double &, double &, double=0, double=NaN) const
Transforms a single point using the inverse of the transformation.
virtual void LocalTransform(int, int, double &, double &, double &, double=0, double=NaN) const
Transforms a single point using the local transformation component only.
virtual void Reset()
Reset transformation (does not remove local transformations)
AffineTransformation _GlobalTransformation
Global transformation.
virtual void Add(const DOFValue *)
Add change to transformation parameters.
double _y
y coordinate of Point
Definition: Point.h:47
virtual void LocalJacobian(Matrix &, double, double, double, double=0, double=NaN) const
Calculates the Jacobian of the local transformation w.r.t world coordinates.
virtual void GlobalTransform(double &, double &, double &, double=0, double=NaN) const
Transforms a single point using the global transformation component only.
virtual void DeriveJacobianWrtDOF(Matrix &, int, double, double, double, double=0, double=NaN) const
Calculates the derivative of the Jacobian of the transformation (w.r.t. world coordinates) w...
virtual void Transform(int, int, double &, double &, double &, double=0, double=NaN) const =0
Transforms a single point.
virtual double ApproximateAsNew(const ImageAttributes &, double *, double *, double *, int=1, double=.0)
virtual void GlobalJacobian(Matrix &, double, double, double, double=0, double=NaN) const
Calculates the Jacobian of the global transformation w.r.t world coordinates.
void Print(Indent=0) const
Prints information about the transformation.
virtual void Hessian(Matrix [3], double, double, double, double=0, double=NaN) const
Calculates the Hessian for each component of the transformation w.r.t world coordinates.
virtual void Jacobian(Matrix &, double, double, double, double=0, double=-1) const
Calculates the Jacobian of the transformation w.r.t world coordinates.
virtual void LocalTransformationStatus(int, FFDStatus)
Put status of local transformation.