OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimPpjFrameSensor.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 //
3 // License: See top level LICENSE.txt file.
4 //
5 // Author: Dave Hicks
6 //
7 // Description: PPJ Frame Model
8 //
9 //*******************************************************************
10 // $Id$
13 #include <ossim/base/ossimTrace.h>
14 #include <ossim/base/ossimLsrRay.h>
21 #include <ossim/matrix/newmatio.h>
22 
23 static ossimTrace traceExec ("ossimPpjFrameSensor:exec");
24 static ossimTrace traceDebug("ossimPpjFrameSensor:debug");
25 
26 RTTI_DEF1(ossimPpjFrameSensor, "ossimPpjFrameSensor", ossimSensorModel);
27 
28 enum
29 {
33  // PARAM_ADJ_ROLL_OFFSET,
34  // PARAM_ADJ_PITCH_OFFSET,
35  // PARAM_ADJ_YAW_OFFSET,
38 };
39 
41  :
42  m_ecef2Cam(),
43  m_ecef2CamInverse(),
44  m_principalPoint(0.0, 0.0),
45  m_focalLengthX(0.0),
46  m_focalLengthY(0.0),
47  m_focalLength(0.0),
48  m_ecefCameraPosition(),
49  m_cameraPositionEllipsoid(),
50  m_radialK1(0.0),
51  m_radialK2(0.0),
52  m_radialP1(0.0),
53  m_radialP2(0.0),
54  m_adjustedCameraPosition(),
55  m_adjustedFocalLength(0.0),
56  m_averageProjectedHeight(0.0)
57 {
58  if (traceDebug())
59  {
61  << "ossimPpjFrameSensor::ossimPpjFrameSensor DEBUG:" << std::endl;
62  }
64  theSensorID = "PpjFrame";
65  m_ecef2Cam.ReSize(3,3);
66  m_ecef2CamInverse.ReSize(3,3);
67 
68  std::fill(m_ecef2Cam.Store(), m_ecef2Cam.Store()+9, 0.0);
69  std::fill(m_ecef2CamInverse.Store(), m_ecef2CamInverse.Store()+9, 0.0);
70  m_ecef2Cam[0][0] = 1.0;
71  m_ecef2Cam[1][1] = 1.0;
72  m_ecef2Cam[2][2] = 1.0;
73  m_ecef2CamInverse[0][0] = 1.0;
74  m_ecef2CamInverse[1][1] = 1.0;
75  m_ecef2CamInverse[2][2] = 1.0;
76 }
77 
79  :
80  ossimSensorModel(src),
81  m_ecef2Cam(src.m_ecef2Cam),
82  m_ecef2CamInverse(src.m_ecef2CamInverse),
83  m_principalPoint(src.m_principalPoint),
84  m_focalLengthX(src.m_focalLengthX),
85  m_focalLengthY(src.m_focalLengthY),
86  m_focalLength(src.m_focalLength),
87  m_ecefCameraPosition(src.m_ecefCameraPosition),
88  m_cameraPositionEllipsoid(src.m_cameraPositionEllipsoid),
89  m_radialK1(src.m_radialK1),
90  m_radialK2(src.m_radialK2),
91  m_radialP1(src.m_radialP1),
92  m_radialP2(src.m_radialP2),
93  m_adjustedCameraPosition(src.m_adjustedCameraPosition),
94  m_adjustedFocalLength(src.m_adjustedFocalLength),
95  m_averageProjectedHeight(src.m_averageProjectedHeight)
96 {
97 }
98 
100 {
101  return new ossimPpjFrameSensor(*this);
102 }
103 
104 void ossimPpjFrameSensor::setFocalLength(double focX, double focY)
105 {
106  m_focalLengthX = focX;
107  m_focalLengthY = focY;
109 }
110 
112 {
114  m_ecefCameraPosition = value;
115 }
116 
118 {
119  m_principalPoint = value;
120 }
121 
122 void ossimPpjFrameSensor::setecef2CamMatrix(const NEWMAT::Matrix& value)
123 {
124  m_ecef2Cam = value;
126 }
127 
128 void ossimPpjFrameSensor::setAveragePrjectedHeight(double averageProjectedHeight)
129 {
130  m_averageProjectedHeight = averageProjectedHeight;
131 }
132 
134  ossimEcefRay& imageRay) const
135 {
136  // Form camera frame LOS vector
137  ossimColumnVector3d camLOS(imagePoint.x - m_principalPoint.x,
138  imagePoint.y - m_principalPoint.y,
140 
141  // Rotate to ECF
142  ossimColumnVector3d ecfLOS = m_ecef2CamInverse * camLOS;
144  ossimEcefVector ecfRayDir(ecfLOS);
145  imageRay.setDirection(ecfRayDir);
146 
147  if (traceDebug())
148  {
150  << "ossimPpjFrameSensor::imagingRay DEBUG:\n"
151  << " camLOS = " << camLOS << "\n"
152  << " m_adjustedPlatformPosition = " << m_adjustedCameraPosition << "\n"
153  << " imageRay = " << imageRay << "\n"
154  << std::endl;
155  }
156 
157 }
158 
160  ossimGpt& worldPt) const
161 {
162  ossimEcefRay ray;
163  imagingRay(imagePoint, ray);
165 }
166 
168  const double& heightEllipsoid,
169  ossimGpt& worldPt) const
170 {
171  ossimEcefRay ray;
172  imagingRay(imagePoint, ray);
173  double h = (ossim::isnan(heightEllipsoid)||ossim::almostEqual(heightEllipsoid, 0.0))?m_averageProjectedHeight:heightEllipsoid;
175  worldPt = ossimGpt(pecf);
176 
177  if (traceDebug())
178  {
179  ossimNotify(ossimNotifyLevel_DEBUG) << "ossimPpjFrameSensor::lineSampleHeightToWorld DEBUG:" << std::endl;
180  ossimNotify(ossimNotifyLevel_DEBUG) << " imagePoint = " << imagePoint << std::endl;
181  ossimNotify(ossimNotifyLevel_DEBUG) << " heightEllipsoid = " << heightEllipsoid << std::endl;
182  ossimNotify(ossimNotifyLevel_DEBUG) << " ray = " << ray << std::endl;
183  ossimNotify(ossimNotifyLevel_DEBUG) << " worldPt = " << worldPt << std::endl;
184  }
185 }
186 
188  ossimDpt& image_point) const
189 {
190  ossimGpt wpt = world_point;
191  if(wpt.isHgtNan())
192  {
194  }
195  ossimEcefPoint gnd_ecf(wpt);
197  ossimEcefVector ecfRay(gnd_ecf - cam_ecf);
198  ossimColumnVector3d camRay(m_ecef2Cam*ecfRay.data());
199 
200  double x = m_principalPoint.x + m_adjustedFocalLength*camRay[0]/camRay[2];
201  double y = m_principalPoint.y + m_adjustedFocalLength*camRay[1]/camRay[2];
202 
203  ossimDpt p(x, y);
204 
205  image_point = p;
206 }
207 
209 {
210  if (traceDebug())
211  {
213  << "ossimPpjFrameSensor::updateModel DEBUG:" << std::endl;
214  }
215 
220 
222  m_cameraPositionEllipsoid.lond() + deltal,
224 
225  // TODO Need to add correction matrix to accommodate orientation offsets. It
226  // shouldn't be done in ECF frame.
227  // double r = ossim::degreesToRadians(m_roll + computeParameterOffset(PARAM_ADJ_ROLL_OFFSET));
228  // double p = ossim::degreesToRadians(m_pitch + computeParameterOffset(PARAM_ADJ_PITCH_OFFSET) );
229  // double y = ossim::degreesToRadians(m_yaw + computeParameterOffset(PARAM_ADJ_YAW_OFFSET));
230  // NEWMAT::Matrix rollM = ossimMatrix3x3::create(1, 0, 0,
231  // 0, cos(r), sin(r),
232  // 0, -sin(r), cos(r));
233  // NEWMAT::Matrix pitchM = ossimMatrix3x3::create(cos(p), 0, -sin(p),
234  // 0, 1, 0,
235  // sin(p), 0, cos(p));
236  // NEWMAT::Matrix yawM = ossimMatrix3x3::create(cos(y), sin(y), 0,
237  // -sin(y), cos(y), 0,
238  // 0,0,1);
239 
241 
242 
243  try
244  {
245  computeGsd();
246  }
247  catch(...)
248  {
249 
250  }
251  if (traceDebug())
252  {
254  << "ossimPpjFrameSensor::updateModel complete..." << std::endl;
255  }
256  /*
257  ossimGpt gpt;
258  lineSampleToWorld(theImageClipRect.ul(),gpt);//+ossimDpt(-w, -h), gpt);
259  theBoundGndPolygon[0] = gpt;
260  lineSampleToWorld(theImageClipRect.ur(),gpt);//+ossimDpt(w, -h), gpt);
261  theBoundGndPolygon[1] = gpt;
262  lineSampleToWorld(theImageClipRect.lr(),gpt);//+ossimDpt(w, h), gpt);
263  theBoundGndPolygon[2] = gpt;
264  lineSampleToWorld(theImageClipRect.ll(),gpt);//+ossimDpt(-w, h), gpt);
265  theBoundGndPolygon[3] = gpt;
266  */
267 }
268 
270 {
271  if (traceExec())
272  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimPpjFrameSensor::initAdjustableParameters: returning..." << std::endl;
274 
279 
284 
289 
290  // TODO Add these back in when orientation angle offsets are fixed.
291  // setAdjustableParameter(PARAM_ADJ_ROLL_OFFSET, 0.0);
292  // setParameterDescription(PARAM_ADJ_ROLL_OFFSET, "roll_offset");
293  // setParameterUnit(PARAM_ADJ_ROLL_OFFSET, "degrees");
294  // setParameterSigma(PARAM_ADJ_ROLL_OFFSET, 10);
295 
296  // setAdjustableParameter(PARAM_ADJ_PITCH_OFFSET, 0.0);
297  // setParameterDescription(PARAM_ADJ_PITCH_OFFSET, "pitch_offset");
298  // setParameterUnit(PARAM_ADJ_PITCH_OFFSET, "degrees");
299  // setParameterSigma(PARAM_ADJ_PITCH_OFFSET, 10);
300 
301  // setAdjustableParameter(PARAM_ADJ_YAW_OFFSET, 0.0);
302  // setParameterDescription(PARAM_ADJ_YAW_OFFSET, "yaw_offset");
303  // setParameterUnit(PARAM_ADJ_YAW_OFFSET, "degrees");
304  // setParameterSigma(PARAM_ADJ_YAW_OFFSET, .04);
305 
310 }
311 
312 bool ossimPpjFrameSensor::loadState(const ossimKeywordlist& kwl, const char* prefix)
313 {
314  if (traceDebug())
315  {
317  << "ossimPpjFrameSensor::loadState DEBUG:" << std::endl;
318  }
319 
320  theGSD.makeNan();
322  ossimSensorModel::loadState(kwl, prefix);
324  {
326  }
327  ossimString principal_point = kwl.find(prefix, "principal_point");
328  ossimString focal_length_x = kwl.find(prefix, "focal_length_x");
329  ossimString focal_length_y = kwl.find(prefix, "focal_length_y");
330  ossimString number_samples = kwl.find(prefix, "number_samples");
331  ossimString number_lines = kwl.find(prefix, "number_lines");
332  ossimString ecf_to_cam_row1 = kwl.find(prefix, "ecf_to_cam_row1");
333  ossimString ecf_to_cam_row2 = kwl.find(prefix, "ecf_to_cam_row2");
334  ossimString ecf_to_cam_row3 = kwl.find(prefix, "ecf_to_cam_row3");
335  ossimString platform_position = kwl.find(prefix, "ecef_camera_position");
336  ossimString averageProjectedHeight = kwl.find(prefix, "average_projected_height");
337 
338  // ossimString roll;
339  // ossimString pitch;
340  // ossimString yaw;
341  // m_roll = 0;
342  // m_pitch = 0;
343  // m_yaw = 0;
344  // roll = kwl.find(prefix, "roll");
345  // pitch = kwl.find(prefix, "pitch");
346  // yaw = kwl.find(prefix, "yaw");
347 
348  bool result = (!principal_point.empty()&&
349  !focal_length_x.empty()&&
350  !platform_position.empty()&&
351  !ecf_to_cam_row1.empty()&&
352  !ecf_to_cam_row2.empty()&&
353  !ecf_to_cam_row3.empty());
354  if(!averageProjectedHeight.empty())
355  {
356  m_averageProjectedHeight = averageProjectedHeight.toDouble();
357  }
358  if(!number_samples.empty())
359  {
360  theImageSize = ossimIpt(number_samples.toDouble(), number_lines.toDouble());
363  }
365  {
367  }
368  if(theRefImgPt.hasNans())
369  {
371  }
372  if(!focal_length_x.empty())
373  {
374  m_focalLengthX = focal_length_x.toDouble();
376  }
377  if(!focal_length_y.empty())
378  {
379  m_focalLengthY = focal_length_y.toDouble();
380  }
381 
382  std::vector<ossimString> row;
383  if(!ecf_to_cam_row1.empty())
384  {
385  row = ecf_to_cam_row1.explode(" ");
386  for (int i=0; i<3; ++i)
387  m_ecef2Cam[0][i] = row[i].toDouble();
388  row = ecf_to_cam_row2.explode(" ");
389  for (int i=0; i<3; ++i)
390  m_ecef2Cam[1][i] = row[i].toDouble();
391  row = ecf_to_cam_row3.explode(" ");
392  for (int i=0; i<3; ++i)
393  m_ecef2Cam[2][i] = row[i].toDouble();
395  }
396 
397  // if(!roll.empty())
398  // {
399  // m_roll = roll.toDouble();
400  // }
401  // if(!pitch.empty())
402  // {
403  // m_pitch = pitch.toDouble();
404  // }
405  // if(!yaw.empty())
406  // {
407  // m_yaw = yaw.toDouble();
408  // }
409 
410  if(!principal_point.empty())
411  {
412  m_principalPoint.toPoint(principal_point);
413  }
414  if(!platform_position.empty())
415  {
416  m_ecefCameraPosition.toPoint(platform_position);
418  }
419 
420 
421  updateModel();
422 
423  if(theGSD.isNan())
424  {
425  try
426  {
427  computeGsd();
428  }
429  catch (const ossimException& e)
430  {
431  if (traceDebug())
432  {
434  << "ossimPpjFrameSensor::loadState Caught Exception:\n"
435  << e.what() << std::endl;
436  }
437  }
438  }
439  if (traceDebug())
440  {
442  << "ossimPpjFrameSensor::loadState complete..." << std::endl;
443  }
444 
445  return result;
446 }
447 
448 bool ossimPpjFrameSensor::saveState(ossimKeywordlist& kwl, const char* prefix)const
449 {
450  ossimSensorModel::saveState(kwl, prefix);
451  // kwl.add(prefix, "roll", ossimString::toString(m_roll), true);
452  // kwl.add(prefix, "pitch", ossimString::toString(m_pitch), true);
453  // kwl.add(prefix, "yaw", ossimString::toString(m_yaw), true);
454  kwl.add(prefix, "gsd", theGSD.toString(), true);
455  kwl.add(prefix, "principal_point", m_principalPoint.toString(), true);
456  kwl.add(prefix, "ecef_camera_position",m_ecefCameraPosition.toString() ,true);
457  kwl.add(prefix, "focal_length_x", ossimString::toString(m_focalLengthX) ,true);
458  kwl.add(prefix, "focal_length_y", ossimString::toString(m_focalLengthY) ,true);
459  kwl.add(prefix, "image_size", theImageSize.toString() ,true);
460  kwl.add(prefix, "average_projected_height", m_averageProjectedHeight, true);
461  ossimString row1 = ossimString::toString(m_ecef2Cam[0][0]) + " " +
462  ossimString::toString(m_ecef2Cam[0][1]) + " " +
464  kwl.add(prefix, "ecf_to_cam_row1", row1, true);
465  ossimString row2 = ossimString::toString(m_ecef2Cam[1][0]) + " " +
466  ossimString::toString(m_ecef2Cam[1][1]) + " " +
468  kwl.add(prefix, "ecf_to_cam_row2", row2, true);
469  ossimString row3 = ossimString::toString(m_ecef2Cam[2][0]) + " " +
470  ossimString::toString(m_ecef2Cam[2][1]) + " " +
472  kwl.add(prefix, "ecf_to_cam_row3", row3, true);
473 
474  return true;
475 }
ossimString theSensorID
ossimString toString() const
Definition: ossimIpt.cpp:139
ossim_uint32 x
void setParameterDescription(ossim_uint32 idx, const ossimString &descrption)
virtual void imagingRay(const ossimDpt &image_point, ossimEcefRay &image_ray) const
virtual ossimObject * dup() const
virtual void worldToLineSample(const ossimGpt &world_point, ossimDpt &image_point) const
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
double lond() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:97
ossimEcefPoint intersectAboveEarthEllipsoid(const double &heightAboveEllipsoid, const ossimDatum *aDatum=ossimDatumFactory::instance() ->wgs84()) const
Represents serializable keyword/value map.
ossim_uint32 y
bool intersectRay(const ossimEcefRay &ray, ossimGpt &gpt, double defaultElevValue=0.0)
METHOD: intersectRay()
const char * find(const char *key) const
bool almostEqual(T x, T y, T tolerance=FLT_EPSILON)
Definition: ossimCommon.h:53
double y
Definition: ossimDpt.h:165
static ossimString toString(bool aValue)
Numeric to string methods.
static ossimElevManager * instance()
METHOD: instance() Implements singelton pattern.
bool isNan() const
Definition: ossimDpt.h:72
void setOrigin(const ossimEcefPoint &orig)
Definition: ossimEcefRay.h:81
NEWMAT::Matrix m_ecef2Cam
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
double latd() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:87
void setFocalLength(double focX, double focY)
void setCameraPosition(const ossimGpt &value)
void toPoint(const std::string &s)
Initializes this point from string.
bool isHgtNan() const
Definition: ossimGpt.h:143
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
void computeGsd()
This method computes the ground sample distance(gsd) and sets class attributes theGSD and theMeanGSD ...
virtual const char * what() const
Returns the error message.
void toPoint(const std::string &s)
Initializes this point from string.
Definition: ossimDpt.cpp:192
double height() const
Definition: ossimGpt.h:107
double toDouble() const
ossimEcefPoint m_ecefCameraPosition
virtual void initAdjustableParameters()
virtual void lineSampleToWorld(const ossimDpt &image_point, ossimGpt &worldPoint) const
void setParameterUnit(ossim_uint32 idx, ossimUnitType unit)
void setAveragePrjectedHeight(double averageProjectedHeight)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
bool hasNans() const
Definition: ossimDrect.h:396
std::vector< ossimString > explode(const ossimString &delimeter) const
bool hasNans() const
Definition: ossimDpt.h:67
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
NEWMAT::Matrix m_ecef2CamInverse
void setPrincipalPoint(const ossimDpt &value)
ossimDrect theImageClipRect
ossimString toString(ossim_uint32 precision=15) const
Definition: ossimDpt.cpp:160
ossimDpt midPoint() const
Definition: ossimDrect.h:817
virtual void setAdjustableParameter(ossim_uint32 idx, double value, bool notify=false)
ossim_int32 y
Definition: ossimIpt.h:142
double x
Definition: ossimDpt.h:164
void resizeAdjustableParameterArray(ossim_uint32 numberOfParameters)
bool empty() const
Definition: ossimString.h:411
const ossimColumnVector3d & data() const
ossimDpt metersPerDegree() const
Definition: ossimGpt.cpp:498
ossim_int32 x
Definition: ossimIpt.h:141
void setDirection(const ossimEcefVector &d)
Definition: ossimEcefRay.h:82
virtual void lineSampleHeightToWorld(const ossimDpt &image_point, const double &heightEllipsoid, ossimGpt &worldPoint) const
RTTI_DEF1(ossimPpjFrameSensor, "ossimPpjFrameSensor", ossimSensorModel)
void setParameterSigma(ossim_uint32 idx, double value, bool notify=false)
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
void makeNan()
Definition: ossimDpt.h:65
void setecef2CamMatrix(const NEWMAT::Matrix &value)
ossimString toString(ossim_uint32 precision=15) const
To string method.
bool isnan(const float &v)
isnan Test for floating point Not A Number (NAN) value.
Definition: ossimCommon.h:91