21 #ifndef otbGCPsToRPCSensorModelImageFilter_hxx
22 #define otbGCPsToRPCSensorModelImageFilter_hxx
29 #include "itkMetaDataObject.h"
35 template <
class TImage>
37 : m_UseImageGCPs(false),
44 m_ModelUpToDate(false)
55 template <
class TImage>
63 template <
class TImage>
67 this->Superclass::Modified();
70 m_ModelUpToDate =
false;
74 template <
class TImage>
78 return m_GCPsContainer;
81 template <
class TImage>
85 return m_ErrorsContainer;
88 template <
class TImage>
92 m_GCPsContainer = container;
97 template <
class TImage>
101 GCPType newGCP(sensorPoint, groundPoint);
103 m_GCPsContainer.push_back(newGCP);
108 template <
class TImage>
114 groundPointWithElevation[0] = groundPoint[0];
115 groundPointWithElevation[1] = groundPoint[1];
123 if (height != height)
125 groundPointWithElevation[2] = height;
130 groundPointWithElevation[2] = m_MeanElevation;
134 this->AddGCP(sensorPoint, groundPointWithElevation);
137 template <
class TImage>
140 if (
id < m_GCPsContainer.size())
142 m_GCPsContainer.erase(m_GCPsContainer.begin() +
id);
148 template <
class TImage>
151 m_GCPsContainer.clear();
155 template <
class TImage>
159 m_UseImageGCPs = use;
161 this->LoadImageGCPs();
164 template <
class TImage>
168 typename TImage::Pointer imagePtr = this->GetOutput();
171 for (
unsigned int i = 0; i < imagePtr->GetGCPCount(); ++i)
174 typename TImage::IndexType index;
175 index[0] =
static_cast<long int>(imagePtr->GetGCPCol(i));
176 index[1] =
static_cast<long int>(imagePtr->GetGCPRow(i));
180 imagePtr->TransformIndexToPhysicalPoint(index, sensorPoint);
185 groundPoint[0] = imagePtr->GetGCPX(i);
186 groundPoint[1] = imagePtr->GetGCPY(i);
187 groundPoint[2] = imagePtr->GetGCPZ(i);
192 unsigned int currentGCP = 0;
194 while ((currentGCP < m_GCPsContainer.size()) && !found)
196 if ((m_GCPsContainer[currentGCP].first == sensorPoint) && (m_GCPsContainer[currentGCP].second == groundPoint))
200 m_GCPsContainer.erase(m_GCPsContainer.begin() + currentGCP);
209 if (m_UseImageGCPs && !found)
210 this->AddGCP(sensorPoint, groundPoint);
216 template <
class TImage>
221 RSTransformType::Pointer rsTransform = RSTransformType::New();
222 rsTransform->SetInputImageMetadata(&m_ImageMetadata);
224 rsTransform->InstantiateTransform();
230 m_ErrorsContainer.clear();
232 for (
unsigned int i = 0; i < m_GCPsContainer.size(); ++i)
235 const auto & sensorPoint = m_GCPsContainer[i].first;
236 const auto & groundPoint = m_GCPsContainer[i].second;
238 auto outPoint = rsTransform->TransformPoint(sensorPoint);
242 groundPoint2D[0] = groundPoint[0];
243 groundPoint2D[1] = groundPoint[1];
245 double error = outPoint.EuclideanDistanceTo(outPoint);
248 m_ErrorsContainer.push_back(error);
254 m_MeanError = sum /
static_cast<double>(m_ErrorsContainer.size());
257 template <
class TImage>
261 Superclass::GenerateOutputInformation();
264 auto imagePtr = this->GetOutput();
266 if (!m_ModelUpToDate)
274 m_RMSGroundError = rmsError;
276 m_ImageMetadata = imagePtr->GetImageMetadata();
280 this->ComputeErrors();
282 m_ModelUpToDate =
true;
285 imagePtr->SetImageMetadata(m_ImageMetadata);
288 template <
class TImage>
291 Superclass::PrintSelf(os, indent);
292 os << indent <<
"UseImageGCPs: " << (m_UseImageGCPs ?
"yes" :
"no") << std::endl;
293 os << indent <<
"UseDEM: " << (m_UseDEM ?
"yes" :
"no") << std::endl;
296 os << indent <<
"MeanElevation: " << m_MeanElevation << std::endl;
298 os << indent <<
"RMS ground error: " << m_RMSGroundError << std::endl;
static DEMHandler & GetInstance()
double GetHeightAboveEllipsoid(double lon, double lat) const
void PrintSelf(std::ostream &os, itk::Indent indent) const override
std::vector< double > ErrorsContainerType
ErrorsContainerType & GetErrorsContainer()
void RemoveGCP(unsigned int id)
GCPsContainerType & GetGCPsContainer()
void Modified() const override
void AddGCP(const Point2DType &sensorPoint, const Point3DType &groundPoint)
std::vector< GCPType > GCPsContainerType
GCPsToRPCSensorModelImageFilter()
itk::Point< double, 2 > Point2DType
void SetUseImageGCPs(bool use)
void SetGCPsContainer(const GCPsContainerType &container)
void GenerateOutputInformation() override
~GCPsToRPCSensorModelImageFilter() override
std::pair< Point2DType, Point3DType > GCPType
itk::Point< double, 3 > Point3DType
void Solve(const GCPsContainerType &gcpContainer, double &rmsError, Projection::RPCParam &outputParams)
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Coefficients for RPC model (quite similar to GDALRPCInfo)