diff --git a/modules/calib3d/src/calibration.cpp b/modules/calib3d/src/calibration.cpp index c03e3a1c34..d488e4569e 100644 --- a/modules/calib3d/src/calibration.cpp +++ b/modules/calib3d/src/calibration.cpp @@ -3188,8 +3188,8 @@ cvRQDecomp3x3( const CvMat *matrixM, CvMat *matrixR, CvMat *matrixQ, Qx = ( 0 c s ), c = m33/sqrt(m32^2 + m33^2), s = m32/sqrt(m32^2 + m33^2) ( 0 -s c ) */ - s = matM[2][1]; - c = matM[2][2]; + 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); c *= z; s *= z; @@ -3207,8 +3207,8 @@ cvRQDecomp3x3( const CvMat *matrixM, CvMat *matrixR, CvMat *matrixQ, Qy = ( 0 1 0 ), c = m33/sqrt(m31^2 + m33^2), s = -m31/sqrt(m31^2 + m33^2) ( s 0 c ) */ - s = -matR[2][0]; - c = matR[2][2]; + 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); c *= z; s *= z; @@ -3227,8 +3227,8 @@ cvRQDecomp3x3( const CvMat *matrixM, CvMat *matrixR, CvMat *matrixQ, ( 0 0 1 ) */ - s = matM[1][0]; - c = matM[1][1]; + 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); c *= z; s *= z; diff --git a/modules/calib3d/test/test_decompose_projection.cpp b/modules/calib3d/test/test_decompose_projection.cpp index e43aa65b69..0e3a420d69 100644 --- a/modules/calib3d/test/test_decompose_projection.cpp +++ b/modules/calib3d/test/test_decompose_projection.cpp @@ -141,4 +141,23 @@ TEST(Calib3d_DecomposeProjectionMatrix, accuracy) test.safe_run(); } +TEST(Calib3d_DecomposeProjectionMatrix, degenerate_cases) +{ + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 2; j++) + { + cv::Matx34d P; + P(0, i) = 1; + P(1, (i + j + 1) % 3) = 1; + P(2, (i + 2 * j + 2) % 3) = 1; + + cv::Matx33d K, R; + cv::Vec4d t; + decomposeProjectionMatrix(P, K, R, t); + EXPECT_LT(cv::norm(K * R, P.get_minor<3, 3>(0, 0), cv::NORM_INF), 1e-6); + } + } +} + }} // namespace