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> 44 class GenericCubicBSplineInterpolateImageFunction 45 : public GenericInterpolateImageFunction<TImage> 46 { 47 mirtkGenericInterpolatorMacro( 48 GenericCubicBSplineInterpolateImageFunction, 49 Interpolation_CubicBSpline 50 ); 51 52 // --------------------------------------------------------------------------- 53 // Types 54 55 public: 56 57 typedef GenericImage<RealType> CoefficientImage; 58 typedef GenericExtrapolateImageFunction<CoefficientImage> CoefficientExtrapolator; 59 typedef GenericMirrorExtrapolateImageFunction<CoefficientImage> DefaultExtrapolator; 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 85 GenericCubicBSplineInterpolateImageFunction(); 86 87 /// Destructor 88 virtual ~GenericCubicBSplineInterpolateImageFunction(); 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 */ 290 class CubicBSplineInterpolateImageFunction 291 : public GenericCubicBSplineInterpolateImageFunction<BaseImage> 292 { 293 mirtkObjectMacro(CubicBSplineInterpolateImageFunction); 294 295 public: 296 297 /// Constructor CubicBSplineInterpolateImageFunction()298 CubicBSplineInterpolateImageFunction() {} 299 300 }; 301 302 303 } // namespace mirtk 304 305 #endif // MIRTK_CubicBSplineInterpolateImageFunction_H 306