【问题标题】:OpenCV real-time stereocam image processing problems (post-calibration)OpenCV 实时立体摄像头图像处理问题(校准后)
【发布时间】:2016-04-20 03:37:47
【问题描述】:

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

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

代码和图片如下。

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


棋盘标定图:

左摄像头图像:

后 StereoBM 处理:

代码片段:

//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);
    }

【问题讨论】:

  • 自动对焦会改变相机的校准 - 你需要禁用它。

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


【解决方案1】:

所以,半个像素的 RMS 误差意味着你的校准基本上是垃圾。

在您的校准图像中,我注意到目标甚至不是平坦的。如果我能看到,相机也能看到,但校准模型仍会假设它是平坦的,这会让优化器非常难过。

建议你看看this answer关于校准。

【讨论】:

  • 这是一篇很棒的帖子,我希望它更醒目、更容易找到。我不确定这是否是您的专业领域,但您知道关闭 USB 相机自动对焦的可靠方法吗?我正在运行 ubuntu 14.04。我一直无法找到通过 openCV 将其关闭的方法,(通过 VideoCapture::set 没有运气)我也没有通过 uvcdynctrl 手动关闭它。我和其中两个人一起跑步:amazon.com/gp/product/B00VLXV4FU/…
  • 不具体,但我会先用谷歌搜索相机板序列号(或所有芯片的 ID),并希望出现规格表(或更好的应用程序员手册),并希望有一个焦点控制/开关输入,然后我会祈祷这个特殊板的设计者有智慧将它路由到 USB 控制器,最后,我会非常仔细地阅读 USB 驱动程序文档看看如何断言该信号。不用说,您在这条链条上被搞砸的机会每一步都会增加:CV专用相机花钱是有原因的:-(
猜你喜欢
  • 2015-08-01
  • 1970-01-01
  • 2012-10-24
  • 2014-07-30
  • 2021-02-13
  • 2012-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多