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_CSplineInterpolateImageFunction_H
21 #define MIRTK_CSplineInterpolateImageFunction_H
22 
23 #include "mirtk/BaseImage.h"
24 #include "mirtk/InterpolateImageFunction.h"
25 
26 
27 namespace mirtk {
28 
29 
30 /**
31  * Cubic spline interpolation of generic image
32  */
33 template <class TImage>
34 class GenericCSplineInterpolateImageFunction
35 : public GenericInterpolateImageFunction<TImage>
36 {
37   mirtkGenericInterpolatorMacro(
38     GenericCSplineInterpolateImageFunction,
39     Interpolation_CSpline
40   );
41 
42 protected:
43 
44   /// Cubic spline function
45   static Real CSpline(Real);
46 
47 public:
48 
49   // ---------------------------------------------------------------------------
50   // Construction/Destruction
51 
52   /// Default constructor
53   GenericCSplineInterpolateImageFunction();
54 
55   /// Destructor
56   virtual ~GenericCSplineInterpolateImageFunction();
57 
58   /// Initialize interpolation function
59   virtual void Initialize(bool = false);
60 
61   // ---------------------------------------------------------------------------
62   // Domain checks
63 
64   /// Returns interval of discrete image indices whose values are needed for
65   /// interpolation of the image value at a given continuous coordinate
66   virtual void BoundingInterval(double, int &, int &) const;
67 
68   // ---------------------------------------------------------------------------
69   // Evaluation
70 
71   /// Get value of given 2D image at arbitrary location (in pixels)
72   ///
73   /// This function is used to interpolate the image value at arbitrary
74   /// locations when no extrapolator was set.
75   VoxelType Get2D(double, double, double = 0, double = 0) const;
76 
77   /// Get value of given 2D image at arbitrary location (in pixels)
78   ///
79   /// This function is used to only interpolate foreground image values.
80   /// If fully outside the foreground region, the _DefaultValue is returned.
81   VoxelType GetWithPadding2D(double, double, double = 0, double = 0) const;
82 
83   /// Get value of given 2D image at arbitrary location (in pixels)
84   ///
85   /// If the location is inside the finite domain of the image, an actual image
86   /// instance can be passed as first argument directly such as an instance of
87   /// GenericImage. Otherwise, an image function which extends the finite
88   /// image domain to an infinite lattice is needed, i.e., an instance of a
89   /// subclass of ExtrapolateImageFunction.
90   template <class TOtherImage> typename TOtherImage::VoxelType
91   Get2D(const TOtherImage *, double, double, double = 0, double = 0) const;
92 
93   /// Get value of given 2D image at arbitrary location (in pixels)
94   ///
95   /// This function is used to only interpolate foreground image values.
96   /// If fully outside the foreground region, the _DefaultValue is returned.
97   ///
98   /// If the location is inside the finite domain of the image, an actual image
99   /// instance can be passed as first argument directly such as an instance of
100   /// GenericImage. Otherwise, an image function which extends the finite
101   /// image domain to an infinite lattice is needed, i.e., an instance of a
102   /// subclass of ExtrapolateImageFunction.
103   template <class TOtherImage> typename TOtherImage::VoxelType
104   GetWithPadding2D(const TOtherImage *, double, double, double = 0, double = 0) const;
105 
106   /// Get value of given 3D 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 Get3D(double, double, double = 0, double = 0) const;
111 
112   /// Get value of given 3D 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 GetWithPadding3D(double, double, double = 0, double = 0) const;
117 
118   /// Get value of given 3D 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   Get3D(const TOtherImage *, double, double, double = 0, double = 0) const;
127 
128   /// Get value of given 3D 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> typename TOtherImage::VoxelType
139   GetWithPadding3D(const TOtherImage *, double, double, double = 0, double = 0) const;
140 
141   /// Get value of given 4D image at arbitrary location (in pixels)
142   ///
143   /// This function is used to interpolate the image value at arbitrary
144   /// locations when no extrapolator was set.
145   VoxelType Get4D(double, double, double = 0, double = 0) const;
146 
147   /// Get value of given 4D image at arbitrary location (in pixels)
148   ///
149   /// This function is used to only interpolate foreground image values.
150   /// If fully outside the foreground region, the _DefaultValue is returned.
151   VoxelType GetWithPadding4D(double, double, double = 0, double = 0) const;
152 
153   /// Get value of given 4D image at arbitrary location (in pixels)
154   ///
155   /// If the location is inside the finite domain of the image, an actual image
156   /// instance can be passed as first argument directly such as an instance of
157   /// GenericImage. Otherwise, an image function which extends the finite
158   /// image domain to an infinite lattice is needed, i.e., an instance of a
159   /// subclass of ExtrapolateImageFunction.
160   template <class TOtherImage> typename TOtherImage::VoxelType
161   Get4D(const TOtherImage *, double, double, double = 0, double = 0) const;
162 
163   /// Get value of given 4D image at arbitrary location (in pixels)
164   ///
165   /// This function is used to only interpolate foreground image values.
166   /// If fully outside the foreground region, the _DefaultValue is returned.
167   ///
168   /// If the location is inside the finite domain of the image, an actual image
169   /// instance can be passed as first argument directly such as an instance of
170   /// GenericImage. Otherwise, an image function which extends the finite
171   /// image domain to an infinite lattice is needed, i.e., an instance of a
172   /// subclass of ExtrapolateImageFunction.
173   template <class TOtherImage> typename TOtherImage::VoxelType
174   GetWithPadding4D(const TOtherImage *, double, double, double = 0, double = 0) const;
175 
176   /// Get value of given image at arbitrary location (in pixels)
177   ///
178   /// This function is used to interpolate the image value at arbitrary
179   /// locations when no extrapolator was set.
180   VoxelType Get(double, double, double = 0, double = 0) const;
181 
182   /// Get value of given image at arbitrary location (in pixels)
183   ///
184   /// This function is used to only interpolate foreground image values.
185   /// If fully outside the foreground region, the _DefaultValue is returned.
186   virtual VoxelType GetWithPadding(double, double, double = 0, double = 0) const;
187 
188   /// Get value of given image at arbitrary location (in pixels)
189   ///
190   /// If the location is inside the finite domain of the image, an actual image
191   /// instance can be passed as first argument directly such as an instance of
192   /// GenericImage. Otherwise, an image function which extends the finite
193   /// image domain to an infinite lattice is needed, i.e., an instance of a
194   /// subclass of ExtrapolateImageFunction.
195   template <class TOtherImage> typename TOtherImage::VoxelType
196   Get(const TOtherImage *, double, double, double = 0, double = 0) const;
197 
198   /// Get value of given image at arbitrary location (in pixels)
199   ///
200   /// This function is used to only interpolate foreground image values.
201   /// If fully outside the foreground region, the _DefaultValue is returned.
202   ///
203   /// If the location is inside the finite domain of the image, an actual image
204   /// instance can be passed as first argument directly such as an instance of
205   /// GenericImage. Otherwise, an image function which extends the finite
206   /// image domain to an infinite lattice is needed, i.e., an instance of a
207   /// subclass of ExtrapolateImageFunction.
208   template <class TOtherImage> typename TOtherImage::VoxelType
209   GetWithPadding(const TOtherImage *, double, double, double = 0, double = 0) const;
210 
211   /// Evaluate generic image without handling boundary conditions
212   ///
213   /// This version is faster than EvaluateOutside, but is only defined inside
214   /// the domain for which all image values required for interpolation are
215   /// defined and thus require no extrapolation of the finite image.
216   virtual VoxelType GetInside(double, double, double = 0, double = 0) const;
217 
218   /// Evaluate generic image at an arbitrary location (in pixels)
219   virtual VoxelType GetOutside(double, double, double = 0, double = 0) const;
220 
221   /// Evaluate generic image without handling boundary conditions
222   ///
223   /// If the location is partially inside the foreground region of the image,
224   /// only the foreground values are interpolated. Otherwise, the _DefaultValue
225   /// is returned.
226   ///
227   /// This version is faster than GetWithPaddingOutside, but is only defined
228   /// inside the domain for which all image values required for interpolation
229   /// are defined and thus require no extrapolation of the finite image.
230   virtual VoxelType GetWithPaddingInside(double, double, double = 0, double = 0) const;
231 
232   /// Evaluate generic image at an arbitrary location (in pixels)
233   ///
234   /// If the location is partially inside the foreground region of the image,
235   /// only the foreground values are interpolated. Otherwise, the _DefaultValue
236   /// is returned.
237   virtual VoxelType GetWithPaddingOutside(double, double, double = 0, double = 0) const;
238 
239 };
240 
241 /**
242  * Cubic spline interpolation of any scalar image
243  */
244 class CSplineInterpolateImageFunction
245 : public GenericCSplineInterpolateImageFunction<BaseImage>
246 {
247   mirtkObjectMacro(CSplineInterpolateImageFunction);
248 
249 public:
250 
251   /// Constructor
CSplineInterpolateImageFunction()252   CSplineInterpolateImageFunction() {}
253 
254 };
255 
256 
257 } // namespace mirtk
258 
259 #endif // MIRTK_CSplineInterpolateImageFunction_H
260