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>
56 typename itk::InterpolateImageFunction<TInputImage, TCoordRep>::SizeType radius({m_Radius,m_Radius});
60 template <
class TInputImage,
class TCoordRep>
66 template <
class TInputImage,
class TCoordRep>
72 template <
class TInputImage,
class TCoordRep>
76 double offset, dist, position, step;
80 offset = indexValue - itk::Math::Floor<IndexValueType>(indexValue + 0.5);
83 step = 4. /
static_cast<double>(2 * m_Radius);
84 position = -
static_cast<double>(m_Radius) * step;
87 auto alpha = this->m_Alpha;
89 for (
unsigned int i = 0; i < m_WinSize; ++i)
92 dist = std::abs(position - offset * step);
99 coef = (alpha + 2.) * dist * dist * dist - (alpha + 3.) * dist * dist + 1;
103 coef = alpha * dist * dist * dist - 5 * alpha * dist * dist + 8 * alpha * dist - 4 * alpha;
117 for (
unsigned int i = 0; i < m_WinSize; ++i)
123 template <
class TInputImage,
class TCoordRep>
126 Superclass::PrintSelf(os, indent);
129 template <
class TInputImage,
class TCoordRep>
138 RealType value = itk::NumericTraits<RealType>::Zero;
140 const auto& BCOCoefX = this->EvaluateCoef(index[0]);
141 const auto& BCOCoefY = this->EvaluateCoef(index[1]);
144 for (dim = 0; dim < ImageDimension; dim++)
146 baseIndex[dim] = itk::Math::Floor<IndexValueType>(index[dim] + 0.5);
149 for (
unsigned int i = 0; i < this->m_WinSize; ++i)
152 for (
unsigned int j = 0; j < this->m_WinSize; ++j)
155 neighIndex[0] = baseIndex[0] + i - this->m_Radius;
156 neighIndex[1] = baseIndex[1] + j - this->m_Radius;
158 if (neighIndex[0] > this->m_EndIndex[0])
160 neighIndex[0] = this->m_EndIndex[0];
162 if (neighIndex[0] < this->m_StartIndex[0])
164 neighIndex[0] = this->m_StartIndex[0];
166 if (neighIndex[1] > this->m_EndIndex[1])
168 neighIndex[1] = this->m_EndIndex[1];
170 if (neighIndex[1] < this->m_StartIndex[1])
172 neighIndex[1] = this->m_StartIndex[1];
174 lineRes +=
static_cast<RealType>(this->GetInputImage()->GetPixel(neighIndex)) * BCOCoefY[j];
176 value += lineRes * BCOCoefX[i];
183 template <
typename TPixel,
unsigned int VImageDimension,
class TCoordRep>
186 Superclass::PrintSelf(os, indent);
189 template <
typename TPixel,
unsigned int VImageDimension,
class TCoordRep>
193 typedef typename itk::NumericTraits<InputPixelType>::ScalarRealType ScalarRealType;
197 unsigned int componentNumber = this->GetInputImage()->GetNumberOfComponentsPerPixel();
202 boost::container::small_vector<ScalarRealType, 8> lineRes(componentNumber);
205 output.Fill(itk::NumericTraits<ScalarRealType>::Zero);
207 const auto& BCOCoefX = this->EvaluateCoef(index[0]);
208 const auto& BCOCoefY = this->EvaluateCoef(index[1]);
211 for (dim = 0; dim < ImageDimension; dim++)
213 baseIndex[dim] = itk::Math::Floor<IndexValueType>(index[dim] + 0.5);
216 for (
unsigned int i = 0; i < this->m_WinSize; ++i)
218 std::fill(lineRes.begin(), lineRes.end(), itk::NumericTraits<ScalarRealType>::Zero);
219 for (
unsigned int j = 0; j < this->m_WinSize; ++j)
222 neighIndex[0] = baseIndex[0] + i - this->m_Radius;
223 neighIndex[1] = baseIndex[1] + j - this->m_Radius;
224 if (neighIndex[0] > this->m_EndIndex[0])
226 neighIndex[0] = this->m_EndIndex[0];
228 if (neighIndex[0] < this->m_StartIndex[0])
230 neighIndex[0] = this->m_StartIndex[0];
232 if (neighIndex[1] > this->m_EndIndex[1])
234 neighIndex[1] = this->m_EndIndex[1];
236 if (neighIndex[1] < this->m_StartIndex[1])
238 neighIndex[1] = this->m_StartIndex[1];
241 const InputPixelType& pixel = this->GetInputImage()->GetPixel(neighIndex);
242 for (
unsigned int k = 0; k < componentNumber; ++k)
244 lineRes[k] += pixel.GetElement(k) * BCOCoefY[j];
247 for (
unsigned int k = 0; k < componentNumber; ++k)
249 output[k] += lineRes[k] * BCOCoefX[i];
CoefContainerType EvaluateCoef(const ContinuousIndexValueType &indexValue) const
virtual void SetRadius(unsigned int radius)
virtual double GetAlpha() const
boost::container::small_vector< double, 7 > CoefContainerType
void PrintSelf(std::ostream &os, itk::Indent indent) const override
TCoordRep ContinuousIndexValueType
virtual SizeType GetRadius() const
virtual void SetAlpha(double alpha)
Superclass::ContinuousIndexType ContinuousIndexType
Superclass::IndexType IndexType
Superclass::InputPixelType InputPixelType
Superclass::OutputType OutputType
Interpolate an image at specified positions using bicubic interpolation.
Superclass::IndexType IndexType
Superclass::ContinuousIndexType ContinuousIndexType
Superclass::OutputType OutputType
OutputType EvaluateAtContinuousIndex(const ContinuousIndexType &index) const override
Superclass::RealType RealType
void PrintSelf(std::ostream &os, itk::Indent indent) const override
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.