立体视差图生成

Stereo Disparity map generation

我正在处理 KITTI 数据集,我正在拍摄 2 张​​图像并找到差异以获得 3D 点云。我面临的问题是我无法获得良好的差异 map.Most视差值小于 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);

您拥有的视差图 "looks" 适合块匹配。

Block Matching是获取视差图最基本的方法。它是一种本地方法,通过强力搜索(来自 opencv 的模滤波)计算视差估计。因此它的输出精度有限并且通常有噪声。

正如其他人提到的,您可以调整 window 大小来稍微改善结果,但这不会使差异明显改善。

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

请记住,视差的定义是:左图中某个像素的 x 坐标与右图中对应像素的 x 坐标之差。即视差的单位是"pixels".

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

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

在 OpenCV 中,默认行为是通过将子像素位移乘以 16 来生成视差图作为带符号的 short。要获得真正的视差值,请将 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,您将看不到任何有意义的内容。

祝你好运,