File: itkAdvancedLinearInterpolateImageFunction.h

package info (click to toggle)
elastix 5.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 42,480 kB
  • sloc: cpp: 68,403; lisp: 4,118; python: 1,013; xml: 182; sh: 177; makefile: 33
file content (173 lines) | stat: -rw-r--r-- 6,773 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*=========================================================================
 *
 *  Copyright UMC Utrecht and contributors
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
#ifndef itkAdvancedLinearInterpolateImageFunction_h
#define itkAdvancedLinearInterpolateImageFunction_h

#include "itkLinearInterpolateImageFunction.h"

namespace itk
{
/** \class AdvancedLinearInterpolateImageFunction
 * \brief Linearly interpolate an image at specified positions.
 *
 * AdvancedLinearInterpolateImageFunction linearly interpolates image intensity at
 * a non-integer pixel position. This class is templated
 * over the input image type and the coordinate representation type
 * (e.g. float or double).
 *
 * This function works for N-dimensional images.
 *
 * This function works for images with scalar and vector pixel
 * types, and for images of type VectorImage.
 *
 * Unlike the LinearInterpolateImageFunction, which implements a constant
 * boundary condition, this class implements a mirroring boundary condition,
 * which mimics the BSplineInterpolateImageFunction.
 *
 * Edge cases, i.e. points exactly on the right most edge of the image,
 * need to be dealt with separately. In this implementation we subtract a
 * small number from the continuous index and interpolate at that position.
 * Alternatively, you would need to implement 7 different possibilities in
 * 3D, e.g.:
 *   x[0] is at end index           -> interpolate in x-y plane
 *   x[0] and x[1] are at end index -> interpolate along z line
 *   all are at end index           -> nearest neighbor interpolation
 * We opt to subtract a small number from x, which is computationally efficient,
 * gives cleaner code, and almost exactly the same interpolated value.
 *
 * \sa VectorAdvancedLinearInterpolateImageFunction
 *
 * \ingroup ImageFunctions ImageInterpolators
 * \ingroup ITKImageFunction
 *
 * \wiki
 * \wikiexample{ImageProcessing/LinearInterpolateImageFunction,Linearly interpolate a position in an image}
 * \endwiki
 */
template <class TInputImage, class TCoordRep = double>
class ITK_TEMPLATE_EXPORT AdvancedLinearInterpolateImageFunction
  : public LinearInterpolateImageFunction<TInputImage, TCoordRep>
{
public:
  ITK_DISALLOW_COPY_AND_MOVE(AdvancedLinearInterpolateImageFunction);

  /** Standard class typedefs. */
  using Self = AdvancedLinearInterpolateImageFunction;
  using Superclass = LinearInterpolateImageFunction<TInputImage, TCoordRep>;
  using Pointer = SmartPointer<Self>;
  using ConstPointer = SmartPointer<const Self>;

  /** Run-time type information (and related methods). */
  itkTypeMacro(AdvancedLinearInterpolateImageFunction, LinearInterpolateImageFunction);

  /** Method for creation through the object factory. */
  itkNewMacro(Self);

  /** OutputType typedef support. */
  using typename Superclass::OutputType;

  /** InputImageType typedef support. */
  using typename Superclass::InputImageType;
  using InputImageSpacingType = typename InputImageType::SpacingType;

  /** InputPixelType typedef support. */
  using typename Superclass::InputPixelType;

  /** RealType typedef support. */
  using typename Superclass::RealType;

  /** Dimension underlying input image. */
  itkStaticConstMacro(ImageDimension, unsigned int, Superclass::ImageDimension);

  /** Index typedef support. */
  using typename Superclass::IndexType;

  /** ContinuousIndex typedef support. */
  using typename Superclass::ContinuousIndexType;
  using ContinuousIndexValueType = typename ContinuousIndexType::ValueType;

  /** Derivative typedef support */
  using CovariantVectorType = CovariantVector<OutputType, Self::ImageDimension>;

  /** Method to compute the derivative. */
  CovariantVectorType
  EvaluateDerivativeAtContinuousIndex(const ContinuousIndexType & x) const;

  /** Method to compute both the value and the derivative. */
  void
  EvaluateValueAndDerivativeAtContinuousIndex(const ContinuousIndexType & x,
                                              OutputType &                value,
                                              CovariantVectorType &       deriv) const
  {
    return this->EvaluateValueAndDerivativeOptimized(Dispatch<ImageDimension>(), x, value, deriv);
  }


protected:
  AdvancedLinearInterpolateImageFunction() = default;
  ~AdvancedLinearInterpolateImageFunction() override = default;

private:
  /** Helper struct to select the correct dimension. */
  struct DispatchBase
  {};
  template <unsigned int>
  struct Dispatch : public DispatchBase
  {};

  /** Method to compute both the value and the derivative. 2D specialization. */
  void
  EvaluateValueAndDerivativeOptimized(const Dispatch<2> &,
                                      const ContinuousIndexType & x,
                                      OutputType &                value,
                                      CovariantVectorType &       deriv) const;

  /** Method to compute both the value and the derivative. 3D specialization. */
  void
  EvaluateValueAndDerivativeOptimized(const Dispatch<3> &,
                                      const ContinuousIndexType & x,
                                      OutputType &                value,
                                      CovariantVectorType &       deriv) const;

  /** Method to compute both the value and the derivative. Generic. */
  void
  EvaluateValueAndDerivativeOptimized(const DispatchBase &,
                                      const ContinuousIndexType & x,
                                      OutputType &                value,
                                      CovariantVectorType &       deriv) const
  {
    return this->EvaluateValueAndDerivativeUnOptimized(x, value, deriv);
  }


  /** Method to compute both the value and the derivative. Generic. */
  void
  EvaluateValueAndDerivativeUnOptimized(const ContinuousIndexType &, OutputType &, CovariantVectorType &) const
  {
    itkExceptionMacro("ERROR: EvaluateValueAndDerivativeAtContinuousIndex() is not implemented for this dimension ("
                      << ImageDimension << ").");
  }
};

} // end namespace itk

#ifndef ITK_MANUAL_INSTANTIATION
#  include "itkAdvancedLinearInterpolateImageFunction.hxx"
#endif

#endif