我正在使用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
使用此公式得到的D
值是您提供视差的每个点的深度。
深度和距离是两个稍有不同的东西。如果使用相机的标准坐标系(即Z轴沿光轴方向,X轴和Y轴沿图像X轴和Y轴方向),则三维点M = (X, Y, Z)
与光中心的距离为sqrt(X²+Y²+Z²)
,深度为Z
。式中D
为深度,而非距离。
如果要从深度值中检索3D点M = (X, Y, Z)
,则需要知道相机矩阵K
: M = D * inv(K) * [u; v; 1]
,其中(u, v)
为该点的图像坐标。
编辑:关于您的第二个问题,您可以使用此方法获得的最大深度与最小视差(而不是最大值,因为disp
在分母上)相关联。由于视差估计是量化的(逐像素完成),你无法估计深度到无穷大。