Isis 3 Programmer Reference
OsirisRexOcamsDistortionMap.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include <QDebug>
10#include <QtGlobal>
11#include <QtMath>
12
13#include "NaifStatus.h"
14#include "OsirisRexOcamsDistortionMap.h"
15#include "CameraFocalPlaneMap.h"
16
17namespace Isis {
34 double zDirection)
35 : CameraDistortionMap(parent, zDirection) {
36
40 p_tolerance = 1.0E-6;
41 p_debug = false;
42
43 // Set up our own focal plane map from the camera model. NOTE!!!
44 // The CameraFocalPlaneMap must be set in the Camera object
45 // prior to calling distortion model!!!
46 if ( !parent->FocalPlaneMap() ) {
47 QString mess = "FocalPlaneMap must be set in the Camera object prior to"
48 " initiating this distortion model!";
49 throw IException(IException::Programmer, mess, _FILEINFO_);
50 }
51
52 m_focalMap.reset(new CameraFocalPlaneMap(*parent->FocalPlaneMap()));
53 }
54
55
61
62
86 // Load distortion coefficients, including filter if we have it.
87 QString odkkey;
88
89
90 odkkey = "INS" + toString(naifIkCode) + "_OD_K";
91 try {
92 for (int i = 0; i < 5; ++i) {
93 p_odk.push_back(p_camera->Spice::getDouble(odkkey, i));
94 }
95 }
96 catch (IException &e) {
97 }
98
99 // Load center-of-distortion coordinates, including filter if we have it
100 QString odcenterkey;
101 odcenterkey = "INS" + toString(naifIkCode) + "_OD_CENTER";
102 m_distortionOriginSample = p_camera->Spice::getDouble(odcenterkey, 0);
103 m_distortionOriginLine = p_camera->Spice::getDouble(odcenterkey, 1);
104
105 QString tolKey = "INS" + toString(naifIkCode) + "_TOLERANCE";
106 p_tolerance = p_camera->getDouble(tolKey, 0);
107
108 QString dbKey = "INS" + toString(naifIkCode) + "_DEBUG_MODEL";
109 p_debug = toBool(p_camera->getString(dbKey, 0));
110 }
111
112
126 if ( p_debug )std::cout << "\nUndistorting at " << dx << ", " << dy << "\n";
127 p_focalPlaneX = dx;
128 p_focalPlaneY = dy;
129
130 if ( p_debug ) {
131 std::cout << "Detector sample=" << p_camera->FocalPlaneMap()->DetectorSample()
132 << ", line=" << p_camera->FocalPlaneMap()->DetectorLine()<< "\n";
133 }
134
135 // Only apply the distortion if we have the correct number of coefficients
136 if (p_odk.size() < 2) {
139 return true;
140 }
141
144 if ( p_debug ) std::cout << "x0=" << x0 << ", y0=" << y0 << "\n";
145
146 double xt = dx;
147 double yt = dy;
148
149 double xx, yy, r, rr, rrr, rrrr;
150 double xdistortion, ydistortion;
151 double xdistorted, ydistorted;
152 double xprevious, yprevious;
153 double drOverR;
154
155 xprevious = 1000000.0;
156 yprevious = 1000000.0;
157
158 double tolerance = p_tolerance;
159
160 bool bConverged = false;
161
162 // Iterating to introduce distortion...
163 // We stop when the difference between distorted coordinates
164 // in successive iterations is at or below the given tolerance.
165 for(int i = 0; i < 50; i++) {
166 xx = (xt-x0) * (xt-x0);
167 yy = (yt-y0) * (yt-y0);
168 rr = xx + yy;
169 r = qSqrt(rr);
170 rrr = rr * r;
171 rrrr = rr * rr;
172
173 drOverR = p_odk[0] + p_odk[1]*r + p_odk[2]*rr + p_odk[3]*rrr + p_odk[4]*rrrr;
174
175 // distortion at the current point location
176 xdistortion = drOverR * (xt-x0);
177 ydistortion = drOverR * (yt-y0);
178
179 // updated image coordinates
180 xt = dx - xdistortion;
181 yt = dy - ydistortion;
182
183 xdistorted = xt;
184 ydistorted = yt;
185
186 // check for convergence
187 if((fabs(xt - xprevious) <= tolerance) && (fabs(yt - yprevious) <= tolerance)) {
188 bConverged = true;
189 break;
190 }
191
192 xprevious = xt;
193 yprevious = yt;
194 }
195
196 if(bConverged) {
197 p_undistortedFocalPlaneX = xdistorted;
198 p_undistortedFocalPlaneY = ydistorted;
199 std::cout << "Converged ux=" << p_undistortedFocalPlaneX
200 << ", uy=" << p_undistortedFocalPlaneY << "\n";
201 m_focalMap->SetFocalPlane(xdistorted, ydistorted);
202
203 if ( p_debug ) {
204 std::cout << "Detector sample=" << m_focalMap->DetectorSample()
205 << ", line=" << m_focalMap->DetectorLine()<< "\n";
206 }
207 }
208 if ( p_debug ) std::cout << "We out!\n";
209 return bConverged;
210 }
211
212
228 const double uy) {
229 if ( p_debug ) std::cout << "\nDistorting at " << ux << ", " << uy << "\n";
232 if ( p_debug ) {
233 std::cout << "Detector sample=" << p_camera->FocalPlaneMap()->DetectorSample()
234 << ", line=" << p_camera->FocalPlaneMap()->DetectorLine()<< "\n";
235 }
236
237 // Only apply the distortion if we have the correct number of coefficients.
238 if (p_odk.size() < 2) {
239 p_focalPlaneX = ux;
240 p_focalPlaneY = uy;
241 return true;
242 }
245
246 // Compute the distance from the focal plane center. If we are
247 // close to the center then no distortion is required
248 double x = ux;
249 double y = uy;
250 double r = qSqrt(((x-x0) * (x-x0)) + ((y - y0) * (y-y0)));
251
252 if (r <= 1.0E-6) {
253 p_focalPlaneX = ux;
254 p_focalPlaneY = uy;
255 return true;
256 }
257
258 double r2 = r*r;
259 double r3 = r2*r;
260 double r4 = r2*r2;
261
262 double drOverR = p_odk[0] + p_odk[1]*r + p_odk[2]*r2 + p_odk[3]*r3 + p_odk[4]*r4;
263
264 p_focalPlaneX = x + drOverR * (x-x0);
265 p_focalPlaneY = y + drOverR * (y-y0);
266 std::cout << "Final at " << p_focalPlaneX << ", " << p_focalPlaneY << "\n";
267 m_focalMap->SetFocalPlane(p_focalPlaneX, p_focalPlaneY);
268 if ( p_debug ) {
269 std::cout << "Detector sample=" << m_focalMap->DetectorSample()
270 << ", line=" << m_focalMap->DetectorLine()<< "\n";
271 }
272 return true;
273 }
274}
275
Distort/undistort focal plane coordinates.
double p_focalPlaneX
Distorted focal plane x.
double p_undistortedFocalPlaneX
Undistorted focal plane x.
std::vector< double > p_odk
Vector of distortion coefficients.
double p_undistortedFocalPlaneY
Undistorted focal plane y.
Camera * p_camera
The camera to distort/undistort.
double p_focalPlaneY
Distorted focal plane y.
Convert between distorted focal plane and detector coordinates.
double PixelPitch() const
Returns the pixel pitch.
Definition Camera.cpp:2772
CameraFocalPlaneMap * FocalPlaneMap()
Returns a pointer to the CameraFocalPlaneMap object.
Definition Camera.cpp:2866
Isis exception class.
Definition IException.h:91
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
double m_detectorOriginLine
The origin of the detector's line coordinate.
virtual bool SetFocalPlane(double dx, double dy)
Compute undistorted focal plane x/y.
virtual ~OsirisRexOcamsDistortionMap()
Default Destructor.
double m_distortionOriginLine
The distortion's origin line coordinate.
double m_distortionOriginSample
The distortion's origin sample coordinate.
virtual void SetDistortion(int naifIkCode)
Load distortion coefficients and center-of-distortion for OCAMS.
double m_pixelPitch
The pixel pitch for OCAMS.
virtual bool SetUndistortedFocalPlane(double ux, double uy)
Compute distorted focal plane x/y.
OsirisRexOcamsDistortionMap(Camera *parent, double zDirection=1.0)
OSIRIS REx Camera distortion map constructor.
double m_detectorOriginSample
The origin of the detector's sample coordinate.
QString getString(const QString &key, int index=0)
This returns a value from the NAIF text pool.
Definition Spice.cpp:1273
SpiceDouble getDouble(const QString &key, int index=0)
This returns a value from the NAIF text pool.
Definition Spice.cpp:1046
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
bool toBool(const QString &string)
Global function to convert from a string to a boolean.
Definition IString.cpp:38