OpenCV实时立体视觉图像处理问题(后期校准)

时间:2016-01-14 17:25:14

标签: c++ opencv camera-calibration stereo-3d

我用两个USB摄像头构建了自己的立体摄像机(带有烦人的自动对焦)。我使用/opencv/samples/cpp/stereo_calib.cpp',校准了它们,产生了一个extrinsics / intrinsics文件,其RMS误差 0.4818 ,平均重投影误差 0.5426

我现在正尝试在openCV中使用Ptr<StereoBM> bm运行实时深度映射。我得到了无用的图像,我想知道是否有人可以指出我在哪里看正确的方向。我还想知道相机的自动对焦是否经常会改变焦距,从而改变校准,改变结果。

下面的代码和图片。

如果有人可以推荐比StereoBM更强大的方法在openCV中进行匹配,那么可以获得奖励:)

棋盘格校准图像:enter image description here

左镜头图像: enter image description here

发布StereoBM处理: enter image description here

代码片段:

//Set up stereoBM
    Ptr<StereoBM> bm = StereoBM::create(16,9);

    //Read intrinsice parameters
    string intrinsic_filepath = "/home/will/Desktop/repos3.0/stereo-vision/Stereo-Vision/intrinsics.yml";
    FileStorage fs(intrinsic_filepath, FileStorage::READ);
    if(!fs.isOpened())
    {
        printf("Failed to open intrinsics.yml");
        return -1;
    }
    Mat M1, D1, M2, D2;
    fs["M1"] >> M1;
    fs["D1"] >> D1;
    fs["M2"] >> M2;
    fs["D2"] >> D2;

    //Read Extrinsic Parameters
    string extrinsic_filepath = "/home/will/Desktop/repos3.0/stereo-vision/Stereo-Vision/extrinsics.yml";
    fs.open(extrinsic_filepath, FileStorage::READ);
    if(!fs.isOpened())
    {
        printf("Failed to open extrinsics");
        return -1;
    }

    Mat R, T, R1, P1, R2, P2;
    fs["R"] >> R;
    fs["T"] >> T;

    Mat frame1,frame2, gray1, gray2;
    int counter = 0;

    capture >> frame1;
    capture >> frame2;

    Size img_size = frame1.size();
    Rect roi1, roi2;
    Mat Q;

    stereoRectify( M1, D1, M2, D2, img_size, R, T, R1, R2, P1, P2, Q, CALIB_ZERO_DISPARITY, -1, img_size, &roi1, &roi2 );

    Mat map11, map12, map21, map22;
    initUndistortRectifyMap(M1, D1, R1, P1, img_size, CV_16SC2, map11, map12);
    initUndistortRectifyMap(M2, D2, R2, P2, img_size, CV_16SC2, map21, map22);

    int numberOfDisparities = 16;
    int SADWindowSize = 9;

    bm->setROI1(roi1);
    bm->setROI2(roi2);
    bm->setPreFilterCap(31);
    bm->setBlockSize(SADWindowSize);
    bm->setMinDisparity(0);
    bm->setNumDisparities(numberOfDisparities);
    bm->setTextureThreshold(10);
    bm->setUniquenessRatio(15);
    bm->setSpeckleWindowSize(100);
    bm->setSpeckleRange(32);
    bm->setDisp12MaxDiff(1);

    while(1){
        capture >> frame1;
        capture2 >> frame2;
        imshow("Cam1", frame1);
        imshow("Cam2", frame2);

        /************************* STEREO ***********************/

        cvtColor(frame1, gray1, CV_RGB2GRAY);
        cvtColor(frame2, gray2, CV_RGB2GRAY);

        int64 t = getTickCount();

        Mat img1r, img2r;
        remap(gray1, img1r, map11, map12, INTER_LINEAR);
        remap(gray2, img2r, map21, map22, INTER_LINEAR);

        Mat disp, disp8;
        bm->compute(img1r, img2r, disp);
        t = getTickCount() - t;
        printf("Time elapsed: %fms\n", t*1000/getTickFrequency());

        disp.convertTo(disp8, CV_8U, 255/(numberOfDisparities*16.));
        imshow("disparity", disp8);
    }

1 个答案:

答案 0 :(得分:1)

因此,RMS误差的半个像素意味着您的校准基本上是垃圾。

在校准图像中,我注意到目标甚至不平坦。如果我可以看到,相机也可以,但校准模型仍然会认为它是平的,这将使优化器非常悲伤。

建议您查看有关校准的this answer