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;
240 sensorPointTemp[0] = sensorPoint[0];
241 sensorPointTemp[1] = sensorPoint[1];
243 auto outPoint = rsTransform->TransformPoint(sensorPoint);
247 groundPoint2D[0] = groundPoint[0];
248 groundPoint2D[1] = groundPoint[1];
250 double error = outPoint.EuclideanDistanceTo(outPoint);
253 m_ErrorsContainer.push_back(error);
259 m_MeanError = sum /
static_cast<double>(m_ErrorsContainer.size());
262 template <
class TImage>
266 Superclass::GenerateOutputInformation();
269 auto imagePtr = this->GetOutput();
271 if (!m_ModelUpToDate)
279 m_RMSGroundError = rmsError;
281 m_ImageMetadata = imagePtr->GetImageMetadata();
285 this->ComputeErrors();
287 m_ModelUpToDate =
true;
290 imagePtr->SetImageMetadata(m_ImageMetadata);
293 template <
class TImage>
296 Superclass::PrintSelf(os, indent);
297 os << indent <<
"UseImageGCPs: " << (m_UseImageGCPs ?
"yes" :
"no") << std::endl;
298 os << indent <<
"UseDEM: " << (m_UseDEM ?
"yes" :
"no") << std::endl;
301 os << indent <<
"MeanElevation: " << m_MeanElevation << std::endl;
303 os << indent <<
"RMS ground error: " << m_RMSGroundError << std::endl;