/usr/include/ossim/projection/ossimRpcSolver.h is in libossim-dev 2.2.2-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | //**************************************************************************************************
//
// OSSIM Open Source Geospatial Data Processing Library
// See top level LICENSE.txt file for license information
//
//**************************************************************************************************
#ifndef ossimRpcSolver_HEADER
#define ossimRpcSolver_HEADER
#include <vector>
#include <ossim/base/ossimConstants.h>
#include <ossim/base/ossimRefPtr.h>
#include <ossim/base/ossimDpt.h>
#include <ossim/base/ossimGpt.h>
#include <ossim/base/ossimDrect.h>
#include <ossim/base/ossimReferenced.h>
#include <ossim/matrix/newmat.h>
#include <ossim/projection/ossimRpcModel.h>
#include <ossim/projection/ossimRpcProjection.h>
#include <ossim/support_data/ossimNitfRegisteredTag.h>
#include <ossim/imaging/ossimImageGeometry.h>
/**
* This currently only support Rational poilynomial B format. This can be
* found in the NITF registered commercial tag document.
*
* @note x=longitude, y=latitude, z=height
*
* <pre>
* Format is:
* coeff[ 0] + coeff[ 1]*x + coeff[ 2]*y + coeff[ 3]*z +
* coeff[ 4]*x*y + coeff[ 5]*x*z + coeff[ 6]*y*z + coeff[ 7]*x*x +
* coeff[ 8]*y*y + coeff[ 9]*z*z + coeff[10]*x*y*z + coeff[11]*x*x*x +
* coeff[12]*x*y*y + coeff[13]*x*z*z + coeff[14]*x*x*y + coeff[15]*y*y*y +
* coeff[16]*y*z*z + coeff[17]*x*x*z + coeff[18]*y*y*z + coeff[19]*z*z*z;
*
* where coeff is one of XNum, XDen, YNum, and YDen. So there are 80
* coefficients all together.
*
* Currently we use a linear least squares fit to solve the coefficients.
* This is the simplest to implement. We probably relly need a nonlinear
* minimizer to fit the coefficients but I don't have time to experiment.
* Levenberg Marquardt might be a solution to look into.
*
* HOW TO USE:
*
* ossimRpcSolver solver;
* solver.solveCoefficients(rect,
* *proj.get());
*
* We can also call solve coefficients with a list of ground control points.
* First is the list of image points followed by the ground points.
* NOTE: Thes must be equal in size.
*
* solver.solveCoefficients(imagePoints,
* groundPoints);
*
* Once you call solveCoefficients you can create the projector:
*
* ossimRefPtr<ossimRpcProjection> rpc = solver.createRpcProjection();
*
* Note that a sub-image bounding rect can be passed into the solve methods. This
* constrains the solution fit to cover only that rectangle in the original image space,
* but the image coordinates used are still based on the full image. If the intent is to
* generate an RPC that will work for an image chip in that chip's local image coordinate
* system (i.e., the UL corner of the chip is 0, 0), then you'll need to call
* rpcModel->setImageOffset(chip_offset) on the output RPC model.
*
* </pre>
*
*/
class OSSIM_DLL ossimRpcSolver : public ossimReferenced
{
public:
/**
* The use elvation flag will deterimne if we force the height t be 0.
* If the elevation is enabled then we use the height field of the control
* points to determine the coefficients of the RPC00 polynomial. If its
* false then we will ignore the height by setting the height field to 0.0.
*
* Note: even if the elevation is enabled all NAN heights are set to 0.0.
*/
ossimRpcSolver(bool useElevation=false,
bool useHeightAboveMSLFlag=false);
/**
* This will convert any projector to an RPC model
*/
void solveCoefficients(const ossimDrect& imageBounds,
ossimProjection* imageProj,
ossim_uint32 xSamples=8,
ossim_uint32 ySamples=8);
void solveCoefficients(const ossimDrect& imageBounds,
ossimImageGeometry* geom,
ossim_uint32 xSamples=8,
ossim_uint32 ySamples=8);
/**
* Similar to the other solve methods except that the final grid size is established
* iteratively so that the error at the midpoints between grid nodes falls below tolerance.
* The RPC is computed for the specified image bounds range only, not the full image. The
* expectation here (when the imageBounds is less than the full valid image rect) is to
* generate an RPC to accompany a subimage that will be written to disk.
* @param imageBounds The AOI in image space for the RPC computation.
* @param geom Represents the geometry of the input image
* @param pixel_tolerance Maximum error in pixels (typically fraction of a pixel) to achieve.
* @return true if solution converged below pixel tolerance.
*/
bool solve(const ossimDrect& aoiBounds,
ossimImageGeometry* geom,
const double& pixel_tolerance=0.5);
/**
* takes associated image points and ground points
* and solves the coefficents for the rational polynomial for
* line and sample calculations from world points.
*
* Note: All data will be normalized between -1 and 1 for
* numerical robustness.
*/
void solveCoefficients(const std::vector<ossimDpt>& imagePoints,
const std::vector<ossimGpt>& groundControlPoints);
/**
* Fetches the solved-for RPC model. See note in header above on setting the image offset
* if this model will be applied to a sub-image chip.
*/
const ossimRefPtr<ossimRpcModel> getRpcModel() const { return theRpcModel; }
double getRmsError()const;
double getMaxError()const;
/**
* @return ossimRefPtr<ossimNitfRegisteredTag>
*
* @note one of the solve methods should have been called prior to this.
*/
ossimRefPtr<ossimNitfRegisteredTag> getNitfRpcBTag() const;
/**
* Sets the image rect over which to compute the RPCs. The Resulting RPC will only be valid
* over that range of image space. */
void setValidImageRect(const ossimIrect& imageRect);
protected:
virtual ~ossimRpcSolver(){}
virtual void solveInitialCoefficients(NEWMAT::ColumnVector& coeff,
const std::vector<double>& f,
const std::vector<double>& x,
const std::vector<double>& y,
const std::vector<double>& z)const;
virtual void solveCoefficients(NEWMAT::ColumnVector& coeff,
const std::vector<double>& f,
const std::vector<double>& x,
const std::vector<double>& y,
const std::vector<double>& z)const;
double eval(const std::vector<double>& coeff,
const double& x, const double& y, const double& z)const;
void evalPoint(const ossimGpt& gpt, ossimDpt& ipt) const;
/**
* Inverts using the SVD method
*/
NEWMAT::Matrix invert(const NEWMAT::Matrix& m)const;
void setupSystemOfEquations(NEWMAT::Matrix& equations,
const NEWMAT::ColumnVector& f,
const std::vector<double>& x,
const std::vector<double>& y,
const std::vector<double>& z)const;
void setupWeightMatrix(NEWMAT::DiagonalMatrix& result, // holds the resulting weights
const NEWMAT::ColumnVector& coefficients,
const NEWMAT::ColumnVector& f,
const std::vector<double>& x,
const std::vector<double>& y,
const std::vector<double>& z)const;
bool theUseElevationFlag;
bool theHeightAboveMSLFlag;
ossim_float64 theMeanResidual;
ossim_float64 theMaxResidual;
ossimRefPtr<ossimImageGeometry> theRefGeom;
ossimRefPtr<ossimRpcModel> theRpcModel;
};
#endif
|