使用视差图测量距离

时间:2014-05-10 12:48:24

标签: python opencv

我正在使用OpenCP和Python进行3D重建和距离测量。我为左相机生成视差图,然后我使用这个公式得到距离:

D=(f*b/disp)

f是焦距,b是两个相机之间的距离,disp是视差地图的矩阵。

我的问题是:

我得到的数字,它们应该是图片中每个点的距离吗?

使用此方法可以获得的最大距离是多少(例如,在我的项目中,我获得的最大数量是110)?

img_L = cv2.pyrDown( cv2.imread(Li) )
img_R = cv2.pyrDown( cv2.imread(Ri) )
'''h, w = img_L.shape[:2]
diff=(6,6,6)
mask=np.zeros((h+2,w+2),np.uint8)
window_size = 3
min_disp = 16
num_disp = 112-min_disp
stereo = cv2.StereoSGBM(minDisparity = min_disp,
    numDisparities = num_disp,
    SADWindowSize = window_size,
    uniquenessRatio = 10,
    speckleWindowSize = 100,
    speckleRange = 32,
    disp12MaxDiff = 1,
    P1 = 8*3*window_size**2,
    P2 = 32*3*window_size**2,
    fullDP = False
)
print "computing disparity..."
disp = stereo.compute(img_L, img_R).astype(np.float32) / 16.0

print "generating 3d point cloud..."
h, w = img_L.shape[:2]
f = 0.8*w                          # guess for focal length
points = cv2.reprojectImageTo3D(disp, Mat)
colors = cv2.cvtColor(img_L, cv2.COLOR_BGR2RGB)
mask = disp > disp.min()
cv2.imshow('left', img_L)
disparity=(disp-min_disp)/num_disp
cv2.imshow('disparity',disparity )
b=6.50
D=b*f/disp
cv2.waitKey()
cv.DestroyAllWindows()
return D

1 个答案:

答案 0 :(得分:2)

使用此公式获得的值D是您提供差异的每个点的深度

深度距离是两个稍微不同的东西。如果您使用相机的标准坐标系(即沿光轴的Z轴,图像X和Y轴方向的X和Y轴),则3D点{​​{1}}的距离为{{ 1}}来自光学中心,深度为M = (X, Y, Z)。公式中的sqrt(X²+Y²+Z²)是深度,而不是距离。

如果您想从深度值中检索3D点Z,您需要知道相机矩阵DM = (X, Y, Z),其中K是图像坐标重点。

编辑关于您的第二个问题,此方法可以获得的最大深度与最小差异(不是最大值,因为M = D * inv(K) * [u; v; 1]在分母上)相关联。并且由于视差估计是量化的(逐个像素地完成),因此无法估计深度到无穷大。