USGS

Isis 3.0 Object Programmers' Reference

Home

ReseauDistortionMap.cpp
Go to the documentation of this file.
1 
23 #include "ReseauDistortionMap.h"
24 #include "LeastSquares.h"
25 #include "BasisFunction.h"
26 #include "CameraFocalPlaneMap.h"
27 #include "Pvl.h"
28 #include "Statistics.h"
29 #include <float.h>
30 
31 using namespace std;
32 namespace Isis {
44  ReseauDistortionMap::ReseauDistortionMap(Camera *parent, Pvl &labels, const QString &fname) :
45  CameraDistortionMap(parent, 1.0) {
46  // Set up distortion coefficients
47  Pvl mast(fname);
48  PvlGroup dim = mast.findGroup("Dimensions");
49  p_distortedLines = dim.findKeyword("DistortedLines");
50  p_distortedSamps = dim.findKeyword("DistortedSamples");
51  p_undistortedLines = dim.findKeyword("UndistortedLines");
52  p_undistortedSamps = dim.findKeyword("UndistortedSamples");
53  PvlGroup mastRes = mast.findGroup("MasterReseaus");
54  PvlKeyword mline = mastRes.findKeyword("Line");
55  PvlKeyword msamp = mastRes.findKeyword("Sample");
56  p_numRes = mline.size();
57  if(mline.size() != msamp.size()) {
58  string msg = "The number of lines and samples for the master reseaus are";
59  msg += "not equal, the data file may be bad";
61  }
62  for(int i = 0; i < p_numRes; i++) {
63  p_mlines.push_back(toDouble(mline[i]));
64  p_msamps.push_back(toDouble(msamp[i]));
65  }
66  p_pixelPitch = parent->PixelPitch();
67 
68  PvlGroup refRes = labels.findGroup("Reseaus", Pvl::Traverse);
69  PvlKeyword rline = refRes.findKeyword("Line");
70  PvlKeyword rsamp = refRes.findKeyword("Sample");
71  if(rline.size() != rsamp.size()) {
72  string msg = "The number of lines and samples for the refined reseaus are";
73  msg += "not equal, the data file may be bad";
75  }
76  for(int i = 0; i < p_numRes; i++) {
77  p_rlines.push_back(toDouble(rline[i]));
78  p_rsamps.push_back(toDouble(rsamp[i]));
79  }
80  if(p_mlines.size() != p_rlines.size()) {
81  string msg = "The number of master reseaus and refined reseaus";
82  msg += "do not appear to be equal";
84  }
85  }
86 
96  bool ReseauDistortionMap::SetFocalPlane(const double dx,
97  const double dy) {
98  p_focalPlaneX = dx;
99  p_focalPlaneY = dy;
100 
101  // Convert distorted x,y position to a sample, line position
102  double focalSamp = dx / p_pixelPitch +
103  p_camera->FocalPlaneMap()->DetectorSampleOrigin();
104  double focalLine = dy / p_pixelPitch +
105  p_camera->FocalPlaneMap()->DetectorLineOrigin();
106 
107  // Find distance from input point to all nominal reseaus
108  double distances[p_numRes], wt[5];
109  int closepts[5];
110  double ldiffsq, sdiffsq;
111  for(int i = 0; i < p_numRes; i++) {
112  sdiffsq = (focalSamp - p_rsamps[i]) * (focalSamp - p_rsamps[i]);
113  ldiffsq = (focalLine - p_rlines[i]) * (focalLine - p_rlines[i]);
114  distances[i] = ldiffsq + sdiffsq;
115  }
116 
117  // Get 5 closest reseaus to the input point
118  for(int ifpt = 0; ifpt < 5; ifpt++) {
119  int imin = 0;
120  for(int i = 0; i < p_numRes; i++) {
121  if(distances[i] < distances[imin]) imin = i;
122  }
123  closepts[ifpt] = imin;
124  wt[ifpt] = distances[imin];
125  distances[imin] = DBL_MAX; /* Arbitrary big number */
126  }
127 
128  // Make sure 5 closest points are not colinear
129  Statistics lstats, sstats;
130  double line[5], samp[5];
131  for(int k = 0; k < 5; k++) {
132  line[k] = p_rlines[closepts[k]];
133  samp[k] = p_rsamps[closepts[k]];
134  }
135  lstats.AddData(line, 5);
136  sstats.AddData(samp, 5);
137 
138  // If they are colinear, return false
139  if(lstats.StandardDeviation() < 10.0 || sstats.StandardDeviation() < 10.0) {
140  return false;
141  }
142 
143  // Weight each of the 5 closest points, and solve the system of equations
144  if(wt[0] > 0.0) {
145  double scale = wt[0];
146  double rfitlines[5], rfitsamps[5], mfitlines[5], mfitsamps[5];
147  for(int ifpt = 0; ifpt < 5; ifpt++) {
148  int index = closepts[ifpt];
149  rfitlines[ifpt] = p_rlines[index];
150  rfitsamps[ifpt] = p_rsamps[index];
151  mfitlines[ifpt] = p_mlines[index];
152  mfitsamps[ifpt] = p_msamps[index];
153  wt[ifpt] = scale / wt[ifpt];
154  }
155  BasisFunction bsX("bilinearInterpX", 3, 3);
156  BasisFunction bsY("bilinearInterpY", 3, 3);
157  LeastSquares lsqX(bsX);
158  LeastSquares lsqY(bsY);
159 
160  vector<double> known;
161  known.resize(3);
162  for(int i = 0; i < 5; i++) {
163  known[0] = 1.0;
164  known[1] = rfitsamps[i];
165  known[2] = rfitlines[i];
166  lsqX.AddKnown(known, mfitsamps[i], wt[i]);
167  lsqY.AddKnown(known, mfitlines[i], wt[i]);
168  }
169  lsqX.Solve();
170  lsqY.Solve();
171 
172  known[1] = focalSamp;
173  known[2] = focalLine;
174 
175  // Test to make sure the point is inside of the image
176  double undistortedFocalSamp = lsqX.Evaluate(known);
177  double undistortedFocalLine = lsqY.Evaluate(known);
178  if(undistortedFocalSamp < 0.5) return false;
179  if(undistortedFocalLine < 0.5) return false;
180  if(undistortedFocalSamp > p_undistortedSamps + 0.5) return false;
181  if(undistortedFocalLine > p_undistortedLines + 0.5) return false;
182 
183  // Convert undistorted sample, line position to an x,y position
184  p_undistortedFocalPlaneX = (undistortedFocalSamp - p_undistortedSamps
185  / 2.0) * p_pixelPitch;
186  p_undistortedFocalPlaneY = (undistortedFocalLine - p_undistortedLines
187  / 2.0) * p_pixelPitch;
188  }
189  else { // If the point passed in is a reseau...
190  int index = closepts[0];
191  p_undistortedFocalPlaneX = (p_msamps[index] - p_undistortedSamps / 2.0)
192  * p_pixelPitch;
193  p_undistortedFocalPlaneY = (p_mlines[index] - p_undistortedLines / 2.0)
194  * p_pixelPitch;
195  }
196  return true;
197  }
198 
209  const double uy) {
210  p_undistortedFocalPlaneX = ux;
211  p_undistortedFocalPlaneY = uy;
212 
213  // Convert undistorted values to sample, line positions
214  double undistortedFocalSamp = ux / p_pixelPitch + p_undistortedSamps / 2.0;
215  double undistortedFocalLine = uy / p_pixelPitch + p_undistortedLines / 2.0;
216 
217  // Find distance from input point to all nominal reseaus
218  double distances[p_numRes], wt[5];
219  int closepts[5];
220  double ldiffsq, sdiffsq;
221  for(int i = 0; i < p_numRes; i++) {
222  sdiffsq = (undistortedFocalSamp - p_msamps[i]) *
223  (undistortedFocalSamp - p_msamps[i]);
224  ldiffsq = (undistortedFocalLine - p_mlines[i]) *
225  (undistortedFocalLine - p_mlines[i]);
226  distances[i] = ldiffsq + sdiffsq;
227  }
228 
229  // Get 5 closest reseaus to the input point
230  for(int ifpt = 0; ifpt < 5; ifpt++) {
231  int imin = 0;
232  for(int i = 0; i < p_numRes; i++) {
233  if(distances[i] < distances[imin]) imin = i;
234  }
235  closepts[ifpt] = imin;
236  wt[ifpt] = distances[imin];
237  distances[imin] = DBL_MAX; /* Arbitrary big number */
238  }
239 
240  // Make sure 5 closest points are not colinear
241  Statistics lstats, sstats;
242  double line[5], samp[5];
243  for(int k = 0; k < 5; k++) {
244  line[k] = p_rlines[closepts[k]];
245  samp[k] = p_rsamps[closepts[k]];
246  }
247  lstats.AddData(line, 5);
248  sstats.AddData(samp, 5);
249  // If they are colinear, return false
250  if(lstats.StandardDeviation() < 10.0 || sstats.StandardDeviation() < 10.0) {
251  return false;
252  }
253 
254  // Weight each of the 5 closest points and solve the system of equations
255  if(wt[0] > 0.0) {
256  double scale = wt[0];
257  double rfitlines[5], rfitsamps[5], mfitlines[5], mfitsamps[5];
258  for(int ifpt = 0; ifpt < 5; ifpt++) {
259  int index = closepts[ifpt];
260  mfitlines[ifpt] = p_mlines[index];
261  mfitsamps[ifpt] = p_msamps[index];
262  rfitlines[ifpt] = p_rlines[index];
263  rfitsamps[ifpt] = p_rsamps[index];
264  wt[ifpt] = scale / wt[ifpt];
265  }
266  BasisFunction bsX("bilinearInterpX", 3, 3);
267  BasisFunction bsY("bilinearInterpY", 3, 3);
268  LeastSquares lsqX(bsX);
269  LeastSquares lsqY(bsY);
270 
271  vector<double> known;
272  known.resize(3);
273  for(int i = 0; i < 5; i++) {
274  known[0] = 1.0;
275  known[1] = mfitsamps[i];
276  known[2] = mfitlines[i];
277  lsqX.AddKnown(known, rfitsamps[i], wt[i]);
278  lsqY.AddKnown(known, rfitlines[i], wt[i]);
279  }
280  lsqX.Solve();
281  lsqY.Solve();
282 
283  known[1] = undistortedFocalSamp;
284  known[2] = undistortedFocalLine;
285 
286  // Test points to make sure they are in the image
287  double distortedFocalSamp = lsqX.Evaluate(known);
288  double distortedFocalLine = lsqY.Evaluate(known);
289  if(distortedFocalSamp < 0.5) return false;
290  if(distortedFocalLine < 0.5) return false;
291  if(distortedFocalSamp > p_undistortedSamps + 0.5) return false;
292  if(distortedFocalLine > p_undistortedLines + 0.5) return false;
293 
294  // Convert distorted sample, line position back to an x,y position
295  p_focalPlaneX = (distortedFocalSamp -
297  p_focalPlaneY = (distortedFocalLine -
299  }
300 
301  else { // If the point passed in is a reseau...
302  int index = closepts[0];
303  p_focalPlaneX = (p_rsamps[index] -
305  p_focalPlaneY = (p_rlines[index] -
307  }
308  return true;
309  }
310 
311 } // end namespace isis