OpenCV Python Depth Map from Stereo Images 立体图像的深度图
【目标】
- 通过立体图像创建一个深度图
【理论】
上一节中,我们学习了一些基本概念,如对极约束和其他一些相关术语。我们还可以看到,如果我们有同一个场景的两张图像,我们可以以一种直观的方式获得深度信息。
上图包含等价三角形。写出它们的等价方程,得到如下结果:
d i s p a r i t y = x − x ′ = B f Z disparity=x-x'=\frac{Bf}{Z} disparity=x−x′=ZBf
x x x和 x ′ x' x′为图像平面中与场景点3D对应的点与其相机中心之间的距离。 B B B是两个相机之间的距离(我们知道), f f f是相机的焦距(已经知道)。所以简而言之,上面的方程说的是,场景中一个点的深度与对应图像点与其相机中心的距离之差成反比。因此,有了这些信息,我们可以推导出图像中所有像素的深度。
所以它会在两张图像之间找到对应的匹配。我们已经看到了极线约束如何使这个操作更快更准确。一旦找到匹配,它就会发现差异。
【代码】
import numpy as np
import cv2
imgL = cv2.imread("assets/tsukuba_l.png", 0)
imgR = cv2.imread("assets/tsukuba_r.png", 0)
stereo = cv2.StereoBM_create(numDisparities=16, blockSize=15)
disparity = stereo.compute(imgL, imgR)
disparity = np.uint8(disparity)
cv2.imshow("L", imgL)
cv2.imshow("R", imgR)
cv2.imshow("depth", disparity)
cv2.waitKey(0)
cv2.destroyAllWindows()
【接口】
- StereoSGBM_create
cv.StereoSGBM_create( [, minDisparity[, numDisparities[, blockSize[, P1[, P2[, disp12MaxDiff[, preFilterCap[, uniquenessRatio[, speckleWindowSize[, speckleRange[, mode]]]]]]]]]]] ) -> retval
创建 StereoSGBM 对象
- minDisparity: 最小可能的视差值,正常情况下为零,但有时校正算法会对图像进行移位,因此需要对该参数进行相应的调整。
- numDisparities: 最大视差减去最小视差。该值总是大于零。在当前实现中,该参数必须能被16整除。
- blockSize: 匹配的块大小。它必须是奇数>=1。通常情况下,它应该在
3~11
范围内。- P1: 控制视差平滑度的第一个参数
- P2: 控制视差平滑度的第二个参数,值越大,越平滑。P1是对相邻像素之间的视差变化±1的惩罚。P2是对相邻像素之间的视差变化超过1的惩罚。算法要求P2 > P1。参见
stereo_match.cpp
示例,其中显示了一些相当不错的P1和P2值(例如分别为8*number_of_image_channels*blockSize*blockSize
和32*number_of_image_channels*blockSize*blockSize
)。- disp12MaxDiff: 在左右图差异检查中允许的最大差异(整数像素单位)。将其设置为非正值以禁用检查。
- preFilterCap: 预过滤图像像素的截断值。该算法首先计算每个像素的x导数,并按
[-preFilterCap, preFilterCap]
区间剪辑其值。结果值被传递给Birchfield-Tomasi
像素代价函数。- uniquenessRatio: 计算出的最佳(最小)代价函数值应该“赢得”第二个最佳值以认为找到的匹配正确的百分比差额。通常,
5-15
之间的值就足够了。- speckleWindowSize: 平滑视差区域的最大大小,以考虑其噪声斑点和无效。将其设置为0以禁用散斑滤波。否则,将其设置在
50-200
范围内。- speckleRange: 每个连接组件内的最大视差变化。如果进行散斑滤波,将参数设置为正值,它将隐式乘以
16
。通常,1
或2
就足够了。- mode: 设置为 StereoSGBM::MODE_HH 可运行全尺寸两步动态规划算法,将会消耗
O(W*H*Disparities)
字节,对于640x480 图像来说很大,对于 HD-尺寸图像来说就是巨大的了。缺省值为false。
其他成员见
OpenCV: cv::StereoSGBM Class Reference
【参考】
- OpenCV: Depth Map from Stereo Images
- Ros stereo img processing wiki page
- OpenCV: cv::StereoSGBM Class Reference