LinearInterpolateImageFunction.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_LinearInterpolateImageFunction_H
21 #define MIRTK_LinearInterpolateImageFunction_H
22 
23 #include "mirtk/InterpolateImageFunction.h"
24 #include "mirtk/BaseImage.h"
25 
26 
27 namespace mirtk {
28 
29 
30 /**
31  * Linear interpolation of generic image
32  */
33 template <class TImage>
35 : public GenericInterpolateImageFunction<TImage>
36 {
37  mirtkGenericInterpolatorMacro(
39  Interpolation_Linear
40  );
41 
42  /// Offsets for fast pixel access
43  int _Offset[16];
44 
45 public:
46 
47  // ---------------------------------------------------------------------------
48  // Construction/Destruction
49 
50  /// Default constructor
52 
53  /// Destructor
55 
56  /// Initialize interpolation function
57  virtual void Initialize(bool = false);
58 
59  // ---------------------------------------------------------------------------
60  // Linear interpolation weights
61 
62  /// Returns truncated integral part of floating point
63  ///
64  /// \param[in] x Floating point number.
65  /// \param[out] w Linear interpolation weights for closest lattice nodes.
66  static int ComputeWeights(double, Real[2]);
67 
68  // ---------------------------------------------------------------------------
69  // Domain checks
70 
71  /// Returns interval of discrete image indices whose values are needed for
72  /// interpolation of the image value at a given continuous coordinate
73  virtual void BoundingInterval(double, int &, int &) const;
74 
75  // ---------------------------------------------------------------------------
76  // Evaluation
77 
78  /// Get value of given 2D image at arbitrary location (in pixels)
79  ///
80  /// This function is used to interpolate the image value at arbitrary
81  /// locations when no extrapolator was set.
82  VoxelType Get2D(double, double, double = 0, double = 0) const;
83 
84  /// Get value of given 2D image at arbitrary location (in pixels)
85  ///
86  /// This function is used to only interpolate foreground image values.
87  /// If fully outside the foreground region, the _DefaultValue is returned.
88  VoxelType GetWithPadding2D(double, double, double = 0, double = 0) const;
89 
90  /// Get value of given 2D image at arbitrary location (in pixels)
91  ///
92  /// If the location is inside the finite domain of the image, an actual image
93  /// instance can be passed as first argument directly such as an instance of
94  /// GenericImage. Otherwise, an image function which extends the finite
95  /// image domain to an infinite lattice is needed, i.e., an instance of a
96  /// subclass of ExtrapolateImageFunction.
97  template <class TOtherImage> typename TOtherImage::VoxelType
98  Get2D(const TOtherImage *, double, double, double = 0, double = 0) const;
99 
100  /// Get value of given 2D image at arbitrary location (in pixels)
101  ///
102  /// This function is used to only interpolate foreground image values.
103  /// If fully outside the foreground region, the _DefaultValue is returned.
104  ///
105  /// If the location is inside the finite domain of the image, an actual image
106  /// instance can be passed as first argument directly such as an instance of
107  /// GenericImage. Otherwise, an image function which extends the finite
108  /// image domain to an infinite lattice is needed, i.e., an instance of a
109  /// subclass of ExtrapolateImageFunction.
110  template <class TOtherImage> typename TOtherImage::VoxelType
111  GetWithPadding2D(const TOtherImage *, double, double, double = 0, double = 0) const;
112 
113  /// Get value of given 3D image at arbitrary location (in pixels)
114  ///
115  /// This function is used to interpolate the image value at arbitrary
116  /// locations when no extrapolator was set.
117  VoxelType Get3D(double, double, double = 0, double = 0) const;
118 
119  /// Get value of given 3D image at arbitrary location (in pixels)
120  ///
121  /// This function is used to only interpolate foreground image values.
122  /// If fully outside the foreground region, the _DefaultValue is returned.
123  VoxelType GetWithPadding3D(double, double, double = 0, double = 0) const;
124 
125  /// Get value of given 3D image at arbitrary location (in pixels)
126  ///
127  /// If the location is inside the finite domain of the image, an actual image
128  /// instance can be passed as first argument directly such as an instance of
129  /// GenericImage. Otherwise, an image function which extends the finite
130  /// image domain to an infinite lattice is needed, i.e., an instance of a
131  /// subclass of ExtrapolateImageFunction.
132  template <class TOtherImage> typename TOtherImage::VoxelType
133  Get3D(const TOtherImage *, double, double, double = 0, double = 0) const;
134 
135  /// Get value of given 3D image at arbitrary location (in pixels)
136  ///
137  /// This function is used to only interpolate foreground image values.
138  /// If fully outside the foreground region, the _DefaultValue is returned.
139  ///
140  /// If the location is inside the finite domain of the image, an actual image
141  /// instance can be passed as first argument directly such as an instance of
142  /// GenericImage. Otherwise, an image function which extends the finite
143  /// image domain to an infinite lattice is needed, i.e., an instance of a
144  /// subclass of ExtrapolateImageFunction.
145  template <class TOtherImage> typename TOtherImage::VoxelType
146  GetWithPadding3D(const TOtherImage *, 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 interpolate the image value at arbitrary
151  /// locations when no extrapolator was set.
152  VoxelType Get4D(double, double, double = 0, double = 0) const;
153 
154  /// Get value of given 4D image at arbitrary location (in pixels)
155  ///
156  /// This function is used to only interpolate foreground image values.
157  /// If fully outside the foreground region, the _DefaultValue is returned.
158  VoxelType GetWithPadding4D(double, double, double = 0, double = 0) const;
159 
160  /// Get value of given 4D image at arbitrary location (in pixels)
161  ///
162  /// If the location is inside the finite domain of the image, an actual image
163  /// instance can be passed as first argument directly such as an instance of
164  /// GenericImage. Otherwise, an image function which extends the finite
165  /// image domain to an infinite lattice is needed, i.e., an instance of a
166  /// subclass of ExtrapolateImageFunction.
167  template <class TOtherImage> typename TOtherImage::VoxelType
168  Get4D(const TOtherImage *, double, double, double = 0, double = 0) const;
169 
170  /// Get value of given 4D image at arbitrary location (in pixels)
171  ///
172  /// This function is used to only interpolate foreground image values.
173  /// If fully outside the foreground region, the _DefaultValue is returned.
174  ///
175  /// If the location is inside the finite domain of the image, an actual image
176  /// instance can be passed as first argument directly such as an instance of
177  /// GenericImage. Otherwise, an image function which extends the finite
178  /// image domain to an infinite lattice is needed, i.e., an instance of a
179  /// subclass of ExtrapolateImageFunction.
180  template <class TOtherImage> typename TOtherImage::VoxelType
181  GetWithPadding4D(const TOtherImage *, double, double, double = 0, double = 0) const;
182 
183  /// Get value of given image at arbitrary location (in pixels)
184  ///
185  /// This function is used to interpolate the image value at arbitrary
186  /// locations when no extrapolator was set.
187  VoxelType Get(double, double, double = 0, double = 0) const;
188 
189  /// Get value of given image at arbitrary location (in pixels)
190  ///
191  /// This function is used to only interpolate foreground image values.
192  /// If fully outside the foreground region, the _DefaultValue is returned.
193  virtual VoxelType GetWithPadding(double, double, double = 0, double = 0) const;
194 
195  /// Get value of given image at arbitrary location (in pixels)
196  ///
197  /// If the location is inside the finite domain of the image, an actual image
198  /// instance can be passed as first argument directly such as an instance of
199  /// GenericImage. Otherwise, an image function which extends the finite
200  /// image domain to an infinite lattice is needed, i.e., an instance of a
201  /// subclass of ExtrapolateImageFunction.
202  template <class TOtherImage> typename TOtherImage::VoxelType
203  Get(const TOtherImage *, double, double, double = 0, double = 0) const;
204 
205  /// Get value of given image at arbitrary location (in pixels)
206  ///
207  /// This function is used to only interpolate foreground image values.
208  /// If fully outside the foreground region, the _DefaultValue is returned.
209  ///
210  /// If the location is inside the finite domain of the image, an actual image
211  /// instance can be passed as first argument directly such as an instance of
212  /// GenericImage. Otherwise, an image function which extends the finite
213  /// image domain to an infinite lattice is needed, i.e., an instance of a
214  /// subclass of ExtrapolateImageFunction.
215  template <class TOtherImage> typename TOtherImage::VoxelType
216  GetWithPadding(const TOtherImage *, double, double, double = 0, double = 0) const;
217 
218  /// Evaluate generic 2D image without handling boundary conditions
219  virtual VoxelType GetInside2D(double, double, double = 0, double = 0) const;
220 
221  /// Evaluate generic 3D image without handling boundary conditions
222  virtual VoxelType GetInside3D(double, double, double = 0, double = 0) const;
223 
224  /// Evaluate generic 4D image without handling boundary conditions
225  virtual VoxelType GetInside4D(double, double, double = 0, double = 0) const;
226 
227  /// Evaluate generic image without handling boundary conditions
228  ///
229  /// This version is faster than EvaluateOutside, but is only defined inside
230  /// the domain for which all image values required for interpolation are
231  /// defined and thus require no extrapolation of the finite image.
232  virtual VoxelType GetInside(double, double, double = 0, double = 0) const;
233 
234  /// Evaluate generic image at an arbitrary location (in pixels)
235  virtual VoxelType GetOutside(double, double, double = 0, double = 0) const;
236 
237  /// Evaluate generic image without handling boundary conditions
238  ///
239  /// If the location is partially inside the foreground region of the image,
240  /// only the foreground values are interpolated. Otherwise, the _DefaultValue
241  /// is returned.
242  ///
243  /// This version is faster than GetWithPaddingOutside, but is only defined
244  /// inside the domain for which all image values required for interpolation
245  /// are defined and thus require no extrapolation of the finite image.
246  virtual VoxelType GetWithPaddingInside(double, double, double = 0, double = 0) const;
247 
248  /// Evaluate generic image at an arbitrary location (in pixels)
249  ///
250  /// If the location is partially inside the foreground region of the image,
251  /// only the foreground values are interpolated. Otherwise, the _DefaultValue
252  /// is returned.
253  virtual VoxelType GetWithPaddingOutside(double, double, double = 0, double = 0) const;
254 
255  // ---------------------------------------------------------------------------
256  // Derivative evaluation
257 
258  /// Get 1st order derivatives of given image at arbitrary location (in pixels)
259  ///
260  /// When the image has scalar data type and stores vector components in the
261  /// fourth dimension, the derivatives of all components are evaluated when
262  /// the t coordinate is set to NaN. Otherwise, only the derivatives of the
263  /// specified t component are evaluated.
264  virtual void EvaluateJacobianInside(Matrix &, double, double, double = 0, double = NaN) const;
265 
266  /// Get 1st order derivatives of given image at arbitrary location (in pixels)
267  ///
268  /// When the image has scalar data type and stores vector components in the
269  /// fourth dimension, the derivatives of all components are evaluated when
270  /// the t coordinate is set to NaN. Otherwise, only the derivatives of the
271  /// specified t component are evaluated.
272  virtual void EvaluateJacobianOutside(Matrix &, double, double, double = 0, double = NaN) const;
273 
274  /// Get 1st order derivatives of given image at arbitrary location (in pixels)
275  ///
276  /// When the image has scalar data type and stores vector components in the
277  /// fourth dimension, the derivatives of all components are evaluated when
278  /// the t coordinate is set to NaN. Otherwise, only the derivatives of the
279  /// specified t component are evaluated.
280  virtual void EvaluateJacobianWithPaddingInside(Matrix &, double, double, double = 0, double = NaN) const;
281 
282  /// Get 1st order derivatives of given image at arbitrary location (in pixels)
283  ///
284  /// When the image has scalar data type and stores vector components in the
285  /// fourth dimension, the derivatives of all components are evaluated when
286  /// the t coordinate is set to NaN. Otherwise, only the derivatives of the
287  /// specified t component are evaluated.
288  virtual void EvaluateJacobianWithPaddingOutside(Matrix &, double, double, double = 0, double = NaN) const;
289 
290  /// Get 1st order derivatives of given 3D image at arbitrary location (in pixels)
291  ///
292  /// This function is used when no extrapolator was set.
293  ///
294  /// When the image has scalar data type and stores vector components in the
295  /// fourth dimension, the derivatives of all components are evaluated when
296  /// the t coordinate is set to NaN. Otherwise, only the derivatives of the
297  /// specified t component are evaluated.
298  void Jacobian2D(Matrix &, double, double, double = 0., double = NaN) const;
299 
300  /// Get 1st order derivatives of given 3D image at arbitrary location (in pixels)
301  ///
302  /// This function is used when no extrapolator was set.
303  ///
304  /// When the image has scalar data type and stores vector components in the
305  /// fourth dimension, the derivatives of all components are evaluated when
306  /// the t coordinate is set to NaN. Otherwise, only the derivatives of the
307  /// specified t component are evaluated.
308  void Jacobian3D(Matrix &, double, double, double = 0., double = NaN) const;
309 
310  /// Get 1st order derivatives of given 4D image at arbitrary location (in pixels)
311  ///
312  /// This function is used when no extrapolator was set.
313  void Jacobian4D(Matrix &, double, double, double = 0., double = NaN) const;
314 
315  /// Get 1st order derivatives of given image at arbitrary location (in pixels)
316  void Jacobian(Matrix &, double, double, double = 0., double = NaN) const;
317 
318 
319  /// Get 1st order derivatives of given 3D image at arbitrary location (in pixels)
320  ///
321  /// Set derivatives to zero outside the image foreground.
322  ///
323  /// When the image has scalar data type and stores vector components in the
324  /// fourth dimension, the derivatives of all components are evaluated when
325  /// the t coordinate is set to NaN. Otherwise, only the derivatives of the
326  /// specified t component are evaluated.
327  void JacobianWithPadding2D(Matrix &, double, double, double = 0., double = NaN) const;
328 
329  /// Get 1st order derivatives of given 3D image at arbitrary location (in pixels)
330  ///
331  /// Set derivatives to zero outside the image foreground.
332  ///
333  /// When the image has scalar data type and stores vector components in the
334  /// fourth dimension, the derivatives of all components are evaluated when
335  /// the t coordinate is set to NaN. Otherwise, only the derivatives of the
336  /// specified t component are evaluated.
337  void JacobianWithPadding3D(Matrix &, double, double, double = 0., double = NaN) const;
338 
339  /// Get 1st order derivatives of given 4D image at arbitrary location (in pixels)
340  ///
341  /// Set derivatives to zero outside the image foreground.
342  void JacobianWithPadding4D(Matrix &, double, double, double = 0., double = NaN) const;
343 
344  /// Get 1st order derivatives of given image at arbitrary location (in pixels)
345  void JacobianWithPadding(Matrix &, double, double, double = 0, double = NaN) const;
346 
347 
348  /// Get 1st order derivatives of given 3D image at arbitrary location (in pixels)
349  ///
350  /// If the location is inside the finite domain of the image, an actual image
351  /// instance can be passed as first argument directly such as an instance of
352  /// GenericImage. Otherwise, an image function which extends the finite
353  /// image domain to an infinite lattice is needed, i.e., an instance of a
354  /// subclass of ExtrapolateImageFunction.
355  ///
356  /// When the image has scalar data type and stores vector components in the
357  /// fourth dimension, the derivatives of all components are evaluated when
358  /// the t coordinate is set to NaN. Otherwise, only the derivatives of the
359  /// specified t component are evaluated.
360  template <class TOtherImage>
361  void Jacobian2D(Matrix &, const TOtherImage *, double, double, double = 0., double = NaN) const;
362 
363  /// Get 1st order derivatives of given 3D image at arbitrary location (in pixels)
364  ///
365  /// If the location is inside the finite domain of the image, an actual image
366  /// instance can be passed as first argument directly such as an instance of
367  /// GenericImage. Otherwise, an image function which extends the finite
368  /// image domain to an infinite lattice is needed, i.e., an instance of a
369  /// subclass of ExtrapolateImageFunction.
370  ///
371  /// When the image has scalar data type and stores vector components in the
372  /// fourth dimension, the derivatives of all components are evaluated when
373  /// the t coordinate is set to NaN. Otherwise, only the derivatives of the
374  /// specified t component are evaluated.
375  template <class TOtherImage>
376  void Jacobian3D(Matrix &, const TOtherImage *, double, double, double = 0., double = NaN) const;
377 
378  /// Get 1st order derivatives of given 4D image at arbitrary location (in pixels)
379  ///
380  /// If the location is inside the finite domain of the image, an actual image
381  /// instance can be passed as first argument directly such as an instance of
382  /// GenericImage. Otherwise, an image function which extends the finite
383  /// image domain to an infinite lattice is needed, i.e., an instance of a
384  /// subclass of ExtrapolateImageFunction.
385  template <class TOtherImage>
386  void Jacobian4D(Matrix &, const TOtherImage *, double, double, double = 0., double = NaN) const;
387 
388  /// Get 1st order derivatives of given image at arbitrary location (in pixels)
389  ///
390  /// If the location is inside the finite domain of the image, an actual image
391  /// instance can be passed as first argument directly such as an instance of
392  /// GenericImage. Otherwise, an image function which extends the finite
393  /// image domain to an infinite lattice is needed, i.e., an instance of a
394  /// subclass of ExtrapolateImageFunction.
395  template <class TOtherImage>
396  void Jacobian(Matrix &, const TOtherImage *, double, double, double = 0., double = NaN) const;
397 
398 };
399 
400 
401 /**
402  * Linear interpolation of any scalar image
403  */
404 
406 : public GenericLinearInterpolateImageFunction<BaseImage>
407 {
408  mirtkObjectMacro(LinearInterpolateImageFunction);
409 
410 public:
411 
412  /// Constructor
414 
415 };
416 
417 
418 } // namespace mirtk
419 
420 #endif // MIRTK_LinearInterpolateImageFunction_H
VoxelType GetWithPadding4D(double, double, double=0, double=0) const
VoxelType Get(double, double, double=0, double=0) const
void JacobianWithPadding3D(Matrix &, double, double, double=0., double=NaN) const
void Jacobian4D(Matrix &, double, double, double=0., double=NaN) const
virtual void EvaluateJacobianWithPaddingInside(Matrix &, double, double, double=0, double=NaN) const
VoxelType Get3D(double, double, double=0, double=0) const
virtual VoxelType GetInside(double, double, double=0, double=0) const
virtual void EvaluateJacobianInside(Matrix &, double, double, double=0, double=NaN) const
virtual void EvaluateJacobianOutside(Matrix &, double, double, double=0, double=NaN) const
Definition: IOConfig.h:41
virtual VoxelType GetInside3D(double, double, double=0, double=0) const
Evaluate generic 3D image without handling boundary conditions.
virtual VoxelType GetWithPaddingOutside(double, double, double=0, double=0) const
virtual void BoundingInterval(double, int &, int &) const
void Jacobian(Matrix &, double, double, double=0., double=NaN) const
Get 1st order derivatives of given image at arbitrary location (in pixels)
VoxelType Get4D(double, double, double=0, double=0) const
virtual VoxelType GetInside2D(double, double, double=0, double=0) const
Evaluate generic 2D image without handling boundary conditions.
void Jacobian3D(Matrix &, double, double, double=0., double=NaN) const
VoxelType Get2D(double, double, double=0, double=0) const
VoxelType GetWithPadding3D(double, double, double=0, double=0) const
virtual VoxelType GetWithPaddingInside(double, double, double=0, double=0) const
void JacobianWithPadding4D(Matrix &, double, double, double=0., double=NaN) const
void Jacobian2D(Matrix &, double, double, double=0., double=NaN) const
virtual VoxelType GetWithPadding(double, double, double=0, double=0) const
virtual void EvaluateJacobianWithPaddingOutside(Matrix &, double, double, double=0, double=NaN) const
virtual VoxelType GetInside4D(double, double, double=0, double=0) const
Evaluate generic 4D image without handling boundary conditions.
void JacobianWithPadding(Matrix &, double, double, double=0, double=NaN) const
Get 1st order derivatives of given image at arbitrary location (in pixels)
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
void JacobianWithPadding2D(Matrix &, double, double, double=0., double=NaN) const