From 6d381556cf5c7cba15a6b9f018637fd4609df3d5 Mon Sep 17 00:00:00 2001 From: Vincent Rabaud Date: Fri, 26 Jan 2024 13:47:49 +0100 Subject: [PATCH 1/2] Fix rectangle rounding in cvGetOptimalNewCameraMatrix. This fixes https://github.com/opencv/opencv/issues/24831 --- modules/calib3d/src/calibration.cpp | 13 +++++++------ modules/calib3d/test/test_undistort.cpp | 11 ++++++++++- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/modules/calib3d/src/calibration.cpp b/modules/calib3d/src/calibration.cpp index c03e3a1c345f..1b389923c238 100644 --- a/modules/calib3d/src/calibration.cpp +++ b/modules/calib3d/src/calibration.cpp @@ -2808,9 +2808,6 @@ void cvGetOptimalNewCameraMatrix( const CvMat* cameraMatrix, const CvMat* distCo (double)((inner.y - cy0)*s + cy), (double)(inner.width*s), (double)(inner.height*s)); - cv::Rect r(cvCeil(inner.x), cvCeil(inner.y), cvFloor(inner.width), cvFloor(inner.height)); - r &= cv::Rect(0, 0, newImgSize.width, newImgSize.height); - *validPixROI = cvRect(r); } } else @@ -2840,11 +2837,15 @@ void cvGetOptimalNewCameraMatrix( const CvMat* cameraMatrix, const CvMat* distCo if( validPixROI ) { icvGetRectangles( cameraMatrix, distCoeffs, 0, &matM, imgSize, inner, outer ); - cv::Rect r = inner; - r &= cv::Rect(0, 0, newImgSize.width, newImgSize.height); - *validPixROI = cvRect(r); } } + if( validPixROI ) + { + cv::Rect r(cvFloor(inner.x), cvFloor(inner.y), cvCeil(inner.x+inner.width)-cvFloor(inner.x)+1, + cvCeil(inner.y+inner.height)-cvFloor(inner.y)+1); + r &= cv::Rect(0, 0, newImgSize.width, newImgSize.height); + *validPixROI = cvRect(r); + } cvConvert(&matM, newCameraMatrix); } diff --git a/modules/calib3d/test/test_undistort.cpp b/modules/calib3d/test/test_undistort.cpp index 38537c86215b..772bca100dca 100644 --- a/modules/calib3d/test/test_undistort.cpp +++ b/modules/calib3d/test/test_undistort.cpp @@ -171,6 +171,7 @@ class CV_GetOptimalNewCameraMatrixNoDistortionTest : public cvtest::ArrayTest cv::Mat camera_mat; cv::Mat distortion_coeffs; cv::Mat new_camera_mat; + cv::Rect validPixROI; cv::Size img_size; double alpha; @@ -187,6 +188,8 @@ CV_GetOptimalNewCameraMatrixNoDistortionTest::CV_GetOptimalNewCameraMatrixNoDist test_array[INPUT].push_back(NULL); // camera_mat test_array[INPUT].push_back(NULL); // distortion_coeffs test_array[OUTPUT].push_back(NULL); // new_camera_mat + test_array[OUTPUT].push_back(NULL); // validPixROI + test_array[REF_OUTPUT].push_back(NULL); test_array[REF_OUTPUT].push_back(NULL); alpha = 0.0; @@ -199,7 +202,9 @@ void CV_GetOptimalNewCameraMatrixNoDistortionTest::get_test_array_types_and_size cvtest::ArrayTest::get_test_array_types_and_sizes(test_case_idx, sizes, types); RNG& rng = ts->get_rng(); matrix_type = types[INPUT][0] = types[INPUT][1] = types[OUTPUT][0] = types[REF_OUTPUT][0] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F; + types[OUTPUT][1] = types[REF_OUTPUT][1] = CV_32S; sizes[INPUT][0] = sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(3,3); + sizes[OUTPUT][1] = sizes[REF_OUTPUT][1] = Size(4,1); sizes[INPUT][1] = cvSize(1,4); } @@ -240,7 +245,7 @@ int CV_GetOptimalNewCameraMatrixNoDistortionTest::prepare_test_case(int test_cas void CV_GetOptimalNewCameraMatrixNoDistortionTest::run_func() { - new_camera_mat = cv::getOptimalNewCameraMatrix(camera_mat, distortion_coeffs, img_size, alpha, img_size, NULL, center_principal_point); + new_camera_mat = cv::getOptimalNewCameraMatrix(camera_mat, distortion_coeffs, img_size, alpha, img_size, &validPixROI, center_principal_point); } void CV_GetOptimalNewCameraMatrixNoDistortionTest::prepare_to_validation(int /*test_case_idx*/) @@ -248,9 +253,13 @@ void CV_GetOptimalNewCameraMatrixNoDistortionTest::prepare_to_validation(int /*t const Mat& src = test_mat[INPUT][0]; Mat& dst = test_mat[REF_OUTPUT][0]; cvtest::copy(src, dst); + Mat& ref_validPixROI = test_mat[REF_OUTPUT][1]; + cvtest::copy(cv::Mat(cv::Vec4i(0, 0, img_size.width, img_size.height)), ref_validPixROI); Mat& output = test_mat[OUTPUT][0]; cvtest::convert(new_camera_mat, output, output.type()); + Mat& output_validPixROI = test_mat[OUTPUT][1]; + cvtest::copy(cv::Mat(cv::Vec4i(validPixROI.x, validPixROI.y, validPixROI.width, validPixROI.height)), output_validPixROI); } //--------- From bb70447fb0b81ee435f9fa11bdad4b34dfbe9deb Mon Sep 17 00:00:00 2001 From: Vincent Rabaud Date: Tue, 30 Jan 2024 14:23:15 +0100 Subject: [PATCH 2/2] Add a tolerance to rectangle computation. --- modules/calib3d/src/calibration.cpp | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/modules/calib3d/src/calibration.cpp b/modules/calib3d/src/calibration.cpp index 1b389923c238..97ddcf357b85 100644 --- a/modules/calib3d/src/calibration.cpp +++ b/modules/calib3d/src/calibration.cpp @@ -2841,8 +2841,32 @@ void cvGetOptimalNewCameraMatrix( const CvMat* cameraMatrix, const CvMat* distCo } if( validPixROI ) { - cv::Rect r(cvFloor(inner.x), cvFloor(inner.y), cvCeil(inner.x+inner.width)-cvFloor(inner.x)+1, - cvCeil(inner.y+inner.height)-cvFloor(inner.y)+1); + // This tolerance defines how incomplete a pixel can be to still be considered complete. + // It has been chosen to get Calib3d_GetOptimalNewCameraMatrixNoDistortion.accuracy to pass. + constexpr double kTolerance = 1e-12; + Point p1, p2; + if( std::abs(inner.x-cvRound(inner.x)) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy