1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkAbstractImageInterpolator.h
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 // .NAME vtkAbstractImageInterpolator - interpolate data values from images
16 // .SECTION Description
17 // vtkAbstractImageInterpolator provides an abstract interface for
18 // interpolating image data.  You specify the data set you want to
19 // interpolate values from, then call Interpolate(x,y,z) to interpolate
20 // the data.
21 // .SECTION Thanks
22 // Thanks to David Gobbi at the Seaman Family MR Centre and Dept. of Clinical
23 // Neurosciences, Foothills Medical Centre, Calgary, for providing this class.
24 // .SECTION See also
25 // vtkImageReslice vtkImageInterpolator vtkImageSincInterpolator
26 
27 
28 #ifndef vtkAbstractImageInterpolator_h
29 #define vtkAbstractImageInterpolator_h
30 
31 #include "vtkImagingCoreModule.h" // For export macro
32 #include "vtkObject.h"
33 
34 #define VTK_IMAGE_BORDER_CLAMP 0
35 #define VTK_IMAGE_BORDER_REPEAT 1
36 #define VTK_IMAGE_BORDER_MIRROR 2
37 
38 class vtkDataObject;
39 class vtkImageData;
40 class vtkDataArray;
41 struct vtkInterpolationInfo;
42 struct vtkInterpolationWeights;
43 
44 class VTKIMAGINGCORE_EXPORT vtkAbstractImageInterpolator : public vtkObject
45 {
46 public:
47   vtkTypeMacro(vtkAbstractImageInterpolator, vtkObject);
48   virtual void PrintSelf(ostream& os, vtkIndent indent);
49 
50   // Description:
51   // Initialize the interpolator with the data that you wish to interpolate.
52   virtual void Initialize(vtkDataObject *data);
53 
54   // Description:
55   // Release any data stored by the interpolator.
56   virtual void ReleaseData();
57 
58   // Description:
59   // Copy the interpolator.  It is possible to duplicate an interpolator
60   // by calling NewInstance() followed by DeepCopy().
61   void DeepCopy(vtkAbstractImageInterpolator *obj);
62 
63   // Description:
64   // Update the interpolator.  If the interpolator has been modified by
65   // a Set method since Initialize() was called, you must call this method
66   // to update the interpolator before you can use it.
67   void Update();
68 
69   // Description:
70   // Get the result of interpolating the specified component of the input
71   // data, which should be set to zero if there is only one component.
72   // If the point is not within the bounds of the data set, then OutValue
73   // will be returned.  This method is primarily meant for use by the
74   // wrapper languages.
75   double Interpolate(double x, double y, double z, int component);
76 
77   // Description:
78   // Sample the input data. This is an inline method that calls the
79   // function that performs the appropriate interpolation for the
80   // data type.  If the point is not within the bounds of the data set,
81   // then the return value is false, and each component will be set to
82   // the OutValue.
83   bool Interpolate(const double point[3], double *value);
84 
85   // Description:
86   // The value to return when the point is out of bounds.
87   void SetOutValue(double outValue);
GetOutValue()88   double GetOutValue() { return this->OutValue; }
89 
90   // Description:
91   // The tolerance to apply when checking whether a point is out of bounds.
92   // This is a fractional distance relative to the voxel size, so a tolerance
93   // of 1 expands the bounds by one voxel.
94   void SetTolerance(double tol);
GetTolerance()95   double GetTolerance() { return this->Tolerance; }
96 
97   // Description:
98   // This method specifies which component of the input will be interpolated,
99   // or if ComponentCount is also set, it specifies the first component.
100   // When the interpolation is performed, it will be clamped to the number
101   // of available components.
102   void SetComponentOffset(int offset);
GetComponentOffset()103   int GetComponentOffset() { return this->ComponentOffset; }
104 
105   // Description:
106   // This method specifies the number of components to extract.  The default
107   // value is -1, which extracts all available components.  When the
108   // interpolation is performed, this will be clamped to the number of
109   // available components.
110   void SetComponentCount(int count);
GetComponentCount()111   int GetComponentCount() { return this->ComponentCount; }
112 
113   // Description:
114   // Compute the number of output components based on the ComponentOffset,
115   // ComponentCount, and the number of components in the input data.
116   int ComputeNumberOfComponents(int inputComponents);
117 
118   // Description:
119   // Get the number of components that will be returned when Interpolate()
120   // is called.  This is only valid after initialization.  Before then, use
121   // ComputeNumberOfComponents instead.
122   int GetNumberOfComponents();
123 
124   // Description:
125   // A version of Interpolate that takes structured coords instead of data
126   // coords.  Structured coords are the data coords after subtracting the
127   // Origin and dividing by the Spacing.
128   void InterpolateIJK(const double point[3], double *value);
129   void InterpolateIJK(const float point[3], float *value);
130 
131   // Description:
132   // Check an x,y,z point to see if it is within the bounds for the
133   // structured coords of the image.  This is meant to be called prior
134   // to InterpolateIJK.  The bounds that are checked against are the input
135   // image extent plus the tolerance.
136   bool CheckBoundsIJK(const double x[3]);
137   bool CheckBoundsIJK(const float x[3]);
138 
139   // Description:
140   // The border mode (default: clamp).  This controls how out-of-bounds
141   // lookups are handled, i.e. how data will be extrapolated beyond the
142   // bounds of the image.  The default is to clamp the lookup point to the
143   // bounds.  The other modes wrap around to the opposite boundary, or
144   // mirror the image at the boundary.
145   void SetBorderMode(int mode);
SetBorderModeToClamp()146   void SetBorderModeToClamp() {
147     this->SetBorderMode(VTK_IMAGE_BORDER_CLAMP); }
SetBorderModeToRepeat()148   void SetBorderModeToRepeat() {
149     this->SetBorderMode(VTK_IMAGE_BORDER_REPEAT); }
SetBorderModeToMirror()150   void SetBorderModeToMirror() {
151     this->SetBorderMode(VTK_IMAGE_BORDER_MIRROR); }
GetBorderMode()152   int GetBorderMode() { return this->BorderMode; }
153   const char *GetBorderModeAsString();
154 
155   // Description:
156   // Get the support size for use in computing update extents.  If the data
157   // will be sampled on a regular grid, then pass a matrix describing the
158   // structured coordinate transformation between the output and the input.
159   // Otherwise, pass NULL as the matrix to retrieve the full kernel size.
160   virtual void ComputeSupportSize(const double matrix[16], int support[3]) = 0;
161 
162   // Description:
163   // True if the interpolation is separable, which means that the weights
164   // can be precomputed in order to accelerate the interpolation.  Any
165   // interpolator which is separable will implement the methods
166   // PrecomputeWeightsForExtent and InterpolateRow
167   virtual bool IsSeparable() = 0;
168 
169   // Description:
170   // If the data is going to be sampled on a regular grid, then the
171   // interpolation weights can be precomputed.  A matrix must be supplied
172   // that provides a transformation between the provided extent and the
173   // structured coordinates of the input.  This matrix must perform only
174   // permutation, scale, and translation, i.e. each of the three columns
175   // must have only one non-zero value.  A checkExtent is provided that can
176   // be used to check which indices in the extent map to out-of-bounds
177   // coordinates in the input data.
178   virtual void PrecomputeWeightsForExtent(
179     const double matrix[16], const int extent[6], int checkExtent[6],
180     vtkInterpolationWeights *&weights);
181   virtual void PrecomputeWeightsForExtent(
182     const float matrix[16], const int extent[6], int checkExtent[6],
183     vtkInterpolationWeights *&weights);
184 
185   // Description:
186   // Free the weights that were provided by PrecomputeWeightsForExtent.
187   virtual void FreePrecomputedWeights(vtkInterpolationWeights *&weights);
188 
189   // Description:
190   // Get a row of samples, using the weights that were precomputed
191   // by PrecomputeWeightsForExtent.  Note that each sample may have
192   // multiple components.  It is possible to select which components
193   // will be returned by setting the ComponentOffset and ComponentCount.
194   void InterpolateRow(
195     vtkInterpolationWeights *&weights, int xIdx, int yIdx, int zIdx,
196     double *value, int n);
197   void InterpolateRow(
198     vtkInterpolationWeights *&weights, int xIdx, int yIdx, int zIdx,
199     float *value, int n);
200 
201   // Description:
202   // Get the spacing of the data being interpolated.
203   vtkGetVector3Macro(Spacing, double);
204 
205   // Description:
206   // Get the origin of the data being interpolated.
207   vtkGetVector3Macro(Origin, double);
208 
209   // Description:
210   // Get the extent of the data being interpolated.
211   vtkGetVector6Macro(Extent, int);
212 
213   // Description:
214   // Get the whole extent of the data being interpolated, including
215   // parts of the data that are not currently in memory.
216   vtkGetVector6Macro(WholeExtent, int);
217 
218 protected:
219   vtkAbstractImageInterpolator();
220   ~vtkAbstractImageInterpolator();
221 
222   // Description:
223   // Subclass-specific updates.
224   virtual void InternalUpdate() = 0;
225 
226   // Description:
227   // Subclass-specific copy.
228   virtual void InternalDeepCopy(vtkAbstractImageInterpolator *obj) = 0;
229 
230   // Description:
231   // Get the interpolation functions.
232   virtual void GetInterpolationFunc(
233     void (**doublefunc)(
234       vtkInterpolationInfo *, const double [3], double *));
235   virtual void GetInterpolationFunc(
236     void (**floatfunc)(
237       vtkInterpolationInfo *, const float [3], float *));
238 
239   // Description:
240   // Get the row interpolation functions.
241   virtual void GetRowInterpolationFunc(
242     void (**doublefunc)(
243       vtkInterpolationWeights *, int, int, int, double *, int));
244   virtual void GetRowInterpolationFunc(
245     void (**floatfunc)(
246       vtkInterpolationWeights *, int, int, int, float *, int));
247 
248   vtkDataArray *Scalars;
249   double StructuredBoundsDouble[6];
250   float StructuredBoundsFloat[6];
251   int WholeExtent[6];
252   int Extent[6];
253   double Spacing[3];
254   double Origin[3];
255   double OutValue;
256   double Tolerance;
257   int BorderMode;
258   int ComponentOffset;
259   int ComponentCount;
260 
261   // information needed by the interpolator funcs
262   vtkInterpolationInfo *InterpolationInfo;
263 
264   void (*InterpolationFuncDouble)(
265     vtkInterpolationInfo *info, const double point[3], double *outPtr);
266   void (*InterpolationFuncFloat)(
267     vtkInterpolationInfo *info, const float point[3], float *outPtr);
268 
269   void (*RowInterpolationFuncDouble)(
270     vtkInterpolationWeights *weights, int idX, int idY, int idZ,
271     double *outPtr, int n);
272   void (*RowInterpolationFuncFloat)(
273     vtkInterpolationWeights *weights, int idX, int idY, int idZ,
274     float *outPtr, int n);
275 
276 private:
277 
278   vtkAbstractImageInterpolator(const vtkAbstractImageInterpolator&);  // Not implemented.
279   void operator=(const vtkAbstractImageInterpolator&);  // Not implemented.
280 };
281 
InterpolateIJK(const double point[3],double * value)282 inline void vtkAbstractImageInterpolator::InterpolateIJK(
283   const double point[3], double *value)
284 {
285   this->InterpolationFuncDouble(this->InterpolationInfo, point, value);
286 }
287 
InterpolateIJK(const float point[3],float * value)288 inline void vtkAbstractImageInterpolator::InterpolateIJK(
289   const float point[3], float *value)
290 {
291   this->InterpolationFuncFloat(this->InterpolationInfo, point, value);
292 }
293 
CheckBoundsIJK(const double x[3])294 inline bool vtkAbstractImageInterpolator::CheckBoundsIJK(const double x[3])
295 {
296   double *bounds = this->StructuredBoundsDouble;
297   return !((x[0] < bounds[0]) | (x[0] > bounds[1]) |
298            (x[1] < bounds[2]) | (x[1] > bounds[3]) |
299            (x[2] < bounds[4]) | (x[2] > bounds[5]));
300 }
301 
CheckBoundsIJK(const float x[3])302 inline bool vtkAbstractImageInterpolator::CheckBoundsIJK(const float x[3])
303 {
304   float *bounds = this->StructuredBoundsFloat;
305   return !((x[0] < bounds[0]) | (x[0] > bounds[1]) |
306            (x[1] < bounds[2]) | (x[1] > bounds[3]) |
307            (x[2] < bounds[4]) | (x[2] > bounds[5]));
308 }
309 
InterpolateRow(vtkInterpolationWeights * & weights,int xIdx,int yIdx,int zIdx,double * value,int n)310 inline void vtkAbstractImageInterpolator::InterpolateRow(
311   vtkInterpolationWeights *&weights, int xIdx, int yIdx, int zIdx,
312   double *value, int n)
313 {
314   this->RowInterpolationFuncDouble(weights, xIdx, yIdx, zIdx, value, n);
315 }
316 
InterpolateRow(vtkInterpolationWeights * & weights,int xIdx,int yIdx,int zIdx,float * value,int n)317 inline void vtkAbstractImageInterpolator::InterpolateRow(
318   vtkInterpolationWeights *&weights, int xIdx, int yIdx, int zIdx,
319   float *value, int n)
320 {
321   this->RowInterpolationFuncFloat(weights, xIdx, yIdx, zIdx, value, n);
322 }
323 
324 #endif
325