diff --git a/include/usgscsm/Distortion.h b/include/usgscsm/Distortion.h index 10c56691840b3a856255ee7727ac756786802d92..d5c3c5165f28bb793414b8f22d84882605595d05 100644 --- a/include/usgscsm/Distortion.h +++ b/include/usgscsm/Distortion.h @@ -19,11 +19,13 @@ void computeTransverseDistortion(double ux, double uy, double &dx, double &dy, void removeDistortion(double dx, double dy, double &ux, double &uy, std::vector<double> const& opticalDistCoeffs, + double focalLength, DistortionType distortionType, const double tolerance = 1.0E-6); void applyDistortion(double ux, double uy, double &dx, double &dy, std::vector<double> const& opticalDistCoeffs, + double focalLength, DistortionType distortionType, const double desiredPrecision = 1.0E-6, const double tolerance = 1.0E-6); diff --git a/src/Distortion.cpp b/src/Distortion.cpp index 38f397ac7d45176f326e2587989ca3333b040abe..e69a5cd2217183bc8c6aa409e0c24fefd3c10ca0 100644 --- a/src/Distortion.cpp +++ b/src/Distortion.cpp @@ -84,13 +84,14 @@ void computeTransverseDistortion(double ux, double uy, double &dx, double &dy, } } -// Compute distorted focal plane coordinates given undistorted coordinates. Use -// the radial-tangential distortion model with 5 coefficients (k1, k2, k3 for -// radial distortion, and p1, p2 for tangential distortion). This was tested to -// give the same results as the OpenCV distortion model, by invoking the -// function cv::projectPoints() (with zero rotation, zero translation, and -// identity camera matrix). The parameters are stored in opticalDistCoeffs -// in the order: [k1, k2, p1, p2, k3]. +// Compute distorted normalized focal plane coordinates given undistorted +// normalized coordinates. Use the radial-tangential distortion model with 5 +// coefficients (k1, k2, k3 for radial distortion, and p1, p2 for tangential +// distortion). This was tested to give the same results as the OpenCV +// distortion model, by invoking the function cv::projectPoints() (with zero +// rotation, zero translation, and identity camera matrix). The parameters are +// stored in opticalDistCoeffs in the order: [k1, k2, p1, p2, k3]. +// Reference: https://docs.opencv.org/4.x/d9/d0c/group__calib3d.html void computeRadTanDistortion(double ux, double uy, double &dx, double &dy, std::vector<double> const& opticalDistCoeffs) { @@ -120,7 +121,7 @@ void computeRadTanDistortion(double ux, double uy, double &dx, double &dy, + (p1 * (r2 + 2.0 * y * y) + 2.0 * p2 * x * y); } -// Compute the jacobian for radtan distortion +// Compute the jacobian for radtan distortion at given normalized coordinates void radTanDistortionJacobian(double x, double y, double *jacobian, std::vector<double> const& opticalDistCoeffs) { @@ -155,6 +156,7 @@ void radTanDistortionJacobian(double x, double y, double *jacobian, void removeDistortion(double dx, double dy, double &ux, double &uy, std::vector<double> const& opticalDistCoeffs, + double focalLength, DistortionType distortionType, const double tolerance) { ux = dx; uy = dy; @@ -343,8 +345,10 @@ void removeDistortion(double dx, double dy, double &ux, double &uy, // with the radtan model. See computeRadTanDistortion() for more details. case RADTAN: { + dx /= focalLength; dy /= focalLength; // Find normalized coordinates newtonRaphson(dx, dy, ux, uy, opticalDistCoeffs, distortionType, tolerance, computeRadTanDistortion, radTanDistortionJacobian); + ux *= focalLength; uy *= focalLength; // Convert back to pixel coordinates } break; @@ -354,6 +358,7 @@ void removeDistortion(double dx, double dy, double &ux, double &uy, void applyDistortion(double ux, double uy, double &dx, double &dy, std::vector<double> const& opticalDistCoeffs, + double focalLength, DistortionType distortionType, const double desiredPrecision, const double tolerance) { dx = ux; @@ -634,7 +639,9 @@ void applyDistortion(double ux, double uy, double &dx, double &dy, // with the RADTAN model. See computeRadTanDistortion() for more details. case RADTAN: { + ux /= focalLength; uy /= focalLength; // Find normalized coordinates computeRadTanDistortion(ux, uy, dx, dy, opticalDistCoeffs); + dx *= focalLength; dy *= focalLength; // Convert back to pixel coordinates } break; diff --git a/src/UsgsAstroFrameSensorModel.cpp b/src/UsgsAstroFrameSensorModel.cpp index 222e4ca463506f1e0a997170978c3aaf12f9b6cb..d702253c62ff8e28c16a9dcc7760810dbe0bfdc8 100644 --- a/src/UsgsAstroFrameSensorModel.cpp +++ b/src/UsgsAstroFrameSensorModel.cpp @@ -172,12 +172,8 @@ csm::ImageCoord UsgsAstroFrameSensorModel::groundToImage( // Apply the distortion to the line/sample location and then convert back to // line/sample double distortedX, distortedY; - // Divide by focal length - undistortedx /= f; undistortedy /= f; applyDistortion(undistortedx, undistortedy, distortedX, distortedY, - m_opticalDistCoeffs, m_distortionType); - // Apply multiplication by focal length - distortedX *= f; distortedY *= f; + m_opticalDistCoeffs, m_focalLength, m_distortionType); MESSAGE_LOG( spdlog::level::trace, @@ -272,16 +268,10 @@ csm::EcefCoord UsgsAstroFrameSensorModel::imageToGround( m_detectorLineSumming, m_startingDetectorSample, m_startingDetectorLine, &m_iTransS[0], &m_iTransL[0], x_camera, y_camera); - // divide x_camera and y_camera by focal length - x_camera /= m_focalLength; y_camera /= m_focalLength; - // Apply the distortion model (remove distortion) double undistortedX, undistortedY; removeDistortion(x_camera, y_camera, undistortedX, undistortedY, - m_opticalDistCoeffs, m_distortionType); - - // Multiply by focal length - undistortedX *= m_focalLength; undistortedY *= m_focalLength; + m_opticalDistCoeffs, m_focalLength, m_distortionType); MESSAGE_LOG( spdlog::level::trace, @@ -405,13 +395,9 @@ csm::EcefLocus UsgsAstroFrameSensorModel::imageToRemoteImagingLocus( // Distort double undistortedFocalPlaneX, undistortedFocalPlaneY; - // divide by focal length - focalPlaneX /= m_focalLength; focalPlaneY /= m_focalLength; removeDistortion(focalPlaneX, focalPlaneY, undistortedFocalPlaneX, undistortedFocalPlaneY, m_opticalDistCoeffs, - m_distortionType); - // Multiply by focal length - undistortedFocalPlaneX *= m_focalLength; undistortedFocalPlaneY *= m_focalLength; + m_focalLength, m_distortionType); MESSAGE_LOG( spdlog::level::trace, diff --git a/src/UsgsAstroLsSensorModel.cpp b/src/UsgsAstroLsSensorModel.cpp index 8d1d9857a3a78732a8a4462f92112c63a9380beb..d59e78b3603ed95cd9b721a3a976c1a5705e9ef9 100644 --- a/src/UsgsAstroLsSensorModel.cpp +++ b/src/UsgsAstroLsSensorModel.cpp @@ -774,7 +774,8 @@ csm::ImageCoord UsgsAstroLsSensorModel::groundToImage( // Invert distortion double distortedFocalX, distortedFocalY; applyDistortion(detectorView[0], detectorView[1], distortedFocalX, - distortedFocalY, m_opticalDistCoeffs, m_distortionType, + distortedFocalY, m_opticalDistCoeffs, m_focalLength, + m_distortionType, desiredPrecision); MESSAGE_LOG( spdlog::level::trace, @@ -1876,7 +1877,7 @@ void UsgsAstroLsSensorModel::losToEcf( double undistortedFocalPlaneX, undistortedFocalPlaneY; removeDistortion(distortedFocalPlaneX, distortedFocalPlaneY, undistortedFocalPlaneX, undistortedFocalPlaneY, - m_opticalDistCoeffs, m_distortionType); + m_opticalDistCoeffs, m_focalLength, m_distortionType); MESSAGE_LOG( spdlog::level::trace, "losToEcf: undistorted focal plane coordinate {} {}", @@ -2800,7 +2801,7 @@ double UsgsAstroLsSensorModel::calcDetectorLineErr(double t, csm::ImageCoord con // Invert distortion double distortedFocalX, distortedFocalY; applyDistortion(detectorView[0], detectorView[1], distortedFocalX, - distortedFocalY, m_opticalDistCoeffs, m_distortionType); + distortedFocalY, m_opticalDistCoeffs, m_focalLength, m_distortionType); // Convert to detector line double detectorLine = m_iTransL[0] + m_iTransL[1] * distortedFocalX + diff --git a/src/UsgsAstroPushFrameSensorModel.cpp b/src/UsgsAstroPushFrameSensorModel.cpp index 10542000c09c8a554d2511ff8c050e7c0a269a33..a91948711f9fa19426275ab48661030ba805b574 100644 --- a/src/UsgsAstroPushFrameSensorModel.cpp +++ b/src/UsgsAstroPushFrameSensorModel.cpp @@ -762,8 +762,8 @@ csm::ImageCoord UsgsAstroPushFrameSensorModel::groundToImage( // Invert distortion double distortedFocalX, distortedFocalY; applyDistortion(focalCoord[0], focalCoord[1], distortedFocalX, - distortedFocalY, m_opticalDistCoeffs, m_distortionType, - desiredPrecision); + distortedFocalY, m_opticalDistCoeffs, m_focalLength, + m_distortionType, desiredPrecision); // Convert to detector line and sample double detectorLine = m_iTransL[0] + m_iTransL[1] * distortedFocalX + @@ -1793,7 +1793,7 @@ void UsgsAstroPushFrameSensorModel::losToEcf( double undistortedFocalPlaneX, undistortedFocalPlaneY; removeDistortion(distortedFocalPlaneX, distortedFocalPlaneY, undistortedFocalPlaneX, undistortedFocalPlaneY, - m_opticalDistCoeffs, m_distortionType); + m_opticalDistCoeffs, m_focalLength, m_distortionType); MESSAGE_LOG("losToEcf: undistorted focal plane coordinate {} {}", undistortedFocalPlaneX, undistortedFocalPlaneY)