diff --git a/modules/calib3d/test/test_cameracalibration.cpp b/modules/calib3d/test/test_cameracalibration.cpp index 2dad0cf222..357208dd6c 100644 --- a/modules/calib3d/test/test_cameracalibration.cpp +++ b/modules/calib3d/test/test_cameracalibration.cpp @@ -1346,6 +1346,108 @@ void CV_ProjectPointsTest_CPP::project( const Mat& objectPoints, const Mat& rvec ///////////////////////////////// Stereo Calibration ///////////////////////////////////// +class CV_StereoCalibrationCornerTest : public cvtest::BaseTest +{ +public: + CV_StereoCalibrationCornerTest(); + ~CV_StereoCalibrationCornerTest(); + void clear(); +protected: + void run(int); +}; + +CV_StereoCalibrationCornerTest::CV_StereoCalibrationCornerTest() +{ +} + + +CV_StereoCalibrationCornerTest::~CV_StereoCalibrationCornerTest() +{ + clear(); +} + +void CV_StereoCalibrationCornerTest::clear() +{ + cvtest::BaseTest::clear(); +} + +static bool resizeCameraMatrix(const Mat &in_cm, Mat &dst_cm, double scale) +{ + if (in_cm.empty() || in_cm.cols != 3 || in_cm.rows != 3 || in_cm.type() != CV_64FC1) + return false; + dst_cm = in_cm * scale; + dst_cm.at(2, 2) = 1.0; + return true; +} + +// see https://github.com/opencv/opencv/pull/6836 for details +void CV_StereoCalibrationCornerTest::run(int) +{ + const Matx33d M1(906.7857732303256, 0.0, 1026.456125870669, + 0.0, 906.7857732303256, 540.0531577669913, + 0.0, 0.0, 1.0); + const Matx33d M2(906.782205162265, 0.0, 1014.619997352785, + 0.0, 906.782205162265, 561.9990018887295, + 0.0, 0.0, 1.0); + const Matx D1(0.0064836857220181504, 0.033880363848984636, 0.0, 0.0, -0.042996356352306114); + const Matx D2(0.023754068600491646, -0.02364619610835259, 0.0, 0.0, 0.0015014971456262652); + + const Size imageSize(2048, 1088); + const double scale = 0.25; + + const Matx33d Rot(0.999788461750194, -0.015696495349844446, -0.013291041528534329, + 0.015233019205877604, 0.999296086451901, -0.034282455101525826, + 0.01381980018141639, 0.03407274036010432, 0.9993238021218641); + const Matx31d T(-1.552005597952028, 0.0019508251875105093, -0.023335501616116062); + + // generate camera matrices for resized image rectification. + Mat srcM1(M1), srcM2(M2); + Mat rszM1, rszM2; + resizeCameraMatrix(srcM1, rszM1, scale); + resizeCameraMatrix(srcM2, rszM2, scale); + Size rszImageSize(cvRound(scale * imageSize.width), cvRound(scale * imageSize.height)); + Size srcImageSize = imageSize; + // apply stereoRectify + Mat srcR[2], srcP[2], srcQ; + Mat rszR[2], rszP[2], rszQ; + stereoRectify(srcM1, D1, srcM2, D2, srcImageSize, Rot, T, + srcR[0], srcR[1], srcP[0], srcP[1], srcQ, + CALIB_ZERO_DISPARITY, 0); + stereoRectify(rszM1, D1, rszM2, D2, rszImageSize, Rot, T, + rszR[0], rszR[1], rszP[0], rszP[1], rszQ, + CALIB_ZERO_DISPARITY, 0); + // generate remap maps + Mat srcRmap[2], rszRmap[2]; + initUndistortRectifyMap(srcM1, D1, srcR[0], srcP[0], srcImageSize, CV_32FC2, srcRmap[0], srcRmap[1]); + initUndistortRectifyMap(rszM1, D1, rszR[0], rszP[0], rszImageSize, CV_32FC2, rszRmap[0], rszRmap[1]); + + // generate source image + // it's an artificial pattern with white rect in the center + Mat image(imageSize, CV_8UC3); + image.setTo(0); + image(cv::Rect(imageSize.width / 3, imageSize.height / 3, imageSize.width / 3, imageSize.height / 3)).setTo(255); + + // perform remap-resize + Mat src_result; + remap(image, src_result, srcRmap[0], srcRmap[1], INTER_LINEAR); + resize(src_result, src_result, Size(), scale, scale, INTER_LINEAR); + // perform resize-remap + Mat rsz_result; + resize(image, rsz_result, Size(), scale, scale, INTER_LINEAR); + remap(rsz_result, rsz_result, rszRmap[0], rszRmap[1], INTER_LINEAR); + + // modifying the camera matrix with resizeCameraMatrix must yield the same + // result as calibrating the downscaled images + int cnz = countNonZero((cv::Mat(src_result - rsz_result) != 0)( + cv::Rect(src_result.cols / 3, src_result.rows / 3, + src_result.cols / 3.1, src_result.rows / 3.1))); + if (cnz) + { + ts->printf( cvtest::TS::LOG, "The camera matrix is wrong for downscaled image\n"); + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + } +} + class CV_StereoCalibrationTest : public cvtest::BaseTest { public: @@ -1949,7 +2051,7 @@ TEST(Calib3d_ProjectPoints_C, accuracy) { CV_ProjectPointsTest_C test; test.saf TEST(Calib3d_ProjectPoints_CPP, regression) { CV_ProjectPointsTest_CPP test; test.safe_run(); } TEST(Calib3d_StereoCalibrate_C, regression) { CV_StereoCalibrationTest_C test; test.safe_run(); } TEST(Calib3d_StereoCalibrate_CPP, regression) { CV_StereoCalibrationTest_CPP test; test.safe_run(); } - +TEST(Calib3d_StereoCalibrateCorner, regression) { CV_StereoCalibrationCornerTest test; test.safe_run(); } TEST(Calib3d_Triangulate, accuracy) {