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