CubicBSplineInterpolateImageFunction.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_CubicBSplineInterpolateImageFunction_H
21 #define MIRTK_CubicBSplineInterpolateImageFunction_H
22 
23 #include "mirtk/BSpline.h"
24 #include "mirtk/BaseImage.h"
25 #include "mirtk/InterpolateImageFunction.h"
26 #include "mirtk/MirrorExtrapolateImageFunction.h"
27 
28 
29 namespace mirtk {
30 
31 
32 /**
33  * Cubic B-spline interpolation of generic image
34  *
35  * Note that the coefficient, i.e., input voxel type may also be a vector
36  * type such as Vector3D in particular. This is required by the B-spline
37  * free-form transformations. If the input image contains the cubic B-spline
38  * interpolation coefficients already, make sure that the VoxelType template
39  * argument matches the voxel type of the input image to avoid an unnecessary
40  * copy of the input image. This image function will use the memory of the
41  * input image directly to access the coefficients in this case.
42  */
43 template <class TImage>
45 : public GenericInterpolateImageFunction<TImage>
46 {
47  mirtkGenericInterpolatorMacro(
49  Interpolation_CubicBSpline
50  );
51 
52  // ---------------------------------------------------------------------------
53  // Types
54 
55 public:
56 
60  typedef BSpline<Real> Kernel;
61 
62  // ---------------------------------------------------------------------------
63  // Attributes
64 
65  /// Input image contains spline coefficients
66  mirtkAttributeMacro(bool, UseInputCoefficients);
67 
68  /// Image of spline coefficients
69  mirtkAttributeMacro(CoefficientImage, Coefficient);
70 
71  /// Infinite discrete coefficient image obtained by extrapolation
72  mirtkAggregateMacro(CoefficientExtrapolator, InfiniteCoefficient);
73 
74 protected:
75 
76  /// Strides for fast iteration over coefficient image
77  int _s2, _s3, _s4;
78 
79 public:
80 
81  // ---------------------------------------------------------------------------
82  // Construction/Destruction
83 
84  /// Constructor
86 
87  /// Destructor
89 
90  /// Initialize image function
91  virtual void Initialize(bool = false);
92 
93  /// Update spline coefficients
94  virtual void Update();
95 
96  // ---------------------------------------------------------------------------
97  // Domain checks
98 
99  /// Returns interval of discrete image indices whose values are needed for
100  /// interpolation of the image value at a given continuous coordinate
101  virtual void BoundingInterval(double, int &, int &) const;
102 
103  // ---------------------------------------------------------------------------
104  // Evaluation
105 
106  /// Get value of given 2D image at arbitrary location (in pixels)
107  ///
108  /// This function is used to interpolate the image value at arbitrary
109  /// locations when no extrapolator was set.
110  VoxelType Get2D(double, double, double = 0, double = 0) const;
111 
112  /// Get value of given 2D image at arbitrary location (in pixels)
113  ///
114  /// This function is used to only interpolate foreground image values.
115  /// If fully outside the foreground region, the _DefaultValue is returned.
116  VoxelType GetWithPadding2D(double, double, double = 0, double = 0) const;
117 
118  /// Get value of given 2D image at arbitrary location (in pixels)
119  ///
120  /// If the location is inside the finite domain of the image, an actual image
121  /// instance can be passed as first argument directly such as an instance of
122  /// GenericImage. Otherwise, an image function which extends the finite
123  /// image domain to an infinite lattice is needed, i.e., an instance of a
124  /// subclass of ExtrapolateImageFunction.
125  template <class TOtherImage> typename TOtherImage::VoxelType
126  Get2D(const TOtherImage *, double, double, double = 0, double = 0) const;
127 
128  /// Get value of given 2D image at arbitrary location (in pixels)
129  ///
130  /// This function is used to only interpolate foreground image values.
131  /// If fully outside the foreground region, the _DefaultValue is returned.
132  ///
133  /// If the location is inside the finite domain of the image, an actual image
134  /// instance can be passed as first argument directly such as an instance of
135  /// GenericImage. Otherwise, an image function which extends the finite
136  /// image domain to an infinite lattice is needed, i.e., an instance of a
137  /// subclass of ExtrapolateImageFunction.
138  template <class TOtherImage, class TCoefficient> typename TCoefficient::VoxelType
139  GetWithPadding2D(const TOtherImage *, const TCoefficient *,
140  double, double, double = 0, double = 0) const;
141 
142  /// Get value of given 3D image at arbitrary location (in pixels)
143  ///
144  /// This function is used to interpolate the image value at arbitrary
145  /// locations when no extrapolator was set.
146  VoxelType Get3D(double, double, double = 0, double = 0) const;
147 
148  /// Get value of given 3D image at arbitrary location (in pixels)
149  ///
150  /// This function is used to only interpolate foreground image values.
151  /// If fully outside the foreground region, the _DefaultValue is returned.
152  VoxelType GetWithPadding3D(double, double, double = 0, double = 0) const;
153 
154  /// Get value of given 3D image at arbitrary location (in pixels)
155  ///
156  /// If the location is inside the finite domain of the image, an actual image
157  /// instance can be passed as first argument directly such as an instance of
158  /// GenericImage. Otherwise, an image function which extends the finite
159  /// image domain to an infinite lattice is needed, i.e., an instance of a
160  /// subclass of ExtrapolateImageFunction.
161  template <class TOtherImage> typename TOtherImage::VoxelType
162  Get3D(const TOtherImage *, double, double, double = 0, double = 0) const;
163 
164  /// Get value of given 3D image at arbitrary location (in pixels)
165  ///
166  /// This function is used to only interpolate foreground image values.
167  /// If fully outside the foreground region, the _DefaultValue is returned.
168  ///
169  /// If the location is inside the finite domain of the image, an actual image
170  /// instance can be passed as first argument directly such as an instance of
171  /// GenericImage. Otherwise, an image function which extends the finite
172  /// image domain to an infinite lattice is needed, i.e., an instance of a
173  /// subclass of ExtrapolateImageFunction.
174  template <class TOtherImage, class TCoefficient> typename TCoefficient::VoxelType
175  GetWithPadding3D(const TOtherImage *, const TCoefficient *,
176  double, double, double = 0, double = 0) const;
177 
178  /// Get value of given 4D image at arbitrary location (in pixels)
179  ///
180  /// This function is used to interpolate the image value at arbitrary
181  /// locations when no extrapolator was set.
182  VoxelType Get4D(double, double, double = 0, double = 0) const;
183 
184  /// Get value of given 4D image at arbitrary location (in pixels)
185  ///
186  /// This function is used to only interpolate foreground image values.
187  /// If fully outside the foreground region, the _DefaultValue is returned.
188  VoxelType GetWithPadding4D(double, double, double = 0, double = 0) const;
189 
190  /// Get value of given 4D image at arbitrary location (in pixels)
191  ///
192  /// If the location is inside the finite domain of the image, an actual image
193  /// instance can be passed as first argument directly such as an instance of
194  /// GenericImage. Otherwise, an image function which extends the finite
195  /// image domain to an infinite lattice is needed, i.e., an instance of a
196  /// subclass of ExtrapolateImageFunction.
197  template <class TOtherImage> typename TOtherImage::VoxelType
198  Get4D(const TOtherImage *, double, double, double = 0, double = 0) const;
199 
200  /// Get value of given 4D image at arbitrary location (in pixels)
201  ///
202  /// This function is used to only interpolate foreground image values.
203  /// If fully outside the foreground region, the _DefaultValue is returned.
204  ///
205  /// If the location is inside the finite domain of the image, an actual image
206  /// instance can be passed as first argument directly such as an instance of
207  /// GenericImage. Otherwise, an image function which extends the finite
208  /// image domain to an infinite lattice is needed, i.e., an instance of a
209  /// subclass of ExtrapolateImageFunction.
210  template <class TOtherImage, class TCoefficient> typename TCoefficient::VoxelType
211  GetWithPadding4D(const TOtherImage *, const TCoefficient *,
212  double, double, double = 0, double = 0) const;
213 
214  /// Get value of given image at arbitrary location (in pixels)
215  ///
216  /// This function is used to interpolate the image value at arbitrary
217  /// locations when no extrapolator was set.
218  VoxelType Get(double, double, double = 0, double = 0) const;
219 
220  /// Get value of given image at arbitrary location (in pixels)
221  ///
222  /// This function is used to only interpolate foreground image values.
223  /// If fully outside the foreground region, the _DefaultValue is returned.
224  virtual VoxelType GetWithPadding(double, double, double = 0, double = 0) const;
225 
226  /// Get value of given image at arbitrary location (in pixels)
227  ///
228  /// If the location is inside the finite domain of the image, an actual image
229  /// instance can be passed as first argument directly such as an instance of
230  /// GenericImage. Otherwise, an image function which extends the finite
231  /// image domain to an infinite lattice is needed, i.e., an instance of a
232  /// subclass of ExtrapolateImageFunction.
233  template <class TOtherImage> typename TOtherImage::VoxelType
234  Get(const TOtherImage *, double, double, double = 0, double = 0) const;
235 
236  /// Get value of given image at arbitrary location (in pixels)
237  ///
238  /// This function is used to only interpolate foreground image values.
239  /// If fully outside the foreground region, the _DefaultValue is returned.
240  ///
241  /// If the location is inside the finite domain of the image, an actual image
242  /// instance can be passed as first argument directly such as an instance of
243  /// GenericImage. Otherwise, an image function which extends the finite
244  /// image domain to an infinite lattice is needed, i.e., an instance of a
245  /// subclass of ExtrapolateImageFunction.
246  template <class TOtherImage, class TCoefficient> typename TCoefficient::VoxelType
247  GetWithPadding(const TOtherImage *, const TCoefficient *,
248  double, double, double = 0, double = 0) const;
249 
250  /// Evaluate generic 2D image without handling boundary conditions
251  virtual VoxelType GetInside2D(double, double, double = 0, double = 0) const;
252 
253  /// Evaluate generic 3D image without handling boundary conditions
254  virtual VoxelType GetInside3D(double, double, double = 0, double = 0) const;
255 
256  /// Evaluate generic 4D image without handling boundary conditions
257  virtual VoxelType GetInside4D(double, double, double = 0, double = 0) const;
258 
259  /// Evaluate generic image without handling boundary conditions
260  ///
261  /// This version is faster than EvaluateOutside, but is only defined inside
262  /// the domain for which all image values required for interpolation are
263  /// defined and thus require no extrapolation of the finite image.
264  virtual VoxelType GetInside(double, double, double = 0, double = 0) const;
265 
266  /// Evaluate generic image at an arbitrary location (in pixels)
267  virtual VoxelType GetOutside(double, double, double = 0, double = 0) const;
268 
269  /// Evaluate generic image without handling boundary conditions
270  ///
271  /// This function is used to only interpolate foreground image values.
272  /// If fully outside the foreground region, the _DefaultValue is returned.
273  ///
274  /// This version is faster than GetWithPaddingOutside, but is only defined
275  /// inside the domain for which all image values required for interpolation
276  /// are defined and thus require no extrapolation of the finite image.
277  virtual VoxelType GetWithPaddingInside(double, double, double = 0, double = 0) const;
278 
279  /// Evaluate generic image at an arbitrary location (in pixels)
280  ///
281  /// This function is used to only interpolate foreground image values.
282  /// If fully outside the foreground region, the _DefaultValue is returned.
283  virtual VoxelType GetWithPaddingOutside(double, double, double = 0, double = 0) const;
284 
285 };
286 
287 /**
288  * Cubic B-spline interpolation of any scalar image
289  */
292 {
293  mirtkObjectMacro(CubicBSplineInterpolateImageFunction);
294 
295 public:
296 
297  /// Constructor
299 
300 };
301 
302 
303 } // namespace mirtk
304 
305 #endif // MIRTK_CubicBSplineInterpolateImageFunction_H
virtual VoxelType GetInside2D(double, double, double=0, double=0) const
Evaluate generic 2D image without handling boundary conditions.
VoxelType Get(double, double, double=0, double=0) const
virtual VoxelType GetInside4D(double, double, double=0, double=0) const
Evaluate generic 4D image without handling boundary conditions.
virtual VoxelType GetWithPaddingInside(double, double, double=0, double=0) const
Definition: IOConfig.h:41
mirtkAttributeMacro(bool, UseInputCoefficients)
Input image contains spline coefficients.
virtual VoxelType GetInside(double, double, double=0, double=0) const
VoxelType Get2D(double, double, double=0, double=0) const
VoxelType GetWithPadding3D(double, double, double=0, double=0) const
virtual VoxelType GetWithPadding(double, double, double=0, double=0) const
VoxelType Get4D(double, double, double=0, double=0) const
virtual VoxelType GetWithPaddingOutside(double, double, double=0, double=0) const
VoxelType Get3D(double, double, double=0, double=0) const
VoxelType GetWithPadding4D(double, double, double=0, double=0) const
int _s2
Strides for fast iteration over coefficient image.
virtual VoxelType GetOutside(double, double, double=0, double=0) const
Evaluate generic image at an arbitrary location (in pixels)
VoxelType GetWithPadding2D(double, double, double=0, double=0) const
mirtkAggregateMacro(CoefficientExtrapolator, InfiniteCoefficient)
Infinite discrete coefficient image obtained by extrapolation.
virtual VoxelType GetInside3D(double, double, double=0, double=0) const
Evaluate generic 3D image without handling boundary conditions.