Merge pull request #16024 from alalek:issue_15953

pull/16068/head^2
Alexander Alekhin 5 years ago
commit c790779a37
  1. 28
      modules/calib3d/src/calibration.cpp
  2. 104
      modules/calib3d/test/test_cameracalibration.cpp

@ -1212,8 +1212,8 @@ CV_IMPL void cvInitIntrinsicParams2D( const CvMat* objectPoints,
matA.reset(cvCreateMat( 2*nimages, 2, CV_64F ));
_b.reset(cvCreateMat( 2*nimages, 1, CV_64F ));
a[2] = (!imageSize.width) ? 0.5 : (imageSize.width)*0.5;
a[5] = (!imageSize.height) ? 0.5 : (imageSize.height)*0.5;
a[2] = (!imageSize.width) ? 0.5 : (imageSize.width - 1)*0.5;
a[5] = (!imageSize.height) ? 0.5 : (imageSize.height - 1)*0.5;
_allH.reset(cvCreateMat( nimages, 9, CV_64F ));
// extract vanishing points in order to obtain initial value for the focal length
@ -2363,8 +2363,8 @@ void cvStereoRectify( const CvMat* _cameraMatrix1, const CvMat* _cameraMatrix2,
for( i = 0; i < 4; i++ )
{
int j = (i<2) ? 0 : 1;
_pts[i].x = (float)((i % 2)*(nx));
_pts[i].y = (float)(j*(ny));
_pts[i].x = (float)((i % 2)*(nx-1));
_pts[i].y = (float)(j*(ny-1));
}
cvUndistortPoints( &pts, &pts, A, Dk, 0, 0 );
cvConvertPointsHomogeneous( &pts, &pts_3 );
@ -2378,8 +2378,8 @@ void cvStereoRectify( const CvMat* _cameraMatrix1, const CvMat* _cameraMatrix2,
_a_tmp[1][2]=0.0;
cvProjectPoints2( &pts_3, k == 0 ? _R1 : _R2, &Z, &A_tmp, 0, &pts );
CvScalar avg = cvAvg(&pts);
cc_new[k].x = (nx)/2 - avg.val[0];
cc_new[k].y = (ny)/2 - avg.val[1];
cc_new[k].x = (nx-1)/2 - avg.val[0];
cc_new[k].y = (ny-1)/2 - avg.val[1];
}
// vertical focal length must be the same for both images to keep the epipolar constraint
@ -2516,8 +2516,8 @@ void cvGetOptimalNewCameraMatrix( const CvMat* cameraMatrix, const CvMat* distCo
{
double cx0 = M[0][2];
double cy0 = M[1][2];
double cx = (newImgSize.width)*0.5;
double cy = (newImgSize.height)*0.5;
double cx = (newImgSize.width-1)*0.5;
double cy = (newImgSize.height-1)*0.5;
icvGetRectangles( cameraMatrix, distCoeffs, 0, cameraMatrix, imgSize, inner, outer );
double s0 = std::max(std::max(std::max((double)cx/(cx0 - inner.x), (double)cy/(cy0 - inner.y)),
@ -2551,14 +2551,14 @@ void cvGetOptimalNewCameraMatrix( const CvMat* cameraMatrix, const CvMat* distCo
icvGetRectangles( cameraMatrix, distCoeffs, 0, 0, imgSize, inner, outer );
// Projection mapping inner rectangle to viewport
double fx0 = (newImgSize.width) / inner.width;
double fy0 = (newImgSize.height) / inner.height;
double fx0 = (newImgSize.width - 1) / inner.width;
double fy0 = (newImgSize.height - 1) / inner.height;
double cx0 = -fx0 * inner.x;
double cy0 = -fy0 * inner.y;
// Projection mapping outer rectangle to viewport
double fx1 = (newImgSize.width) / outer.width;
double fy1 = (newImgSize.height) / outer.height;
double fx1 = (newImgSize.width - 1) / outer.width;
double fy1 = (newImgSize.height - 1) / outer.height;
double cx1 = -fx1 * outer.x;
double cy1 = -fy1 * outer.y;
@ -2622,8 +2622,8 @@ CV_IMPL int cvStereoRectifyUncalibrated(
cvGEMM( &U, &W, 1, 0, 0, &W, CV_GEMM_A_T );
cvMatMul( &W, &V, &F );
cx = cvRound( (imgSize.width)*0.5 );
cy = cvRound( (imgSize.height)*0.5 );
cx = cvRound( (imgSize.width-1)*0.5 );
cy = cvRound( (imgSize.height-1)*0.5 );
cvZero( _H1 );
cvZero( _H2 );

@ -1345,108 +1345,6 @@ 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<double>(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<double, 5, 1> D1(0.0064836857220181504, 0.033880363848984636, 0.0, 0.0, -0.042996356352306114);
const Matx<double, 5, 1> 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_EXACT);
// perform resize-remap
Mat rsz_result;
resize(image, rsz_result, Size(), scale, scale, INTER_LINEAR_EXACT);
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,
(int)(src_result.cols / 3.1), int(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:
@ -2250,7 +2148,7 @@ TEST(Calib3d_ProjectPoints_CPP, outputShape)
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_StereoCalibrate_CPP, extended)
{

Loading…
Cancel
Save