cpp verison of StereoRectify is wrong (Bug #1338)


Added by Patrick Beeson over 13 years ago. Updated almost 13 years ago.


Status:Cancelled Start date:
Priority:Blocker Due date:
Assignee:Vadim Pisarevsky % Done:

0%

Category:calibration, 3d
Target version:2.4.0
Affected version: Operating System:
Difficulty: HW Platform:
Pull request:

Description

Back when ROS was using cv 2.0, there was that pesky bug somewhere in calibration that caused incorrect calibration. So, I wrote my own offline stereo calibration program that used cv 2.1 and got good results. Over the last week, I've been trying to calibrate a new camera and getting horrible results (the final rectified images I see after calling steroRectify, initUndistortMap, and remap were basically zooming in on very small parts of the two images.

After a while, I noticed that the P1, P2 returned were fishy looking, so instead of using those, I set P1 and P2 to the intrinsic matrices and calulated new rectification matricies (R1,R2) directly from the fundamental matrix (Hartley's method). This gave good results.

I also then ran the offline 'calibrate from tar' script in ROS calibrate_camera package, which does EXACTLY the same process of stereo calibration, but using Python. Here, I get out good quality rectification and projection matrices from stereoRectify. In short, cv 2.2 (and 2.3) stereorectify gives proper results in Python, but incorrect results in C++. I tested this by giving the two the exact same images, verifying that stereorectify is getting the same intrinsic and extrinsic parameters.


Associated revisions

Revision 90cf8fbd
Added by Roman Donchenko over 11 years ago

Merge pull request #1338 from asmorkalov:android_tegra_detector

History

Updated by Patrick Beeson over 13 years ago

Here is some code where if you run stereoRectify on same intrinsics/extrinsics from stereoCalibrate(), when get weird P1 and P2, but if you calcualte them using stereoRectifyUncalibrated they work (but the fx/fy in the two projection matricies are no longer equal, which isn't the best -- I know some code just looks at fx/fy in one of the two matrices and assumes they are equal).

 1Mat R1, R2, P1, P2, Q;
 2Rect validRoir2;
 3
 4stereoRectify(cameraMatrixr0, distCoeffsr0,
 5          cameraMatrixr1, distCoeffsr1,
 6          imageSize, R, T, R1, R2, P1, P2, Q,
 7          0, imageSize, &validRoir0, &validRoir1, CV_CALIB_ZERO_DISPARITY);
 8
 9    Mat rmapr2r2;
10// IF BY CALIBRATED (BOUGUET'S METHOD)
11    if( useCalibrated )
12    {
13        // we already computed everything
14
15      //BUT P1 and P2 have REALLY large numbers and are correct.
16
17    }
18// OR ELSE HARTLEY'S METHOD
19    else
20 // use intrinsic parameters of each camera, but
21 // compute the rectification transformation directly
22 // from the fundamental matrix
23    {
24        vector<Point2f> allimgptr2;
25        for( k = 0; k < 2; k++ )
26        {
27            for( i = 0; i < nimages; i++ )
28                std::copy(imagePoints[k][i].begin(), imagePoints[k][i].end(), back_inserter(allimgpt[k]));
29        }
30        F = findFundamentalMat(Mat(allimgptr0), Mat(allimgptr1), FM_8POINT, 0, 0);
31        Mat H1, H2;
32        stereoRectifyUncalibrated(Mat(allimgptr0), Mat(allimgptr1), F, imageSize, H1, H2, 3);
33
34        R1 = cameraMatrixr0.inv()*H1*cameraMatrixr0;
35        R2 = cameraMatrixr1.inv()*H2*cameraMatrixr1;
36    P1 = Mat::zeros(3, 4, CV_64F);
37    P2 = Mat::zeros(3, 4, CV_64F);
38
39    for (uint i=0;i<3;i++)
40      for (uint j=0;j<3;j++) {
41        P1.at<double>(i,j) = cameraMatrixr0.at<double>(i,j);
42        P2.at<double>(i,j) = cameraMatrixr1.at<double>(i,j);
43      }
44    P2.at<double>(0,3) = P2.at<double>(0,0)*T.at<double>(0,0);
45
46    // P1 and P2 are now good but P1(0,0) != P2(0,0) (same for
47    // (1,1)) would like them to be the same.
48
49    }

Updated by Patrick Beeson over 13 years ago

I now believe the issue was with stereoCalibrate converging to a bad set of parameters on occasion.

  • Status changed from Open to Done
  • (deleted custom field) set to invalid

Updated by Andrey Kamaev almost 13 years ago

  • Status changed from Done to Cancelled
  • Target version set to 2.4.0

Also available in: Atom PDF