Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Isis 3 Programmer Reference
OsirisRexDistortionMap.cpp
1
6
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include <QDebug>
10#include <QtGlobal>
11#include <QtMath>
12
13#include "NaifStatus.h"
14#include "OsirisRexDistortionMap.h"
15#include "CameraFocalPlaneMap.h"
16
17namespace Isis {
34 : CameraDistortionMap(parent, zDirection) {
35
36 // Set up our own focal plane map from the camera model. NOTE!!!
37 // The CameraFocalPlaneMap must be set in the Camera object
38 // prior to calling distortion model!!!
39 if ( !parent->FocalPlaneMap() ) {
40 QString mess = "FocalPlaneMap must be set in the Camera object prior to"
41 " initiating this distortion model!";
42 throw IException(IException::Programmer, mess, _FILEINFO_);
43 }
44
45 // Replicate focal plane map for proper image coordinate conversions
46 m_focalMap.reset(new CameraFocalPlaneMap(*parent->FocalPlaneMap()));
47
50
51 m_pixelPitch = p_camera->PixelPitch();
52 m_debug = false;
53 }
54
55
61
62
85 bool OsirisRexDistortionMap::SetDistortion(int naifIkCode, QString filter) {
86 // Load distortion coefficients, including filter if we have it.
87 QString odkkey;
88
89 if (filter.toUpper().compare("UNKNOWN") == 0) {
90 odkkey = "INS" + toString(naifIkCode) + "_OD_K";
91 }
92 else {
93 odkkey = "INS" + toString(naifIkCode) + "_OD_K_" + filter.trimmed().toUpper();
94 }
95
96 try {
97 for (int i = 0; i < 5; ++i) {
98 p_odk.push_back(p_camera->Spice::getDouble(odkkey, i));
99 }
100 }
101 catch (IException &e) {
102 // This means that this is an older image without a filter provided
103 // don't update p_odk, we will not apply the distortion in this case
106 if ( m_debug ) std::cout << "Bad Distortion Model - set to -1\n";
107 return (false);
108 }
109
110 // Load center-of-distortion coordinates, including filter if we have it
111 QString odcenterkey;
112 if (filter.toUpper().compare("UNKNOWN") == 0) {
113 odcenterkey = "INS" + toString(naifIkCode) + "_OD_CENTER";
114 }
115 else {
116 odcenterkey = "INS" + toString(naifIkCode) + "_OD_CENTER_" + filter.trimmed().toUpper();
117 }
118 m_distortionOriginSample = p_camera->Spice::getDouble(odcenterkey, 0);
119 m_distortionOriginLine = p_camera->Spice::getDouble(odcenterkey, 1);
120
121 try {
122 QString dbKey = "INS" + toString(naifIkCode) + "_DEBUG_MODEL";
123 m_debug = toBool(p_camera->getString(dbKey, 0));
124 } catch (IException &ie) {
125 m_debug = false;
126 }
127
128
129 if ( m_debug) {
130 std::cout << "\nModel Initialized! - IKCode = " << naifIkCode
131 << ", Filter = " << filter << "\n";
132 std::cout << "Detector Center Samp = " << m_detectorOriginSample
133 << ", Line = " << m_detectorOriginLine << "\n";
134 std::cout << "Distortion Center Samp = " << m_distortionOriginSample
135 << ", Line = " << m_distortionOriginLine << "\n";
136 }
137
138 return (true);
139 }
140
141
154 bool OsirisRexDistortionMap::SetFocalPlane(double dx, double dy) {
155 p_focalPlaneX = dx;
156 p_focalPlaneY = dy;
157
158 if ( m_debug ) {
159 m_focalMap->SetFocalPlane(dx, dy);
160 std::cout << "\nCompute Undistorted at dx = " << dx
161 << ", dy = " << dy << "\n";
162 std::cout << "DLine = " << m_focalMap->DetectorLine()
163 << ", DSamp = " << m_focalMap->DetectorSample() << "\n";
164 }
165
166 // Only apply the distortion if we have the correct number of coefficients
167 if (p_odk.size() < 2) {
170 return true;
171 }
172
175 if ( m_debug) {
176 std::cout << "Detector Center Samp = " << m_detectorOriginSample
177 << ", Line = " << m_detectorOriginLine << "\n";
178 std::cout << "Distortion Center Samp = " << m_distortionOriginSample
179 << ", Line = " << m_distortionOriginLine << "\n";
180 std::cout << "x0 = " << x0 << ", y0 = " << y0 << "\n";
181 std::cout << "xP = " << x0 / m_pixelPitch << ", yP = " << y0 / m_pixelPitch << "\n";
182 }
183 double xt = dx;
184 double yt = dy;
185
186 double xx, yy, r, rr, rrr, rrrr;
187 double xdistortion, ydistortion;
188 double xdistorted, ydistorted;
189 double xprevious, yprevious;
190 double drOverR;
191
192 xprevious = 1000000.0;
193 yprevious = 1000000.0;
194
195 double tolerance = 0.000001;
196
197 bool bConverged = false;
198
199 // Iterating to introduce distortion...
200 // We stop when the difference between distorted coordinates
201 // in successive iterations is at or below the given tolerance.
202 int nrevs(0);
203 for(int i = 0; i < 50; i++) {
204 xx = (xt-x0) * (xt-x0);
205 yy = (yt-y0) * (yt-y0);
206 rr = xx + yy;
207 r = qSqrt(rr);
208 rrr = rr * r;
209 rrrr = rr * rr;
210
211 drOverR = p_odk[0] + p_odk[1]*r + p_odk[2]*rr + p_odk[3]*rrr + p_odk[4]*rrrr;
212
213 // distortion at the current point location
214 xdistortion = drOverR * (xt-x0);
215 ydistortion = drOverR * (yt-y0);
216
217 // updated image coordinates
218 xt = dx - xdistortion;
219 yt = dy - ydistortion;
220
221 xdistorted = xt;
222 ydistorted = yt;
223
224 // check for convergence
225 if((fabs(xt - xprevious) <= tolerance) && (fabs(yt - yprevious) <= tolerance)) {
226 bConverged = true;
227 break;
228 }
229
230
231 if ( m_debug ) {
232 std::cout << "i=" << i << ", xt=" << xt << ", yt=" << yt
233 << ", xdist=" << xdistortion
234 << ", ydist=" << ydistortion
235 << ", xtol=" << (xt - xprevious)
236 << ", ytol=" << (yt - yprevious) << "\n";
237 }
238
239 nrevs++;
240 xprevious = xt;
241 yprevious = yt;
242
243 }
244
245 if ( m_debug ) {
246 std::cout << "Loop terminated after " << nrevs << " iterations! - converged? "
247 << ( ( bConverged ) ? "Yes!" : "No-(") << "\n";
248 }
249
250 if ( bConverged ) {
251 p_undistortedFocalPlaneX = xdistorted;
252 p_undistortedFocalPlaneY = ydistorted;
253 }
254
255 if ( m_debug ) {
256 m_focalMap->SetFocalPlane(p_undistortedFocalPlaneX, p_undistortedFocalPlaneY);
257 std::cout << "Undistorted ux = " << p_undistortedFocalPlaneX
258 << ", uy = " << p_undistortedFocalPlaneY << "\n";
259 std::cout << "ULine = " << m_focalMap->DetectorLine()
260 << ", USamp = " << m_focalMap->DetectorSample() << "\n";
261 }
262 return bConverged;
263 }
264
265
281 const double uy) {
284
285 if ( m_debug ) {
286 m_focalMap->SetFocalPlane(ux, uy);
287 std::cout << "\nCompute Distorted at ux = " << ux
288 << ", uy = " << uy << "\n";
289 std::cout << "ULine = " << m_focalMap->DetectorLine()
290 << ", USamp = " << m_focalMap->DetectorSample() << "\n";
291 }
292
293 // Only apply the distortion if we have the correct number of coefficients.
294 if (p_odk.size() < 2) {
295 p_focalPlaneX = ux;
296 p_focalPlaneY = uy;
297 return true;
298 }
301
302 if ( m_debug ) {
303 std::cout << "Detector Center Samp = " << m_detectorOriginSample
304 << ", Line = " << m_detectorOriginLine << "\n";
305 std::cout << "Distortion Center Samp = " << m_distortionOriginSample
306 << ", Line = " << m_distortionOriginLine << "\n";
307 std::cout << "x0 = " << x0 << ", y0 = " << y0 << "\n";
308 std::cout << "xP = " << x0 / m_pixelPitch << ", yP = " << y0 / m_pixelPitch << "\n";
309 }
310
311 // Compute the distance from the focal plane center.
312 double x = ux;
313 double y = uy;
314 double r = qSqrt(((x-x0) * (x-x0)) + ((y - y0) * (y-y0)));
315
316 double r2 = r*r;
317 double r3 = r2*r;
318 double r4 = r2*r2;
319
320 double drOverR = p_odk[0] + p_odk[1]*r + p_odk[2]*r2 + p_odk[3]*r3 + p_odk[4]*r4;
321
322 p_focalPlaneX = x + drOverR * (x-x0);
323 p_focalPlaneY = y + drOverR * (y-y0);
324
325 if ( m_debug ) {
326 m_focalMap->SetFocalPlane(p_focalPlaneX, p_focalPlaneY);
327 std::cout << "Distorted dx = " << p_focalPlaneX
328 << ", dy = " << p_focalPlaneY << "\n";
329 std::cout << "DLine = " << m_focalMap->DetectorLine()
330 << ", DSamp = " << m_focalMap->DetectorSample() << "\n";
331 }
332 return true;
333 }
334}
CameraDistortionMap(Camera *parent, double zDirection=1.0)
Camera distortion map constructor.
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.
CameraFocalPlaneMap * FocalPlaneMap()
Returns a pointer to the CameraFocalPlaneMap object.
Definition Camera.cpp:2866
virtual bool SetFocalPlane(double dx, double dy)
Compute undistorted focal plane x/y.
virtual ~OsirisRexDistortionMap()
Default Destructor.
OsirisRexDistortionMap(Camera *parent, double zDirection=1.0)
OSIRIS REx Camera distortion map constructor.
double m_distortionOriginSample
The distortion's origin sample coordinate.
virtual bool SetDistortion(int naifIkCode, QString filter="UNKNOWN")
Load distortion coefficients and center-of-distortion for OCAMS.
double m_detectorOriginLine
The origin of the detector's line coordinate.
virtual bool SetUndistortedFocalPlane(double ux, double uy)
Compute distorted focal plane x/y.
double m_pixelPitch
The pixel pitch for OCAMS.
double m_distortionOriginLine
The distortion's origin line coordinate.
double m_detectorOriginSample
The origin of the detector's sample coordinate.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(const LinearAlgebra::Vector &vector, int precision)
A global function to format LinearAlgebra::Vector as a QString with the given precision.