Skip to content

Commit e268fdc

Browse files
committed
Merge pull request opencv#10793 from denmatfoton:master
2 parents bb925fe + f378f1d commit e268fdc

File tree

2 files changed

+72
-19
lines changed

2 files changed

+72
-19
lines changed

modules/calib3d/src/calibration.cpp

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2296,7 +2296,7 @@ void cvStereoRectify( const CvMat* _cameraMatrix1, const CvMat* _cameraMatrix2,
22962296
CvRect* roi1, CvRect* roi2 )
22972297
{
22982298
double _om[3], _t[3] = {0}, _uu[3]={0,0,0}, _r_r[3][3], _pp[3][4];
2299-
double _ww[3], _wr[3][3], _z[3] = {0,0,0}, _ri[3][3];
2299+
double _ww[3], _wr[3][3], _z[3] = {0,0,0}, _ri[3][3], _w3[3];
23002300
cv::Rect_<float> inner1, inner2, outer1, outer2;
23012301

23022302
CvMat om = cvMat(3, 1, CV_64F, _om);
@@ -2305,11 +2305,13 @@ void cvStereoRectify( const CvMat* _cameraMatrix1, const CvMat* _cameraMatrix2,
23052305
CvMat r_r = cvMat(3, 3, CV_64F, _r_r);
23062306
CvMat pp = cvMat(3, 4, CV_64F, _pp);
23072307
CvMat ww = cvMat(3, 1, CV_64F, _ww); // temps
2308+
CvMat w3 = cvMat(3, 1, CV_64F, _w3); // temps
23082309
CvMat wR = cvMat(3, 3, CV_64F, _wr);
23092310
CvMat Z = cvMat(3, 1, CV_64F, _z);
23102311
CvMat Ri = cvMat(3, 3, CV_64F, _ri);
23112312
double nx = imageSize.width, ny = imageSize.height;
23122313
int i, k;
2314+
double nt, nw;
23132315

23142316
if( matR->rows == 3 && matR->cols == 3 )
23152317
cvRodrigues2(matR, &om); // get vector rotation
@@ -2320,15 +2322,33 @@ void cvStereoRectify( const CvMat* _cameraMatrix1, const CvMat* _cameraMatrix2,
23202322
cvMatMul(&r_r, matT, &t);
23212323

23222324
int idx = fabs(_t[0]) > fabs(_t[1]) ? 0 : 1;
2323-
double c = _t[idx], nt = cvNorm(&t, 0, CV_L2);
2324-
_uu[idx] = c > 0 ? 1 : -1;
23252325

2326-
// calculate global Z rotation
2327-
cvCrossProduct(&t,&uu,&ww);
2328-
double nw = cvNorm(&ww, 0, CV_L2);
2329-
if (nw > 0.0)
2330-
cvConvertScale(&ww, &ww, acos(fabs(c)/nt)/nw);
2331-
cvRodrigues2(&ww, &wR);
2326+
// if idx == 0
2327+
// e1 = T / ||T||
2328+
// e2 = e1 x [0,0,1]
2329+
2330+
// if idx == 1
2331+
// e2 = T / ||T||
2332+
// e1 = e2 x [0,0,1]
2333+
2334+
// e3 = e1 x e2
2335+
2336+
_uu[2] = 1;
2337+
cvCrossProduct(&uu, &t, &ww);
2338+
nt = cvNorm(&t, 0, CV_L2);
2339+
nw = cvNorm(&ww, 0, CV_L2);
2340+
cvConvertScale(&ww, &ww, 1 / nw);
2341+
cvCrossProduct(&t, &ww, &w3);
2342+
nw = cvNorm(&w3, 0, CV_L2);
2343+
cvConvertScale(&w3, &w3, 1 / nw);
2344+
_uu[2] = 0;
2345+
2346+
for (i = 0; i < 3; ++i)
2347+
{
2348+
_wr[idx][i] = -_t[i] / nt;
2349+
_wr[idx ^ 1][i] = -_ww[i];
2350+
_wr[2][i] = _w3[i] * (1 - 2 * idx); // if idx == 1 -> opposite direction
2351+
}
23322352

23332353
// apply to both views
23342354
cvGEMM(&wR, &r_r, 1, 0, 0, &Ri, CV_GEMM_B_T);
@@ -2342,16 +2362,11 @@ void cvStereoRectify( const CvMat* _cameraMatrix1, const CvMat* _cameraMatrix2,
23422362
double fc_new = DBL_MAX;
23432363
CvPoint2D64f cc_new[2] = {{0,0}, {0,0}};
23442364

2345-
for( k = 0; k < 2; k++ ) {
2346-
const CvMat* A = k == 0 ? _cameraMatrix1 : _cameraMatrix2;
2347-
const CvMat* Dk = k == 0 ? _distCoeffs1 : _distCoeffs2;
2348-
double dk1 = Dk && Dk->data.ptr ? cvmGet(Dk, 0, 0) : 0;
2349-
double fc = cvmGet(A,idx^1,idx^1);
2350-
if( dk1 < 0 ) {
2351-
fc *= 1 + dk1*(nx*nx + ny*ny)/(4*fc*fc);
2352-
}
2353-
fc_new = MIN(fc_new, fc);
2354-
}
2365+
newImgSize = newImgSize.width * newImgSize.height != 0 ? newImgSize : imageSize;
2366+
const double ratio_x = (double)newImgSize.width / imageSize.width / 2;
2367+
const double ratio_y = (double)newImgSize.height / imageSize.height / 2;
2368+
const double ratio = idx == 1 ? ratio_x : ratio_y;
2369+
fc_new = (cvmGet(_cameraMatrix1, idx ^ 1, idx ^ 1) + cvmGet(_cameraMatrix2, idx ^ 1, idx ^ 1)) * ratio;
23552370

23562371
for( k = 0; k < 2; k++ )
23572372
{

modules/calib3d/test/test_cameracalibration.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,6 +2116,44 @@ TEST(Calib3d_StereoCalibrate_CPP, extended)
21162116
EXPECT_TRUE(err.total() == 2);
21172117
}
21182118

2119+
TEST(Calib3d_StereoCalibrate, regression_10791)
2120+
{
2121+
const Matx33d M1(
2122+
853.1387981631528, 0, 704.154907802121,
2123+
0, 853.6445089162528, 520.3600712930319,
2124+
0, 0, 1
2125+
);
2126+
const Matx33d M2(
2127+
848.6090216909176, 0, 701.6162856852185,
2128+
0, 849.7040162357157, 509.1864036137,
2129+
0, 0, 1
2130+
);
2131+
const Matx<double, 14, 1> D1(-6.463598629567206, 79.00104930508179, -0.0001006144444464403, -0.0005437499822299972,
2132+
12.56900616588467, -6.056719942752855, 76.3842481414836, 45.57460250612659,
2133+
0, 0, 0, 0, 0, 0);
2134+
const Matx<double, 14, 1> D2(0.6123436439798265, -0.4671756923224087, -0.0001261947899033442, -0.000597334584036978,
2135+
-0.05660119809538371, 1.037075740629769, -0.3076042835831711, -0.2502169324283623,
2136+
0, 0, 0, 0, 0, 0);
2137+
2138+
const Matx33d R(
2139+
0.9999926627018476, -0.0001095586963765905, 0.003829169539302921,
2140+
0.0001021735876758584, 0.9999981346680941, 0.0019287874145156,
2141+
-0.003829373712065528, -0.001928382022437616, 0.9999908085776333
2142+
);
2143+
const Matx31d T(-58.9161771697128, -0.01581306249996402, -0.8492960216760961);
2144+
2145+
const Size imageSize(1280, 960);
2146+
2147+
Mat R1, R2, P1, P2, Q;
2148+
Rect roi1, roi2;
2149+
stereoRectify(M1, D1, M2, D2, imageSize, R, T,
2150+
R1, R2, P1, P2, Q,
2151+
CALIB_ZERO_DISPARITY, 1, imageSize, &roi1, &roi2);
2152+
2153+
EXPECT_GE(roi1.area(), 400*300) << roi1;
2154+
EXPECT_GE(roi2.area(), 400*300) << roi2;
2155+
}
2156+
21192157
TEST(Calib3d_Triangulate, accuracy)
21202158
{
21212159
// the testcase from http://code.opencv.org/issues/4334

0 commit comments

Comments
 (0)