21 #ifndef otbBCOInterpolateImageFunction_hxx
22 #define otbBCOInterpolateImageFunction_hxx
26 #include "itkNumericTraits.h"
31 template <
class TInputImage,
class TCoordRep>
34 Superclass::PrintSelf(os, indent);
35 os << indent <<
"Radius: " << m_Radius << std::endl;
36 os << indent <<
"Alpha: " << m_Alpha << std::endl;
39 template <
class TInputImage,
class TCoordRep>
44 itkExceptionMacro(<<
"Radius must be strictly greater than 1");
49 m_WinSize = 2 * m_Radius + 1;
53 template <
class TInputImage,
class TCoordRep>
59 template <
class TInputImage,
class TCoordRep>
65 template <
class TInputImage,
class TCoordRep>
71 template <
class TInputImage,
class TCoordRep>
75 double offset, dist, position, step;
79 offset = indexValue - itk::Math::Floor<IndexValueType>(indexValue + 0.5);
82 step = 4. /
static_cast<double>(2 * m_Radius);
83 position = -
static_cast<double>(m_Radius) * step;
86 auto alpha = this->m_Alpha;
88 for (
unsigned int i = 0; i < m_WinSize; ++i)
91 dist = std::abs(position - offset * step);
98 coef = (alpha + 2.) * dist * dist * dist - (alpha + 3.) * dist * dist + 1;
102 coef = alpha * dist * dist * dist - 5 * alpha * dist * dist + 8 * alpha * dist - 4 * alpha;
116 for (
unsigned int i = 0; i < m_WinSize; ++i)
122 template <
class TInputImage,
class TCoordRep>
125 Superclass::PrintSelf(os, indent);
128 template <
class TInputImage,
class TCoordRep>
137 RealType value = itk::NumericTraits<RealType>::Zero;
139 const auto& BCOCoefX = this->EvaluateCoef(index[0]);
140 const auto& BCOCoefY = this->EvaluateCoef(index[1]);
143 for (dim = 0; dim < ImageDimension; dim++)
145 baseIndex[dim] = itk::Math::Floor<IndexValueType>(index[dim] + 0.5);
148 for (
unsigned int i = 0; i < this->m_WinSize; ++i)
151 for (
unsigned int j = 0; j < this->m_WinSize; ++j)
154 neighIndex[0] = baseIndex[0] + i - this->m_Radius;
155 neighIndex[1] = baseIndex[1] + j - this->m_Radius;
157 if (neighIndex[0] > this->m_EndIndex[0])
159 neighIndex[0] = this->m_EndIndex[0];
161 if (neighIndex[0] < this->m_StartIndex[0])
163 neighIndex[0] = this->m_StartIndex[0];
165 if (neighIndex[1] > this->m_EndIndex[1])
167 neighIndex[1] = this->m_EndIndex[1];
169 if (neighIndex[1] < this->m_StartIndex[1])
171 neighIndex[1] = this->m_StartIndex[1];
173 lineRes +=
static_cast<RealType>(this->GetInputImage()->GetPixel(neighIndex)) * BCOCoefY[j];
175 value += lineRes * BCOCoefX[i];
182 template <
typename TPixel,
unsigned int VImageDimension,
class TCoordRep>
185 Superclass::PrintSelf(os, indent);
188 template <
typename TPixel,
unsigned int VImageDimension,
class TCoordRep>
192 typedef typename itk::NumericTraits<InputPixelType>::ScalarRealType ScalarRealType;
196 unsigned int componentNumber = this->GetInputImage()->GetNumberOfComponentsPerPixel();
201 boost::container::small_vector<ScalarRealType, 8> lineRes(componentNumber);
204 output.Fill(itk::NumericTraits<ScalarRealType>::Zero);
206 const auto& BCOCoefX = this->EvaluateCoef(index[0]);
207 const auto& BCOCoefY = this->EvaluateCoef(index[1]);
210 for (dim = 0; dim < ImageDimension; dim++)
212 baseIndex[dim] = itk::Math::Floor<IndexValueType>(index[dim] + 0.5);
215 for (
unsigned int i = 0; i < this->m_WinSize; ++i)
217 std::fill(lineRes.begin(), lineRes.end(), itk::NumericTraits<ScalarRealType>::Zero);
218 for (
unsigned int j = 0; j < this->m_WinSize; ++j)
221 neighIndex[0] = baseIndex[0] + i - this->m_Radius;
222 neighIndex[1] = baseIndex[1] + j - this->m_Radius;
223 if (neighIndex[0] > this->m_EndIndex[0])
225 neighIndex[0] = this->m_EndIndex[0];
227 if (neighIndex[0] < this->m_StartIndex[0])
229 neighIndex[0] = this->m_StartIndex[0];
231 if (neighIndex[1] > this->m_EndIndex[1])
233 neighIndex[1] = this->m_EndIndex[1];
235 if (neighIndex[1] < this->m_StartIndex[1])
237 neighIndex[1] = this->m_StartIndex[1];
240 const InputPixelType& pixel = this->GetInputImage()->GetPixel(neighIndex);
241 for (
unsigned int k = 0; k < componentNumber; ++k)
243 lineRes[k] += pixel.GetElement(k) * BCOCoefY[j];
246 for (
unsigned int k = 0; k < componentNumber; ++k)
248 output[k] += lineRes[k] * BCOCoefX[i];