立体视差图生成

Posted

技术标签:

【中文标题】立体视差图生成【英文标题】:Stereo Disparity map generation 【发布时间】:2015-03-07 13:28:49 【问题描述】:

我正在研究 KITTI 数据集,我正在拍摄 2 张​​图像并找到视差以获得 3D 点云。我面临的问题是我无法获得良好的视差图。大部分视差值是小于 0.1。视差值在 0 到 1 之间(我需要缩放它们吗)。 我的音响的参数如下所示

cv::StereoBM sbm;
    sbm.state->SADWindowSize = 9;
    sbm.state->numberOfDisparities = 112;
    sbm.state->preFilterSize = 5;
    sbm.state->preFilterCap = 1;
    sbm.state->minDisparity = 0;
    sbm.state->textureThreshold = 5;
    sbm.state->uniquenessRatio = 5;
    sbm.state->speckleWindowSize = 0;
    sbm.state->speckleRange = 20;
    sbm.state->disp12MaxDiff = 64;
sbm(leftimage, rightimage,disp);
    normalize(disp, disp8, 0.1, 255, CV_MINMAX, CV_8U);

【问题讨论】:

我的直觉是你的窗口尺寸太小了。您的窗口大小为 9 x 9,但如果您查看右侧路标的位移,我敢肯定它比 9 像素窗口大得多。您是否尝试过增加窗口大小? 15岁呢? 25 岁? 第二个问题是几乎所有的视差值都在1以下。这不应该是这样的 你改变了窗口大小吗? 是的 ....我使用 15 时图像更好 ....使用 25 时图像更差 ....所以我厌倦了 15 ......谢谢......我使用从该链接下载的工具箱调整了所有参数martinperis.com/stereobmtuner/stereoBMTuner-1.0.tgz 没问题。是的,当你用滑动窗口做视差时,你必须找到正确的窗口。太小意味着您不会捕捉到任何差异......而太大意味着您可能会将错误信息引入比较窗口。尽管使用滑动窗口很快,但它们并不能提供最好的结果。已经有一些关于自适应确定窗口大小的工作。检查 Kanade 和 Okutomi 的工作:cs.cmu.edu/~ph/869/papers/kanade-okutomi.pdf - 无论如何,我要跑题了。很高兴你让它工作! 【参考方案1】:

您拥有的视差图“看起来”适合块匹配。

块匹配是获取视差图的最基本方法。它是一种本地方法,通过蛮力搜索(来自 opencv 的模过滤)计算视差估计。因此,它的输出在准确性上是有限的,并且通常是嘈杂的。

正如其他人所提到的,您可以调整窗口大小以稍微改善结果,但这不会显着改善差异。

查看KITTI benchmark 上的立体评估,并在必要时选择更准确的算法。 OpenCV 有一个 SGM 的实现,可以产生更平滑的视差。所需的视差图质量取决于您的应用程序。在某些情况下,块匹配就足够了。对于其他人来说,可能不是。

请记住,视差的定义是:左图像中一个像素的 x 坐标与右图像中相应像素的 x 坐标之间的差异。也就是视差的单位是“像素”。

更大的差异,意味着更接近的物体。当您缩放图像以进行显示时,较大的差异会显得更亮。例如,道路上的标志离摄像头较近,看起来比道路上远处的像素更亮。

您的视差值不应介于 0 和 1 之间。您正在缩放图像以显示为 uint8,这可以显示,但不适合将视差用于实际测量。

在 OpenCV 中,默认行为是将视差图生成为通过将子像素移位乘以 16 获得的有符号短。要获得真正的视差值,请将 opencv 的输出除以 16 并转换为浮点数。

你可以这样做:

cv::Mat<float> true_dmap = disp * (1.0 / 16.0f);

disp.convertTo(true_dmap, CV_32F, 1.0/16.0, 0.0);

或者,您可以致电reprojectImageTo3D 来获取给定估计的视差图和立体校准的点云。

注意,如果您尝试通过 imshow 显示 true_map,您将看不到有意义的内容。

祝你好运,

【讨论】:

嘿,Bender,这是一个令人印象深刻的答案,我一直在 OpenCV 中使用 GPU 版本的 stereoBM,它奇怪地返回与 CPU 不同的结果,而且大多数调整参数设置器似乎什么也没做,GPU代码版本在 8UC1 中返回,与在 16SC1 中返回的 CPU 对应版本不同。我的深度计算似乎一团糟,就像我在 50 厘米的距离上得到了 20000 厘米。我应该怎么做才能获得正确的距离。

以上是关于立体视差图生成的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 OpenCV 3.0 StereoSGBM 和 PCL 生成一对立体图像的有效点云表示

立体匹配中的视差图和视差图有啥区别?

实时立体匹配网络StereoNet

使用立体相机从视差图进行深度重建

OpenCV中的立体图像创建深度图

立体视觉—计算视差图