From 8329c09ba88d569aba4bb7515a78fbe12db3219e Mon Sep 17 00:00:00 2001 From: Rostislav Vasilikhin Date: Fri, 27 Jan 2023 07:40:08 +0100 Subject: [PATCH] Merge pull request #23178 from savuor:stddev_calib_fisheye Fixes #23057 Parameter uncertainty fixed + ground truth test data fixed ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake --- modules/calib/src/fisheye.cpp | 7 ++++++- modules/calib/test/test_fisheye.cpp | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/modules/calib/src/fisheye.cpp b/modules/calib/src/fisheye.cpp index a7eb6d202b..cb715cd729 100644 --- a/modules/calib/src/fisheye.cpp +++ b/modules/calib/src/fisheye.cpp @@ -1568,13 +1568,18 @@ void cv::internal::EstimateUncertainties(InputArrayOfArrays objectPoints, InputA Vec sigma_x; meanStdDev(ex.reshape(1, 1), noArray(), sigma_x); - sigma_x *= sqrt(2.0 * (double)ex.total()/(2.0 * (double)ex.total() - 1.0)); Mat JJ2, ex3; ComputeJacobians(objectPoints, imagePoints, params, omc, Tc, check_cond, thresh_cond, JJ2, ex3); sqrt(JJ2.inv(), JJ2); + int nParams = JJ2.rows; + // an explanation of that denominator correction can be found here: + // R. Hartley, A. Zisserman, Multiple View Geometry in Computer Vision, 2004, section 5.1.3, page 134 + // see the discussion for more details: https://github.com/opencv/opencv/pull/22992 + sigma_x *= sqrt(2.0 * (double)ex.total()/(2.0 * (double)ex.total() - nParams)); + errors = 3 * sigma_x(0) * JJ2.diag(); rms = sqrt(norm(ex, NORM_L2SQR)/ex.total()); } diff --git a/modules/calib/test/test_fisheye.cpp b/modules/calib/test/test_fisheye.cpp index 7c93206153..f85bdfd68c 100644 --- a/modules/calib/test/test_fisheye.cpp +++ b/modules/calib/test/test_fisheye.cpp @@ -597,9 +597,9 @@ TEST_F(fisheyeTest, EstimateUncertainties) cv::internal::EstimateUncertainties(objectPoints, imagePoints, param, rvec, tvec, errors, err_std, thresh_cond, check_cond, rms); - EXPECT_MAT_NEAR(errors.f, cv::Vec2d(1.29837104202046, 1.31565641071524), 1e-10); - EXPECT_MAT_NEAR(errors.c, cv::Vec2d(0.890439368129246, 0.816096854937896), 1e-10); - EXPECT_MAT_NEAR(errors.k, cv::Vec4d(0.00516248605191506, 0.0168181467500934, 0.0213118690274604, 0.00916010877545648), 1e-10); + EXPECT_MAT_NEAR(errors.f, cv::Vec2d(1.34250246865020720, 1.36037536429654530), 1e-10); + EXPECT_MAT_NEAR(errors.c, cv::Vec2d(0.92070526160049848, 0.84383585812851514), 1e-10); + EXPECT_MAT_NEAR(errors.k, cv::Vec4d(0.0053379581373996041, 0.017389792901700545, 0.022036256089491224, 0.0094714594258908952), 1e-10); EXPECT_MAT_NEAR(err_std, cv::Vec2d(0.187475975266883, 0.185678953263995), 1e-10); CV_Assert(fabs(rms - 0.263782587133546) < 1e-10); CV_Assert(errors.alpha == 0);