USGS

Isis 3.0 Object Programmers' Reference

Home

MarciDistortionMap.cpp
Go to the documentation of this file.
1 
23 #include <cmath>
24 
25 #include "IString.h"
26 #include "MarciDistortionMap.h"
27 
28 namespace Isis {
42  QString odkkey = "INS" + toString(naifIkCode) + "_DISTORTION_COEFFS";
43 
44  for(int i = 0; i < 4; i++) {
45  p_odk.push_back(p_camera->getDouble(odkkey, i));
46  }
47  }
48 
60  bool MarciDistortionMap::SetFocalPlane(const double dx, const double dy) {
61  p_focalPlaneX = dx;
62  p_focalPlaneY = dy;
63 
64  double dxPix = p_focalPlaneX / p_camera->PixelPitch();
65  double dyPix = p_focalPlaneY / p_camera->PixelPitch();
66 
67  // Get the distance from the focal plane center and if we are close
68  // then skip the distortion
69  double radialDist2 = (dxPix * dxPix) + (dyPix * dyPix);
70 
71  if(radialDist2 <= 1.0E-3) {
72  p_undistortedFocalPlaneX = dx;
73  p_undistortedFocalPlaneY = dy;
74  return true;
75  }
76 
77  // Ok we need to apply distortion correction
78  double radialDist4 = radialDist2 * radialDist2;
79  double radialDist6 = radialDist4 * radialDist2;
80 
81  double uRadialDist = p_odk[0] + radialDist2 * p_odk[1] +
82  radialDist4 * p_odk[2] +
83  radialDist6 * p_odk[3];
84 
85  // double radialDist = sqrt(radialDist2);
86  double uxPix = dxPix * uRadialDist;
87  double uyPix = dyPix * uRadialDist;
88 
89 
90  p_undistortedFocalPlaneX = uxPix * p_camera->PixelPitch();
91  p_undistortedFocalPlaneY = uyPix * p_camera->PixelPitch();
92 
93  return true;
94  }
95 
109  const double uy) {
110  p_undistortedFocalPlaneX = ux;
111  p_undistortedFocalPlaneY = uy;
112 
113  double uxPix = ux / p_camera->PixelPitch();
114  double uyPix = uy / p_camera->PixelPitch();
115 
116  double dxPix = GuessDx(uxPix);
117  double dyPix = uyPix;
118 
119  // Get the distance from the focal plane center and if we are close
120  // then skip the distortion
121  double Ru = sqrt((uxPix * uxPix) + (uyPix * uyPix));
122 
123  if(Ru <= 1.0E-6) {
124  p_focalPlaneX = ux;
125  p_focalPlaneY = uy;
126  return true;
127  }
128 
129  double delta = 1.0;
130  int iter = 0;
131 
132  double Rd = sqrt((dxPix * dxPix) + (dyPix * dyPix));
133 
134  while(fabs(delta) > 1E-9) {
135  if(fabs(delta) > 1E30 || iter > 50) {
136  return false;
137  }
138 
139  double Rd2 = Rd * Rd;
140  double Rd3 = Rd2 * Rd;
141  double Rd4 = Rd3 * Rd;
142  double Rd5 = Rd4 * Rd;
143  double Rd6 = Rd5 * Rd;
144 
145  double fRd = p_odk[0] + Rd2 * p_odk[1] +
146  Rd4 * p_odk[2] +
147  Rd6 * p_odk[3] - Ru * (1.0 / Rd);
148 
149  double fRd2 = 2 * p_odk[1] * Rd +
150  4 * p_odk[2] * Rd3 +
151  6 * p_odk[3] * Rd5 +
152  Ru * (1.0 / Rd2);
153 
154  delta = fRd / fRd2;
155 
156  Rd = Rd - delta;
157 
158  iter ++;
159  }
160 
161  dxPix = uxPix * (Rd / Ru);
162  dyPix = uyPix * (Rd / Ru);
163 
164  p_focalPlaneX = dxPix * p_camera->PixelPitch();
165  p_focalPlaneY = dyPix * p_camera->PixelPitch();
166 
167  return true;
168  }
169 
170  double MarciDistortionMap::GuessDx(double uX) {
171  // We're using natural log fits, but if uX < 1 the fit doesnt work
172  if(fabs(uX) < 1) return uX;
173 
174  if(p_filter == 0) { // BLUE FILTER
175  return (1.4101 * log(fabs(uX)));
176  }
177 
178  else if(p_filter == 1) { // GREEN FILTER
179  return (1.1039 * log(fabs(uX)));
180  }
181 
182  else if(p_filter == 2) { // ORANGE FILTER
183  return (0.8963 * log(fabs(uX)) + 2.1644);
184  }
185 
186  else if(p_filter == 3) { // RED FILTER
187  return (1.1039 * log(fabs(uX)));
188  }
189 
190  else if(p_filter == 4) { // NIR FILTER
191  return (1.4101 * log(fabs(uX)));
192  }
193 
194  return uX;
195  }
196 }
197