使用 StereoBM 时视差图中出现黑柱

问题描述 投票:0回答:2

我正在尝试在 OpenCV 中使用 StereoBM 从一对图像中提取视差图。忽略下面视差图的不良质量,您可以看到它的左侧有许多黑色列,对应于参数 ndisparities。我认为 ndisparities 只告诉 StereoBM 它可以在多“远”的距离上搜索对应项。什么可能导致这种行为?它似乎限制了生成的深度图的宽度,但我不明白为什么。

Disparity map

您可以在下面看到立体声对here和我的代码。预先感谢您的指点!

Mat Limg = imread("left.jpg", CV_LOAD_IMAGE_GRAYSCALE);
Mat Rimg = imread("right.jpg", CV_LOAD_IMAGE_GRAYSCALE);

Mat disp(Limg.size(), CV_16SC1), disp8U;
int ndisparities = 512;
StereoBM SBM(StereoBM::BASIC_PRESET, ndisparities , 11);
SBM(Limg, Rimg, disp, CV_16S);

double minVal, maxVal;
minMaxLoc( disp, &minVal, &maxVal );
disp.convertTo( disp8U, CV_8UC1, 255/(maxVal - minVal));
imshow("disparity", disp8U)
c++ opencv image-processing computer-vision
2个回答
10
投票

视差图量化左右图像中对应点对之间的纵向(极线)偏移。

原则上,

 disparity := x_l - x_r

其中

x_l
x_r
是空间中给定点的两个相机在焦平面上的投影。 (请记住,较大的差异代表距离相机“更近”的像素。[A])

参数
ndisparities

量化了您可以拥有的

预期
最大视差(假设您可以忽略最小视差)。 既然您假设

ndisparities

是您最大的差异,那么它就是正确的


x_l - x_r < ndisparities,

x_r > x_l - ndisparities

因此,在左图像的前 
ndisparities

列中寻找与右图像的任何像素的对应关系是没有意义的:根本不可能。


从某种意义上说,右摄像头的视锥正好从左摄像头视锥右侧的

ndisparities

列开始。



修复:

如果您希望视差图左侧的

黑柱

更少,则需要能够假设较低的ndisparities值。


由于

ndisparities

取决于距最近物体(来自 [A])的摄像机的距离,因此要么将摄像机远离物体,要么将摄像机彼此靠近。


在你非常具体的情况下,你有一个巨大的差异(立体BM有很多工作)!前景中的“x”符号显示出与图像比例相当的差异!我相信你需要把相机放远一点。


0
投票

这是您描述的默认行为,其中

cv2.StereoSGBM_create

stereo.compute
返回的估计视差图缺少最左边的
numDisparities
列。我在这里使用一个合成场景,我有一个完美的地面实况视差图用于比较。第三张图片显示了地面真实视差和估计视差之间的绝对差异或
误差

现在这就是我认为它
应该

的样子。当然,左下角的部分无法成功匹配,因为它们在两个图像中都不可见,但最左边的许多列中较高的部分绝对可以匹配,而且应该匹配。

为了实现这一目标,我必须采用将图像向左扩展(在 C++ 代码中称为)

ndisparities

列的技巧,然后再次从生成的视差图中将它们裁剪掉。

rectified_left_gray  = np.hstack([np.zeros((height, num_disp), dtype=np.uint8), rectified_left_gray])
rectified_right_gray = np.hstack([np.zeros((height, num_disp), dtype=np.uint8), rectified_right_gray])

disparity = stereo.compute(rectified_left_gray, rectified_right_gray) / 16.0
disparity = disparity[:, num_disp:]

    

© www.soinside.com 2019 - 2024. All rights reserved.