USGS

Isis 3.0 Object Programmers' Reference

Home

CameraDistortionMap.cpp
Go to the documentation of this file.
00001 
00023 #include "IString.h"
00024 #include "CameraDistortionMap.h"
00025 
00026 namespace Isis {
00039   CameraDistortionMap::CameraDistortionMap(Camera *parent, double zDirection) {
00040     p_camera = parent;
00041     p_camera->SetDistortionMap(this);
00042     p_zDirection = zDirection;
00043   }
00044 
00064   void CameraDistortionMap::SetDistortion(int naifIkCode) {
00065     QString odkkey = "INS" + toString(naifIkCode) + "_OD_K";
00066     for(int i = 0; i < 3; ++i) {
00067       p_odk.push_back(p_camera->Spice::getDouble(odkkey, i));
00068     }
00069   }
00070 
00087   bool CameraDistortionMap::SetFocalPlane(double dx, double dy) {
00088     p_focalPlaneX = dx;
00089     p_focalPlaneY = dy;
00090 
00091     // No coefficients == no distortion
00092     if(p_odk.size() <= 0) {
00093       p_undistortedFocalPlaneX = dx;
00094       p_undistortedFocalPlaneY = dy;
00095       return true;
00096     }
00097 
00098     // Get the distance from the focal plane center and if we are close
00099     // then skip the distortion
00100     double r2 = (dx * dx) + (dy * dy);
00101     if(r2 <= 1.0E-6) {
00102       p_undistortedFocalPlaneX = dx;
00103       p_undistortedFocalPlaneY = dy;
00104       return true;
00105     }
00106 
00107     // Ok we need to apply distortion correction
00108     double drOverR = p_odk[0] + (r2 * (p_odk[1] + (r2 * p_odk[2])));
00109     p_undistortedFocalPlaneX = dx - (drOverR * dx);
00110     p_undistortedFocalPlaneY = dy - (drOverR * dy);
00111     return true;
00112   }
00113 
00132   bool CameraDistortionMap::SetUndistortedFocalPlane(const double ux,
00133       const double uy) {
00134     p_undistortedFocalPlaneX = ux;
00135     p_undistortedFocalPlaneY = uy;
00136 
00137     // No coefficients == nodistortion
00138     if(p_odk.size() <= 0) {
00139       p_focalPlaneX = ux;
00140       p_focalPlaneY = uy;
00141       return true;
00142     }
00143 
00144     // Compute the distance from the focal plane center and if we are
00145     // close to the center then no distortion is required
00146     double rp2 = (ux * ux) + (uy * uy);
00147     if(rp2 <= 1.0E-6) {
00148       p_focalPlaneX = ux;
00149       p_focalPlaneY = uy;
00150       return true;
00151     }
00152 
00153     // Ok make the correction, start by computing
00154     // fractional distortion at rp (r-prime)
00155     double rp = sqrt(rp2);
00156     double drOverR = p_odk[0] + (rp2 * (p_odk[1] + (rp2 * p_odk[2])));
00157 
00158     // Estimate r
00159     double r = rp + (drOverR * rp);
00160     double r_prev, r2_prev;
00161     double tolMilliMeters = p_camera->PixelPitch() / 100.0;
00162     int iteration = 0;
00163     do {
00164       // Don't get in a end-less loop.  This algorithm should
00165       // converge quickly.  If not then we are probably way outside
00166       // of the focal plane.  Just set the distorted position to the
00167       // undistorted position. Also, make sure the focal plane is less
00168       // than 1km, it is unreasonable for it to grow larger than that.
00169       if(iteration >= 15 || r > 1E9) {
00170         drOverR = 0.0;
00171         break;
00172       }
00173 
00174       r_prev = r;
00175       r2_prev = r * r;
00176 
00177       // Compute new fractional distortion:
00178       drOverR = p_odk[0] + (r2_prev * (p_odk[1] + (r2_prev * p_odk[2])));
00179 
00180       r = rp + (drOverR * r_prev);  // Compute new estimate of r
00181       iteration++;
00182     }
00183     while(fabs(r - r_prev) > tolMilliMeters);
00184 
00185     p_focalPlaneX = ux / (1.0 - drOverR);
00186     p_focalPlaneY = uy / (1.0 - drOverR);
00187     return true;
00188   }
00189 
00191   std::vector<double> CameraDistortionMap::OpticalDistortionCoefficients() const {
00192     return p_odk;
00193   }
00194 
00196   double CameraDistortionMap::ZDirection() const {
00197     return p_zDirection;
00198   }
00199 
00200 }
00201