diff --git a/modules/calib3d/src/calibration.cpp b/modules/calib3d/src/calibration.cpp index 24d2875fdd..50940a80ff 100644 --- a/modules/calib3d/src/calibration.cpp +++ b/modules/calib3d/src/calibration.cpp @@ -3190,7 +3190,7 @@ cvRQDecomp3x3( const CvMat *matrixM, CvMat *matrixR, CvMat *matrixQ, */ s = std::abs(matM[2][1]) > DBL_EPSILON ? matM[2][1] : 0; c = std::abs(matM[2][1]) > DBL_EPSILON ? matM[2][2] : 1; - z = 1./std::sqrt(c * c + s * s + DBL_EPSILON); + z = 1./std::sqrt(c * c + s * s); c *= z; s *= z; @@ -3209,7 +3209,7 @@ cvRQDecomp3x3( const CvMat *matrixM, CvMat *matrixR, CvMat *matrixQ, */ s = std::abs(matR[2][0]) > DBL_EPSILON ? -matR[2][0] : 0; c = std::abs(matR[2][0]) > DBL_EPSILON ? matR[2][2] : 1; - z = 1./std::sqrt(c * c + s * s + DBL_EPSILON); + z = 1./std::sqrt(c * c + s * s); c *= z; s *= z; @@ -3229,7 +3229,7 @@ cvRQDecomp3x3( const CvMat *matrixM, CvMat *matrixR, CvMat *matrixQ, s = std::abs(matM[1][0]) > DBL_EPSILON ? matM[1][0] : 0; c = std::abs(matM[1][0]) > DBL_EPSILON ? matM[1][1] : 1; - z = 1./std::sqrt(c * c + s * s + DBL_EPSILON); + z = 1./std::sqrt(c * c + s * s); c *= z; s *= z; diff --git a/modules/calib3d/test/test_decompose_projection.cpp b/modules/calib3d/test/test_decompose_projection.cpp index 0e3a420d69..a25081b452 100644 --- a/modules/calib3d/test/test_decompose_projection.cpp +++ b/modules/calib3d/test/test_decompose_projection.cpp @@ -160,4 +160,24 @@ TEST(Calib3d_DecomposeProjectionMatrix, degenerate_cases) } } +TEST(Calib3d_DecomposeProjectionMatrix, bug_23733) +{ + cv::Matx34d P(52, -7, 4, 12, + -6, 49, 12, 8, + 4, 17, 1, 0); + P *= 1e-6; + + cv::Matx33d K, R; + cv::Vec4d t; + decomposeProjectionMatrix(P, K, R, t); + + EXPECT_LT(cv::norm(R.t() * R - cv::Matx33d::eye(), cv::NORM_INF), 1e-10); + + cv::Matx34d M; + cv::hconcat(R, -R * cv::Vec3d(t[0] / t[3], t[1] / t[3], t[2] / t[3]), M); + + cv::Matx34d P_recompose = K * M; + EXPECT_LT(cv::norm(P_recompose - P, cv::NORM_INF), 1e-16); +} + }} // namespace