Isis 3.0 Object Programmers' Reference |
Home |
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