22 #ifndef otbSarParametricMapFunction_hxx
23 #define otbSarParametricMapFunction_hxx
26 #include "itkNumericTraits.h"
28 #include "itkMetaDataObject.h"
31 #include <vnl/algo/vnl_svd.h>
39 template <
class TInputImage,
class TCoordRep>
41 : m_PointSet(
PointSetType::New()), m_IsInitialize(false), m_ProductWidth(0), m_ProductHeight(0)
48 template <
class TInputImage,
class TCoordRep>
55 m_IsInitialize =
false;
56 m_PointSet->Initialize();
57 m_PointSet->SetPoint(0, p0);
58 m_PointSet->SetPointData(0, value);
59 EvaluateParametricCoefficient();
64 template <
class TInputImage,
class TCoordRep>
67 m_Coeff.SetSize(polynomalSize[1] + 1, polynomalSize[0] + 1);
72 template <
class TInputImage,
class TCoordRep>
75 SetPolynomalSize(
IndexType {polynomalSize[0], polynomalSize[1]});
78 template <
class TInputImage,
class TCoordRep>
84 const double p0 = point[0] / m_ProductWidth;
85 const double p1 = point[1] / m_ProductHeight;
88 for (
unsigned int ycoeff = m_Coeff.Rows(); ycoeff > 0; --ycoeff)
90 double intermediate = 0;
91 for (
unsigned int xcoeff = m_Coeff.Cols(); xcoeff > 0; --xcoeff)
94 intermediate = intermediate * p0 + m_Coeff(ycoeff - 1, xcoeff - 1);
96 result = result * p1 + intermediate;
102 template <
class TInputImage,
class TCoordRep>
111 typename PointSetType::PixelType pointValue;
112 pointValue = itk::NumericTraits<PixelType>::Zero;
114 if (pointSet->GetNumberOfPoints() == 0)
116 itkExceptionMacro(<<
"PointSet must be set before evaluating the parametric coefficient (at least one value)");
118 else if (pointSet->GetNumberOfPoints() == 1)
120 pointSet->GetPointData(0, &pointValue);
121 m_Coeff(0, 0) = pointValue;
126 auto imd = this->GetInputImage()->GetImageMetadata();
130 m_ProductHeight = this->GetInputImage()->GetLargestPossibleRegion().GetSize()[1];
134 m_ProductWidth = this->GetInputImage()->GetLargestPossibleRegion().GetSize()[0];
137 unsigned int nbRecords = pointSet->GetNumberOfPoints();
138 unsigned int nbCoef = m_Coeff.Rows() * m_Coeff.Cols();
140 vnl_matrix<double> a(nbRecords, nbCoef);
141 vnl_vector<double> b(nbRecords), bestParams(nbCoef);
147 for (
unsigned int i = 0; i < nbRecords; ++i)
149 this->GetPointSet()->GetPoint(i, &point);
150 this->GetPointSet()->GetPointData(i, &pointValue);
155 for (
unsigned int xcoeff = 0; xcoeff < m_Coeff.Cols(); ++xcoeff)
157 double xpart = std::pow(
static_cast<double>(point[0]) / m_ProductWidth,
static_cast<double>(xcoeff));
159 for (
unsigned int ycoeff = 0; ycoeff < m_Coeff.Rows(); ++ycoeff)
161 double ypart = std::pow(
static_cast<double>(point[1]) / m_ProductHeight,
static_cast<double>(ycoeff));
162 a(i, xcoeff * m_Coeff.Rows() + ycoeff) = xpart * ypart;
169 vnl_svd<double> svd(a);
170 bestParams = svd.solve(b);
172 for (
unsigned int xcoeff = 0; xcoeff < m_Coeff.Cols(); ++xcoeff)
174 for (
unsigned int ycoeff = 0; ycoeff < m_Coeff.Rows(); ++ycoeff)
176 m_Coeff(ycoeff, xcoeff) = bestParams(xcoeff * m_Coeff.Rows() + ycoeff);
181 m_IsInitialize =
true;
187 template <
class TInputImage,
class TCoordRep>
191 RealType result = itk::NumericTraits<RealType>::Zero;
195 itkExceptionMacro(<<
"Must call EvaluateParametricCoefficient before evaluating");
197 else if (m_Coeff.Rows() * m_Coeff.Cols() == 1)
199 result = m_Coeff(0, 0);
203 result = this->Horner(point);
212 template <
class TInputImage,
class TCoordRep>
215 this->Superclass::PrintSelf(os, indent);
216 os << indent <<
"Polynom coefficients: " << m_Coeff << std::endl;