ITK  5.1.0
Insight Toolkit
itkLinearInterpolateImageFunction.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkLinearInterpolateImageFunction_h
19 #define itkLinearInterpolateImageFunction_h
20 
23 
24 namespace itk
25 {
48 template <typename TInputImage, typename TCoordRep = double>
49 class ITK_TEMPLATE_EXPORT LinearInterpolateImageFunction : public InterpolateImageFunction<TInputImage, TCoordRep>
50 {
51 public:
52  ITK_DISALLOW_COPY_AND_ASSIGN(LinearInterpolateImageFunction);
53 
59 
62 
64  itkNewMacro(Self);
65 
67  using OutputType = typename Superclass::OutputType;
68 
70  using InputImageType = typename Superclass::InputImageType;
71 
73  using InputPixelType = typename Superclass::InputPixelType;
74 
76  using RealType = typename Superclass::RealType;
77 
79  static constexpr unsigned int ImageDimension = Superclass::ImageDimension;
80 
82  using IndexType = typename Superclass::IndexType;
83 
85  using SizeType = typename Superclass::SizeType;
86 
88  using ContinuousIndexType = typename Superclass::ContinuousIndexType;
89  using InternalComputationType = typename ContinuousIndexType::ValueType;
90 
100  EvaluateAtContinuousIndex(const ContinuousIndexType & index) const override
101  {
102  return this->EvaluateOptimized(Dispatch<ImageDimension>(), index);
103  }
104 
105  SizeType
106  GetRadius() const override
107  {
108  return SizeType::Filled(1);
109  }
110 
111 protected:
112  LinearInterpolateImageFunction() = default;
113  ~LinearInterpolateImageFunction() override = default;
114  void
115  PrintSelf(std::ostream & os, Indent indent) const override;
116 
117 private:
119  {};
120  template <unsigned int>
121  struct Dispatch : public DispatchBase
122  {};
123 
124  inline OutputType
126  {
127  return 0;
128  }
129 
130  inline OutputType
131  EvaluateOptimized(const Dispatch<1> &, const ContinuousIndexType & index) const
132  {
133  IndexType basei;
134  basei[0] = Math::Floor<IndexValueType>(index[0]);
135  if (basei[0] < this->m_StartIndex[0])
136  {
137  basei[0] = this->m_StartIndex[0];
138  }
139 
140  const InternalComputationType & distance = index[0] - static_cast<InternalComputationType>(basei[0]);
141 
142  const TInputImage * const inputImagePtr = this->GetInputImage();
143  const RealType & val0 = inputImagePtr->GetPixel(basei);
144  if (distance <= 0.)
145  {
146  return (static_cast<OutputType>(val0));
147  }
148 
149  ++basei[0];
150  if (basei[0] > this->m_EndIndex[0])
151  {
152  return (static_cast<OutputType>(val0));
153  }
154  const RealType & val1 = inputImagePtr->GetPixel(basei);
155 
156  return (static_cast<OutputType>(val0 + (val1 - val0) * distance));
157  }
158 
159  inline OutputType
160  EvaluateOptimized(const Dispatch<2> &, const ContinuousIndexType & index) const
161  {
162  IndexType basei;
163 
164  basei[0] = Math::Floor<IndexValueType>(index[0]);
165  if (basei[0] < this->m_StartIndex[0])
166  {
167  basei[0] = this->m_StartIndex[0];
168  }
169  const InternalComputationType & distance0 = index[0] - static_cast<InternalComputationType>(basei[0]);
170 
171  basei[1] = Math::Floor<IndexValueType>(index[1]);
172  if (basei[1] < this->m_StartIndex[1])
173  {
174  basei[1] = this->m_StartIndex[1];
175  }
176  const InternalComputationType & distance1 = index[1] - static_cast<InternalComputationType>(basei[1]);
177 
178  const TInputImage * const inputImagePtr = this->GetInputImage();
179  const RealType & val00 = inputImagePtr->GetPixel(basei);
180  if (distance0 <= 0. && distance1 <= 0.)
181  {
182  return (static_cast<OutputType>(val00));
183  }
184  else if (distance1 <= 0.) // if they have the same "y"
185  {
186  ++basei[0]; // then interpolate across "x"
187  if (basei[0] > this->m_EndIndex[0])
188  {
189  return (static_cast<OutputType>(val00));
190  }
191  const RealType & val10 = inputImagePtr->GetPixel(basei);
192  return (static_cast<OutputType>(val00 + (val10 - val00) * distance0));
193  }
194  else if (distance0 <= 0.) // if they have the same "x"
195  {
196  ++basei[1]; // then interpolate across "y"
197  if (basei[1] > this->m_EndIndex[1])
198  {
199  return (static_cast<OutputType>(val00));
200  }
201  const RealType & val01 = inputImagePtr->GetPixel(basei);
202  return (static_cast<OutputType>(val00 + (val01 - val00) * distance1));
203  }
204  // fall-through case:
205  // interpolate across "xy"
206  ++basei[0];
207  if (basei[0] > this->m_EndIndex[0]) // interpolate across "y"
208  {
209  --basei[0];
210  ++basei[1];
211  if (basei[1] > this->m_EndIndex[1])
212  {
213  return (static_cast<OutputType>(val00));
214  }
215  const RealType & val01 = inputImagePtr->GetPixel(basei);
216  return (static_cast<OutputType>(val00 + (val01 - val00) * distance1));
217  }
218  const RealType & val10 = inputImagePtr->GetPixel(basei);
219 
220  const RealType & valx0 = val00 + (val10 - val00) * distance0;
221 
222  ++basei[1];
223  if (basei[1] > this->m_EndIndex[1]) // interpolate across "x"
224  {
225  return (static_cast<OutputType>(valx0));
226  }
227  const RealType & val11 = inputImagePtr->GetPixel(basei);
228  --basei[0];
229  const RealType & val01 = inputImagePtr->GetPixel(basei);
230 
231  const RealType & valx1 = val01 + (val11 - val01) * distance0;
232 
233  return (static_cast<OutputType>(valx0 + (valx1 - valx0) * distance1));
234  }
235 
236  inline OutputType
237  EvaluateOptimized(const Dispatch<3> &, const ContinuousIndexType & index) const
238  {
239  IndexType basei;
240  basei[0] = Math::Floor<IndexValueType>(index[0]);
241  if (basei[0] < this->m_StartIndex[0])
242  {
243  basei[0] = this->m_StartIndex[0];
244  }
245  const InternalComputationType & distance0 = index[0] - static_cast<InternalComputationType>(basei[0]);
246 
247  basei[1] = Math::Floor<IndexValueType>(index[1]);
248  if (basei[1] < this->m_StartIndex[1])
249  {
250  basei[1] = this->m_StartIndex[1];
251  }
252  const InternalComputationType & distance1 = index[1] - static_cast<InternalComputationType>(basei[1]);
253 
254  basei[2] = Math::Floor<IndexValueType>(index[2]);
255  if (basei[2] < this->m_StartIndex[2])
256  {
257  basei[2] = this->m_StartIndex[2];
258  }
259  const InternalComputationType & distance2 = index[2] - static_cast<InternalComputationType>(basei[2]);
260 
261  const TInputImage * const inputImagePtr = this->GetInputImage();
262  const RealType & val000 = inputImagePtr->GetPixel(basei);
263  if (distance0 <= 0. && distance1 <= 0. && distance2 <= 0.)
264  {
265  return (static_cast<OutputType>(val000));
266  }
267 
268  if (distance2 <= 0.)
269  {
270  if (distance1 <= 0.) // interpolate across "x"
271  {
272  ++basei[0];
273  if (basei[0] > this->m_EndIndex[0])
274  {
275  return (static_cast<OutputType>(val000));
276  }
277  const RealType & val100 = inputImagePtr->GetPixel(basei);
278 
279  return static_cast<OutputType>(val000 + (val100 - val000) * distance0);
280  }
281  else if (distance0 <= 0.) // interpolate across "y"
282  {
283  ++basei[1];
284  if (basei[1] > this->m_EndIndex[1])
285  {
286  return (static_cast<OutputType>(val000));
287  }
288  const RealType & val010 = inputImagePtr->GetPixel(basei);
289 
290  return static_cast<OutputType>(val000 + (val010 - val000) * distance1);
291  }
292  else // interpolate across "xy"
293  {
294  ++basei[0];
295  if (basei[0] > this->m_EndIndex[0]) // interpolate across "y"
296  {
297  --basei[0];
298  ++basei[1];
299  if (basei[1] > this->m_EndIndex[1])
300  {
301  return (static_cast<OutputType>(val000));
302  }
303  const RealType & val010 = inputImagePtr->GetPixel(basei);
304  return static_cast<OutputType>(val000 + (val010 - val000) * distance1);
305  }
306  const RealType & val100 = inputImagePtr->GetPixel(basei);
307  const RealType & valx00 = val000 + (val100 - val000) * distance0;
308 
309  ++basei[1];
310  if (basei[1] > this->m_EndIndex[1]) // interpolate across "x"
311  {
312  return (static_cast<OutputType>(valx00));
313  }
314  const RealType & val110 = inputImagePtr->GetPixel(basei);
315 
316  --basei[0];
317  const RealType & val010 = inputImagePtr->GetPixel(basei);
318  const RealType & valx10 = val010 + (val110 - val010) * distance0;
319 
320  return static_cast<OutputType>(valx00 + (valx10 - valx00) * distance1);
321  }
322  }
323  else
324  {
325  if (distance1 <= 0.)
326  {
327  if (distance0 <= 0.) // interpolate across "z"
328  {
329  ++basei[2];
330  if (basei[2] > this->m_EndIndex[2])
331  {
332  return (static_cast<OutputType>(val000));
333  }
334  const RealType & val001 = inputImagePtr->GetPixel(basei);
335 
336  return static_cast<OutputType>(val000 + (val001 - val000) * distance2);
337  }
338  else // interpolate across "xz"
339  {
340  ++basei[0];
341  if (basei[0] > this->m_EndIndex[0]) // interpolate across "z"
342  {
343  --basei[0];
344  ++basei[2];
345  if (basei[2] > this->m_EndIndex[2])
346  {
347  return (static_cast<OutputType>(val000));
348  }
349  const RealType & val001 = inputImagePtr->GetPixel(basei);
350 
351  return static_cast<OutputType>(val000 + (val001 - val000) * distance2);
352  }
353  const RealType & val100 = inputImagePtr->GetPixel(basei);
354 
355  const RealType & valx00 = val000 + (val100 - val000) * distance0;
356 
357  ++basei[2];
358  if (basei[2] > this->m_EndIndex[2]) // interpolate across "x"
359  {
360  return (static_cast<OutputType>(valx00));
361  }
362  const RealType & val101 = inputImagePtr->GetPixel(basei);
363 
364  --basei[0];
365  const RealType & val001 = inputImagePtr->GetPixel(basei);
366 
367  const RealType & valx01 = val001 + (val101 - val001) * distance0;
368 
369  return static_cast<OutputType>(valx00 + (valx01 - valx00) * distance2);
370  }
371  }
372  else if (distance0 <= 0.) // interpolate across "yz"
373  {
374  ++basei[1];
375  if (basei[1] > this->m_EndIndex[1]) // interpolate across "z"
376  {
377  --basei[1];
378  ++basei[2];
379  if (basei[2] > this->m_EndIndex[2])
380  {
381  return (static_cast<OutputType>(val000));
382  }
383  const RealType & val001 = inputImagePtr->GetPixel(basei);
384 
385  return static_cast<OutputType>(val000 + (val001 - val000) * distance2);
386  }
387  const RealType & val010 = inputImagePtr->GetPixel(basei);
388 
389  const RealType & val0x0 = val000 + (val010 - val000) * distance1;
390 
391  ++basei[2];
392  if (basei[2] > this->m_EndIndex[2]) // interpolate across "y"
393  {
394  return (static_cast<OutputType>(val0x0));
395  }
396  const RealType & val011 = inputImagePtr->GetPixel(basei);
397 
398  --basei[1];
399  const RealType & val001 = inputImagePtr->GetPixel(basei);
400 
401  const RealType & val0x1 = val001 + (val011 - val001) * distance1;
402 
403  return static_cast<OutputType>(val0x0 + (val0x1 - val0x0) * distance2);
404  }
405  else // interpolate across "xyz"
406  {
407  ++basei[0];
408  if (basei[0] > this->m_EndIndex[0]) // interpolate across "yz"
409  {
410  --basei[0];
411  ++basei[1];
412  if (basei[1] > this->m_EndIndex[1]) // interpolate across "z"
413  {
414  --basei[1];
415  ++basei[2];
416  if (basei[2] > this->m_EndIndex[2])
417  {
418  return (static_cast<OutputType>(val000));
419  }
420  const RealType & val001 = inputImagePtr->GetPixel(basei);
421 
422  return static_cast<OutputType>(val000 + (val001 - val000) * distance2);
423  }
424  const RealType & val010 = inputImagePtr->GetPixel(basei);
425  const RealType & val0x0 = val000 + (val010 - val000) * distance1;
426 
427  ++basei[2];
428  if (basei[2] > this->m_EndIndex[2]) // interpolate across "y"
429  {
430  return (static_cast<OutputType>(val0x0));
431  }
432  const RealType & val011 = inputImagePtr->GetPixel(basei);
433 
434  --basei[1];
435  const RealType & val001 = inputImagePtr->GetPixel(basei);
436 
437  const RealType & val0x1 = val001 + (val011 - val001) * distance1;
438 
439  return static_cast<OutputType>(val0x0 + (val0x1 - val0x0) * distance2);
440  }
441  const RealType & val100 = inputImagePtr->GetPixel(basei);
442 
443  const RealType & valx00 = val000 + (val100 - val000) * distance0;
444 
445  ++basei[1];
446  if (basei[1] > this->m_EndIndex[1]) // interpolate across "xz"
447  {
448  --basei[1];
449  ++basei[2];
450  if (basei[2] > this->m_EndIndex[2]) // interpolate across "x"
451  {
452  return (static_cast<OutputType>(valx00));
453  }
454  const RealType & val101 = inputImagePtr->GetPixel(basei);
455 
456  --basei[0];
457  const RealType & val001 = inputImagePtr->GetPixel(basei);
458 
459  const RealType & valx01 = val001 + (val101 - val001) * distance0;
460 
461  return static_cast<OutputType>(valx00 + (valx01 - valx00) * distance2);
462  }
463  const RealType & val110 = inputImagePtr->GetPixel(basei);
464 
465  --basei[0];
466  const RealType & val010 = inputImagePtr->GetPixel(basei);
467 
468  const RealType & valx10 = val010 + (val110 - val010) * distance0;
469 
470  const RealType & valxx0 = valx00 + (valx10 - valx00) * distance1;
471 
472  ++basei[2];
473  if (basei[2] > this->m_EndIndex[2]) // interpolate across "xy"
474  {
475  return (static_cast<OutputType>(valxx0));
476  }
477  const RealType & val011 = inputImagePtr->GetPixel(basei);
478 
479  ++basei[0];
480  const RealType & val111 = inputImagePtr->GetPixel(basei);
481 
482  --basei[1];
483  const RealType & val101 = inputImagePtr->GetPixel(basei);
484 
485  --basei[0];
486  const RealType & val001 = inputImagePtr->GetPixel(basei);
487 
488  const RealType & valx01 = val001 + (val101 - val001) * distance0;
489  const RealType & valx11 = val011 + (val111 - val011) * distance0;
490  const RealType & valxx1 = valx01 + (valx11 - valx01) * distance1;
491 
492  return (static_cast<OutputType>(valxx0 + (valxx1 - valxx0) * distance2));
493  }
494  }
495  }
496 
497  inline OutputType
498  EvaluateOptimized(const DispatchBase &, const ContinuousIndexType & index) const
499  {
500  return this->EvaluateUnoptimized(index);
501  }
502 
504  virtual inline OutputType
505  EvaluateUnoptimized(const ContinuousIndexType & index) const;
506 
509  template <typename RealTypeScalarRealType>
510  void
511  MakeZeroInitializer(const TInputImage * const inputImagePtr,
513  {
514  // Variable length vector version to get the size of the pixel correct.
515  typename TInputImage::IndexType idx;
516  idx.Fill(0);
517  const typename TInputImage::PixelType & tempPixel = inputImagePtr->GetPixel(idx);
518  const unsigned int sizeOfVarLengthVector = tempPixel.GetSize();
519  tempZeros.SetSize(sizeOfVarLengthVector);
521  }
522 
523  template <typename RealTypeScalarRealType>
524  void
525  MakeZeroInitializer(const TInputImage * const itkNotUsed(inputImagePtr), RealTypeScalarRealType & tempZeros) const
526  {
527  // All other cases
529  }
530 };
531 } // end namespace itk
532 
533 #ifndef ITK_MANUAL_INSTANTIATION
534 # include "itkLinearInterpolateImageFunction.hxx"
535 #endif
536 
537 #endif
itk::VariableLengthVector::Fill
void Fill(TValue const &v)
itk::InterpolateImageFunction::SizeType
typename InputImageType::SizeType SizeType
Definition: itkInterpolateImageFunction.h:78
itk::LinearInterpolateImageFunction::EvaluateOptimized
OutputType EvaluateOptimized(const DispatchBase &, const ContinuousIndexType &index) const
Definition: itkLinearInterpolateImageFunction.h:498
itkVariableLengthVector.h
itk::LinearInterpolateImageFunction::EvaluateOptimized
OutputType EvaluateOptimized(const Dispatch< 3 > &, const ContinuousIndexType &index) const
Definition: itkLinearInterpolateImageFunction.h:237
itk::VariableLengthVector::SetSize
void SetSize(unsigned int sz, TReallocatePolicy reallocatePolicy, TKeepValuesPolicy keepValues)
itk::GTest::TypedefsAndConstructors::Dimension2::SizeType
ImageBaseType::SizeType SizeType
Definition: itkGTestTypedefsAndConstructors.h:49
itk::LinearInterpolateImageFunction::EvaluateOptimized
OutputType EvaluateOptimized(const Dispatch< 2 > &, const ContinuousIndexType &index) const
Definition: itkLinearInterpolateImageFunction.h:160
itk::SmartPointer< Self >
itk::Indent
Control indentation during Print() invocation.
Definition: itkIndent.h:49
itk::LinearInterpolateImageFunction::MakeZeroInitializer
void MakeZeroInitializer(const TInputImage *const, RealTypeScalarRealType &tempZeros) const
Definition: itkLinearInterpolateImageFunction.h:525
itk::Index::Fill
void Fill(IndexValueType value)
Definition: itkIndex.h:270
itk::GTest::TypedefsAndConstructors::Dimension2::IndexType
ImageBaseType::IndexType IndexType
Definition: itkGTestTypedefsAndConstructors.h:50
itk::LinearInterpolateImageFunction
Linearly interpolate an image at specified positions.
Definition: itkLinearInterpolateImageFunction.h:49
itk::LightObject
Light weight base class for most itk classes.
Definition: itkLightObject.h:59
itk::LinearInterpolateImageFunction::InternalComputationType
typename ContinuousIndexType::ValueType InternalComputationType
Definition: itkLinearInterpolateImageFunction.h:89
itk::LinearInterpolateImageFunction::MakeZeroInitializer
void MakeZeroInitializer(const TInputImage *const inputImagePtr, VariableLengthVector< RealTypeScalarRealType > &tempZeros) const
A method to generically set all components to zero.
Definition: itkLinearInterpolateImageFunction.h:511
itk::InterpolateImageFunction::ContinuousIndexType
typename Superclass::ContinuousIndexType ContinuousIndexType
Definition: itkInterpolateImageFunction.h:81
itk::LinearInterpolateImageFunction::DispatchBase
Definition: itkLinearInterpolateImageFunction.h:118
itk::InterpolateImageFunction::InputImageType
typename Superclass::InputImageType InputImageType
Definition: itkInterpolateImageFunction.h:65
itk::VariableLengthVector
Represents an array whose length can be defined at run-time.
Definition: itkConstantBoundaryCondition.h:28
itk::NumericTraits
Define additional traits for native types such as int or float.
Definition: itkNumericTraits.h:58
itk::LinearInterpolateImageFunction::InputPixelType
typename Superclass::InputPixelType InputPixelType
Definition: itkLinearInterpolateImageFunction.h:73
itk::NumericTraits::ZeroValue
static T ZeroValue()
Definition: itkNumericTraits.h:148
itk::LinearInterpolateImageFunction::Dispatch
Definition: itkLinearInterpolateImageFunction.h:121
itk::InterpolateImageFunction::OutputType
typename Superclass::OutputType OutputType
Definition: itkInterpolateImageFunction.h:62
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkArray.h:26
itk::LinearInterpolateImageFunction::GetRadius
SizeType GetRadius() const override
Definition: itkLinearInterpolateImageFunction.h:106
itkInterpolateImageFunction.h
itk::LinearInterpolateImageFunction::EvaluateAtContinuousIndex
OutputType EvaluateAtContinuousIndex(const ContinuousIndexType &index) const override
Definition: itkLinearInterpolateImageFunction.h:100
itk::LinearInterpolateImageFunction::EvaluateOptimized
OutputType EvaluateOptimized(const Dispatch< 0 > &, const ContinuousIndexType &) const
Definition: itkLinearInterpolateImageFunction.h:125
itk::InterpolateImageFunction
Base class for all image interpolators.
Definition: itkInterpolateImageFunction.h:44
itk::LinearInterpolateImageFunction::EvaluateOptimized
OutputType EvaluateOptimized(const Dispatch< 1 > &, const ContinuousIndexType &index) const
Definition: itkLinearInterpolateImageFunction.h:131
itk::InterpolateImageFunction::IndexType
typename Superclass::IndexType IndexType
Definition: itkInterpolateImageFunction.h:74
itk::InterpolateImageFunction::RealType
typename NumericTraits< typename TInputImage::PixelType >::RealType RealType
Definition: itkInterpolateImageFunction.h:84