基础
在OpenCV中,深度地图通常是通过计算立体视觉(stereo vision)或结构光(structured light)技术得到的。立体视觉是通过将两个或多个摄像机(或图像)的视角结合起来,计算物体的深度信息。而结构光技术则是通过投射特定的光纹或模式到场景中,然后通过观察光纹的形变来计算物体的深度。通过学习和了解了对极约束的基本概念和相关术语后。我们可以确定,如果同一场景有两幅图像的话我们在直觉上就可以获得图像的深度信息。下面的这幅图和其中的数学公式可以证明我们的直觉是对的。
x 和x' 分别是图像中的点到3D 空间中的点和到摄像机中心的距离。B 是这两个摄像机之间的距离,f 是摄像机的焦距。上面的等式告诉我们点的深度与x 和x' 的差成反比。所以根据这个等式我们就可以得到图像中所有点的深度图。这样就可以找到两幅图像中的匹配点了。前面我们已经知道了对极约束可以使这个操作更快更准。一旦找到了匹配就可以计算出disparity 了。让我们看看在OpenCV 中怎样做吧。
代码
在OpenCV中,可以使用以下函数来生成深度地图:
1.cv2.StereoBM_create()
和cv2.StereoSGBM_create()
:这些函数用于执行立体匹配算法,从而计算出左右摄像机间的视差图。然后,可以使用视差图计算深度地图。
2.cv2.reprojectImageTo3D()
:这个函数可以将视差图转换为三维点云,其中每个点的坐标表示其在世界坐标系中的位置。
3.cv2.createStructuredLight()
、cv2.unwrapPhaseMap()
和cv2.reconstructPhaseMap()
:这些函数用于处理结构光图像,从而计算出物体的深度地图。
下面的代码显示了构建深度图的简单过程:
import numpy as np
import cv2
from matplotlib import pyplot as plt
imgL = cv2.imread('tsukuba_l.png',0)
imgR = cv2.imread('tsukuba_r.png',0)
stereo = cv2.createStereoBM(numDisparities=16, blockSize=15)
disparity = stereo.compute(imgL,imgR)
plt.imshow(disparity,'gray')
plt.show()
下图左侧为原始图像,右侧为深度图像。如图所示,结果中有很大的噪音。通过调整numDisparities 和blockSize 的值,我们会得到更好的结果。