ScalingAndSquaring.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2017 Imperial College London
5  * Copyright 2013-2017 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_ScalingAndSquaring_H
21 #define MIRTK_ScalingAndSquaring_H
22 
23 #include "mirtk/Object.h"
24 #include "mirtk/GenericImage.h"
25 #include "mirtk/InterpolateImageFunction.h"
26 #include "mirtk/LinearInterpolateImageFunction.h"
27 #include "mirtk/FastCubicBSplineInterpolateImageFunction.h"
28 
29 
30 namespace mirtk {
31 
32 
33 /**
34  * Computes the exponential map of a SVF and its derivatives
35  *
36  * This class implements an image filter which computes the exponential map
37  * of a stationary velocity field using the scaling and squaring method.
38  * The result is a diffeomorphic displacement field. Additionally, this filter
39  * computes also the derivatives of the exponential map with respect to the
40  * spatial coordinate.
41  *
42  * The exponentiation of a voxel-based image similarity gradient follows the
43  * computation outlined in Modat et al., "Parametric non-rigid registration
44  * using a stationary velocity field", MMBIA, 145–150, 2012. See also the
45  * derivation in the appendix of Ashburner, "A fast diffeomorphic
46  * image registration algorithm", NeuroImage, 38(1), 95–113, 2007.
47  *
48  * This image filter is in particular used by the BSplineFreeFormTransformationSV
49  * class of the Transformation module.
50  */
51 template <class TReal>
52 class ScalingAndSquaring : public Object
53 {
54  mirtkObjectMacro(ScalingAndSquaring);
55 
56  // ---------------------------------------------------------------------------
57  // Types
58 
59 public:
60 
61  /// Image type of input, output, and intermediate images
63 
64  /// Type of image extrapolation function
66 
67  /// Type of vector field interpolator
69 
70  /// Type of input velocity field interpolator
72 
73 private:
74 
75  // ---------------------------------------------------------------------------
76  // Input
77 
78  /// Input velocity field
79  mirtkPublicAggregateMacro(const ImageType, InputVelocity);
80 
81  /// Input displacement field
82  mirtkPublicAggregateMacro(const ImageType, InputDisplacement);
83 
84  /// Input deformation field
85  mirtkPublicAggregateMacro(const ImageType, InputDeformation);
86 
87  /// Input image of partial derivatives w.r.t. deformation generated by the velocity field
88  mirtkPublicAggregateMacro(const ImageType, InputGradient);
89 
90  // ---------------------------------------------------------------------------
91  // Interim
92 
93  /// Intermediate displacement field
94  mirtkReadOnlyAttributeMacro(UniquePtr<ImageType>, InterimDisplacement);
95 
96  /// Intermediate Jacobian w.r.t. x
97  mirtkReadOnlyAttributeMacro(UniquePtr<ImageType>, InterimJacobian);
98 
99  /// Intermediate determinant of Jacobian w.r.t. x
100  mirtkReadOnlyAttributeMacro(UniquePtr<ImageType>, InterimDetJacobian);
101 
102  /// Intermediate log of determinant of Jacobian w.r.t. x
103  mirtkReadOnlyAttributeMacro(UniquePtr<ImageType>, InterimLogJacobian);
104 
105  // ---------------------------------------------------------------------------
106  // Output
107 
108  /// Output displacement field
109  mirtkPublicAggregateMacro(ImageType, OutputDisplacement);
110 
111  /// Output deformation field
112  mirtkPublicAggregateMacro(ImageType, OutputDeformation);
113 
114  /// Jacobian of output deformation field w.r.t. x
115  mirtkPublicAggregateMacro(ImageType, OutputJacobian);
116 
117  /// Determinant of Jacobian of output deformation field w.r.t. x
118  mirtkPublicAggregateMacro(ImageType, OutputDetJacobian);
119 
120  /// Log of determinant of Jacobian of output deformation field w.r.t. x
121  mirtkPublicAggregateMacro(ImageType, OutputLogJacobian);
122 
123  /// Output image of partial derivatives w.r.t. v
124  mirtkPublicAggregateMacro(ImageType, OutputGradient);
125 
126  // ---------------------------------------------------------------------------
127  // Settings
128 
129  /// Attributes of intermediate images, defaults to output attributes
130  mirtkPublicAttributeMacro(ImageAttributes, InterimAttributes);
131 
132  /// Attributes of output images, defaults to input attributes
133  mirtkPublicAttributeMacro(ImageAttributes, OutputAttributes);
134 
135  /// Whether to compute interpolation coefficients from the given input.
136  /// Set to \c false if the input is the coefficient image.
137  ///
138  /// \note The input velocity field is currently always interpolated using
139  /// the cubic B-spline interpolation mode. Thus, when this flag is
140  /// set to \c true, the input velocity field must contain the
141  /// coefficients of the respective cubic B-spline function.
142  mirtkPublicAttributeMacro(bool, ComputeInterpolationCoefficients);
143 
144  /// Whether filter should invert the velocities
145  ///
146  /// This is equivalent to changing the sign of the upper integration limit.
147  /// Settings this option to \c true can be used to highlight that the inverse
148  /// is computed or to switch between forward and backward mapping without
149  /// changing the integration interval.
150  mirtkPublicAttributeMacro(bool, ComputeInverse);
151 
152  /// Upper integration limit (negative <=> inverse)
153  mirtkPublicAttributeMacro(double, UpperIntegrationLimit);
154 
155  /// Number of integration steps
156  ///
157  /// When _MaxScaledVelocity is positive, the number of steps may be increased
158  /// by this filter if necessary. After filter execution, this attribute is
159  /// set to the used number of steps.
160  mirtkPublicAttributeMacro(int, NumberOfSteps);
161 
162  /// Number of squaring steps
163  ///
164  /// When not set or non-positive, respectively, this attribute is set to the
165  /// number of squaring steps required for the specified number of integration
166  /// steps, i.e., iceil(log(_NumberOfSteps) / log(2)). Otherwise, this attribute
167  /// overrides the specified number of integration steps, which are set to
168  /// pow(2, _NumberOfSquaringSteps) after filter execution.
169  mirtkPublicAttributeMacro(int, NumberOfSquaringSteps);
170 
171  /// Maximum velocity after scaling
172  ///
173  /// Set to zero in order to scale velocities by exactly
174  /// pow(2.0, _NumberOfSquaringSteps). Otherwise, the number of squaring steps
175  /// is increased in order to ensure that the maximum velocity in each
176  /// dimension is less or equal the specified value.
177  mirtkPublicAttributeMacro(double, MaxScaledVelocity);
178 
179  /// Whether to upsample the input velocity field
180  mirtkPublicAttributeMacro(bool, Upsample);
181 
182  /// Whether to use a Gaussian pyramid downsampler when downsampling the
183  /// previously upsampled output fields to obey Shannon's sampling theorem.
184  /// Otherwise a simple interpolation without smoothing kernel is used.
185  mirtkPublicAttributeMacro(bool, SmoothBeforeDownsampling);
186 
187  // ---------------------------------------------------------------------------
188  // Construction/Destruction
189 
190 public:
191 
192  /// Constructor
194 
195  /// Destructor
196  virtual ~ScalingAndSquaring();
197 
198  // ---------------------------------------------------------------------------
199  // Evaluation
200 
201 protected:
202 
203  /// Initialize filter
204  virtual void Initialize();
205 
206  /// Finalize filter
207  virtual void Finalize();
208 
209  /// Resample intermediate filter output
210  void Resample(ImageType *, ImageType *, bool = false);
211 
212  /// Finalize output displacement field
213  void FinalizeDisplacement();
214 
215  /// Finalize output Jacobian field
216  void FinalizeJacobian();
217 
218  /// Finalize output Jacobian determinants
219  void FinalizeDetJacobian();
220 
221  /// Finalize log-transformed output Jacobian determinants
222  void FinalizeLogJacobian();
223 
224 public:
225 
226  /// Compute output deformation/displacement field and its derivatives
227  virtual void Run();
228 
229 };
230 
231 
232 } // namespace mirtk
233 
234 #endif // MIRTK_ScalingAndSquaring_H
void FinalizeJacobian()
Finalize output Jacobian field.
GenericNearestNeighborExtrapolateImageFunction< ImageType > Extrapolator
Type of image extrapolation function.
void FinalizeDisplacement()
Finalize output displacement field.
ScalingAndSquaring()
Constructor.
void FinalizeLogJacobian()
Finalize log-transformed output Jacobian determinants.
GenericLinearInterpolateImageFunction< ImageType > VectorField
Type of vector field interpolator.
virtual void Finalize()
Finalize filter.
GenericImage< TReal > ImageType
Image type of input, output, and intermediate images.
Definition: IOConfig.h:41
void FinalizeDetJacobian()
Finalize output Jacobian determinants.
virtual ~ScalingAndSquaring()
Destructor.
GenericFastCubicBSplineInterpolateImageFunction< ImageType > VelocityField
Type of input velocity field interpolator.
virtual void Initialize()
Initialize filter.
virtual void Run()
Compute output deformation/displacement field and its derivatives.
void Resample(ImageType *, ImageType *, bool=false)
Resample intermediate filter output.