PointSetDistance.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2015 Imperial College London
5  * Copyright 2013-2015 Andreas Schuh
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MIRTK_PointSetDistance_H
21 #define MIRTK_PointSetDistance_H
22 
23 #include "mirtk/DataFidelity.h"
24 
25 #include "mirtk/Array.h"
26 #include "mirtk/Vector3D.h"
27 #include "mirtk/PointSetDistanceMeasure.h"
28 #include "mirtk/RegisteredPointSet.h"
29 
30 
31 namespace mirtk {
32 
33 
34 /**
35  * Base class for point set distance measures
36  */
38 {
39  mirtkAbstractMacro(PointSetDistance);
40 
41  // ---------------------------------------------------------------------------
42  // Types
43 public:
44 
45  /// Type of gradient w.r.t a single transformed data point
47 
48  // ---------------------------------------------------------------------------
49  // Attributes
50 protected:
51 
52  /// First point set
54 
55  /// Second point set
57 
58  /// Memory for (non-parametric) gradient w.r.t points of target
59  mirtkComponentMacro(GradientType, GradientWrtTarget);
60 
61  /// Memory for (non-parametric) gradient w.r.t points of source
62  mirtkComponentMacro(GradientType, GradientWrtSource);
63 
64  /// Whether Update has not been called since initialization
65  mirtkAttributeMacro(bool, InitialUpdate);
66 
67  /// Allocate memory for (non-parametric) gradient w.r.t points of target
68  void AllocateGradientWrtTarget(int);
69 
70  /// Allocate memory for (non-parametric) gradient w.r.t points of source
71  void AllocateGradientWrtSource(int);
72 
73  // ---------------------------------------------------------------------------
74  // Construction/Destruction
75 protected:
76 
77  /// Constructor
78  PointSetDistance(const char * = "", double = 1.0);
79 
80  /// Copy constructor
81  PointSetDistance(const PointSetDistance &, int = -1, int = -1);
82 
83  /// Assignment operator
85 
86  /// Copy attributes from other point set distance measure
87  void CopyAttributes(const PointSetDistance &, int = -1, int = -1);
88 
89 public:
90 
91  /// Instantiate specified similarity measure
93  const char * = "", double = 1.0);
94 
95  /// Destructor
96  virtual ~PointSetDistance();
97 
98  // ---------------------------------------------------------------------------
99  // Initialization
100 
101 protected:
102 
103  /// Initialize distance measure once input and parameters have been set
104  void Initialize(int, int);
105 
106  /// Reinitialize distance measure after change of input topology
107  ///
108  /// This function is called in particular when an input surface has been
109  /// reparameterized, e.g., by a local remeshing filter.
110  void Reinitialize(int, int);
111 
112 public:
113 
114  /// Initialize distance measure once input and parameters have been set
115  virtual void Initialize();
116 
117  /// Reinitialize distance measure after change of input topology
118  ///
119  /// This function is called in particular when an input surface has been
120  /// reparameterized, e.g., by a local remeshing filter.
121  virtual void Reinitialize();
122 
123  // ---------------------------------------------------------------------------
124  // Evaluation
125 
126  /// Update moving input points and internal state of distance measure
127  virtual void Update(bool = true);
128 
129 protected:
130 
131  /// Compute non-parametric gradient w.r.t points of given data set
132  ///
133  /// \param[in] target Transformed point set.
134  /// \param[out] gradient Non-parametric gradient of point set distance measure.
135  virtual void NonParametricGradient(const RegisteredPointSet *target,
136  GradientType *gradient) = 0;
137 
138  /// Convert non-parametric gradient of point set distance measure into
139  /// gradient w.r.t transformation parameters
140  ///
141  /// This function calls Transformation::ParametricGradient of the
142  /// transformation to apply the chain rule in order to obtain the gradient
143  /// of the distance measure w.r.t the transformation parameters.
144  /// It adds the weighted gradient to the final registration energy gradient.
145  ///
146  /// \param[in] target Transformed point set.
147  /// \param[in] np_gradient Point-wise non-parametric gradient.
148  /// \param[in,out] gradient Gradient to which the computed parametric gradient
149  /// is added, after multiplication by the given \p weight.
150  /// \param[in] weight Weight of point set distance measure.
151  virtual void ParametricGradient(const RegisteredPointSet *target,
152  const GradientType *np_gradient,
153  double *gradient,
154  double weight);
155 
156  /// Evaluate gradient of point set distance measure
157  ///
158  /// This function calls the virtual NonParametricGradient function to be
159  /// implemented by subclasses for each transformed input point set to obtain
160  /// the gradient of the point set distance measure. It then converts this gradient
161  /// into a gradient w.r.t the transformation parameters using the ParametricGradient.
162  ///
163  /// If both target and source point sets are transformed by different transformations,
164  /// the resulting gradient vector contains first the derivative values w.r.t
165  /// the parameters of the target transformation followed by those computed
166  /// w.r.t the parameters of the source transformation. If both point sets are
167  /// transformed by the same transformation, the sum of the derivative values
168  /// is added to the resulting gradient vector. This is in particular the case
169  /// for a velocity based transformation model which is applied to deform both
170  /// point sets "mid-way". Otherwise, only one input point set is transformed
171  /// (usually the target) and the derivative values of only the respective
172  /// transformation parameters added to the gradient vector.
173  ///
174  /// \sa NonParametricGradient, ParametricGradient
175  ///
176  /// \param[in,out] gradient Gradient to which the computed gradient of the
177  /// point set distance measure is added after
178  /// multiplying by the given similarity \p weight.
179  /// \param[in] step Step length for finite differences (unused).
180  /// \param[in] weight Weight of point set distance measure.
181  virtual void EvaluateGradient(double *gradient, double step, double weight);
182 
183  // ---------------------------------------------------------------------------
184  // Debugging
185 public:
186 
187  /// Write input of data fidelity term
188  virtual void WriteDataSets(const char *, const char *, bool = true) const;
189 
190  /// Write gradient of data fidelity term w.r.t each transformed input
191  virtual void WriteGradient(const char *, const char *) const;
192 
193 protected:
194 
195  /// Write gradient of data fidelity term w.r.t each transformed input
196  virtual void WriteGradient(const char *,
197  const RegisteredPointSet *,
198  const GradientType *,
199  const Array<int> * = NULL) const;
200 
201 };
202 
203 
204 } // namespace mirtk
205 
206 #endif // MIRTK_PointSetDistance_H
Vector3D< double > GradientType
Type of gradient w.r.t a single transformed data point.
void AllocateGradientWrtTarget(int)
Allocate memory for (non-parametric) gradient w.r.t points of target.
virtual void Reinitialize()
virtual ~PointSetDistance()
Destructor.
virtual void ParametricGradient(const RegisteredPointSet *target, const GradientType *np_gradient, double *gradient, double weight)
virtual void WriteGradient(const char *, const char *) const
Write gradient of data fidelity term w.r.t each transformed input.
void CopyAttributes(const PointSetDistance &, int=-1, int=-1)
Copy attributes from other point set distance measure.
virtual void Initialize()
Initialize distance measure once input and parameters have been set.
mirtkPublicAggregateMacro(RegisteredPointSet, Target)
First point set.
Definition: IOConfig.h:41
static PointSetDistance * New(PointSetDistanceMeasure, const char *="", double=1.0)
Instantiate specified similarity measure.
virtual void EvaluateGradient(double *gradient, double step, double weight)
mirtkAttributeMacro(bool, InitialUpdate)
Whether Update has not been called since initialization.
mirtkComponentMacro(GradientType, GradientWrtTarget)
Memory for (non-parametric) gradient w.r.t points of target.
virtual void NonParametricGradient(const RegisteredPointSet *target, GradientType *gradient)=0
void AllocateGradientWrtSource(int)
Allocate memory for (non-parametric) gradient w.r.t points of source.
PointSetDistance & operator=(const PointSetDistance &)
Assignment operator.
PointSetDistance(const char *="", double=1.0)
Constructor.
virtual void Update(bool=true)
Update moving input points and internal state of distance measure.
virtual void WriteDataSets(const char *, const char *, bool=true) const
Write input of data fidelity term.