深度估计
1、与深度相关通道的概念
- 深度图:灰色图,该图像的每个像素值都是摄像头到位表面之间距离的估计值,比如:CAP_OPENNI_DEPTH_MAP通道的图像给出了基于浮点数的距离,该距离以毫米为单位
- 点云图,彩色图像,该图像的每种颜色都对应一个(x,y,z)维度空间,比如:CAP_OPENNI_POINT_CLOUD_MAP通道会得到BGR图像,这个单位的值是米
- 视差图:灰度图像,该图像的每个像素值代表了物体表面的立体视差,立体视差是指:加入将从图通视角观察同一场景得到的两张图像叠放在一起,这很可能让人觉得是两张图像,在整个图像中,针对两张图像中的两个孪生的物体之间任意一堆相互对应的两个像素点,可以度量这些像素之间的距离,这个度量就是立体视差,近距离的物体会产生较大的立体视差,而远距离的会小一些,因此近距离的物体在视差图中会更明亮一些
- 有效深度掩模。踏实表明一个给定的像素的深度信息是否有效(一个非零值表示有效,零值代表无效),比如,如果深度摄像头依赖于红外照明器(红外闪光灯),在灯光被遮挡区域的深度信息就是无效的
2、一种计算视差图的算法(StereoSGBM)
参数 | 描述 |
minDisparity | 这个参数表示可能的最小视差值,它通常为0,但有时校正算法会移动图像,所以参数值也要相应的调整 |
numDisparity | 最大的视差值和最小的视差值之差,总是大于0的,要可以被16整除 |
windowSize | 是一个匹配快的大小,他必须是大于等于1的奇数,通常在3-11之间 |
P1 | 控制视差图平滑度的第一个参数 |
P2 | 控制视差图平滑度的第二个参数,这个值越大,视差图月平滑。P1是临近像素间视差值变化为1的惩罚值,P2是临近像素视差值变化大于1的惩罚值,算法要求P2>P1, |
disp12MaxDiff | 表示在左右视差检查中最大允许的偏差 |
preFilterCap | 便是预过滤图像像素的截断值,算法首先计算每个像素在x方向的衍生值,然后使用[-preFilterCap,preFilterCap]区间来截取他的值,最后的结果传给像素代价函数 |
uniquenessRatio | 有代价函数计算得到的最好(最小)结果值比第二好的值小多少(用百分比表示)才是正确的,通常早5-15之间 |
speckleWindowSize | 表示平滑时差趋于的最大窗口尺寸,以考虑噪声斑点或无效性,将他设为0就不会尽心斑点过滤,否则在50-200之间的某个值 |
speckleRange | 值每个已连接部分的最大视差变化,如果进行斑点过滤,则该参数取正值,函数会自动乘以16,一般情况下1-2就足够了。 |
import cv2
import numpy as np
def update(val = 0):
stereo.setBlockSize(cv2.getTrackbarPos('window_size','disparity'))
stereo.setBlockSize(cv2.getTrackbarPos('speckleRange', 'disparity'))
stereo.setBlockSize(cv2.getTrackbarPos('speckleWindowSize', 'disparity'))
stereo.setBlockSize(cv2.getTrackbarPos('uniquenessRatio', 'disparity'))
stereo.setBlockSize(cv2.getTrackbarPos('disp12MaxDiff', 'disparity'))
print('computing disparity......')
disp = stereo.compute(imgL,imgR).astype(np.float32)/16.0
cv2.imshow("left",imgL)
cv2.imshow("disparity",(disp - min_disp) / num_disp )
if __name__ == "__main__":
window_size = 5
min_disp = 16
num_disp = 192-min_disp
blockSize = window_size
uniquenessRatio = 1
speckleRange = 3
speckleWindowSize = 3
disp12MaxDiff = 200
P1 = 600
P2 = 2400
imgL = cv2.imread("../images/aloeL.jpg")
imgR = cv2.imread("../images/aloeR.jpg")
cv2.namedWindow("disparity",500)
cv2.createTrackbar('speckleRange','disparity',speckleRange,50,update)
cv2.createTrackbar('window_size', 'disparity', window_size, 21, update)
cv2.createTrackbar('speckleWindowSize', 'disparity', speckleWindowSize, 200, update)
cv2.createTrackbar('uniquenessRatio', 'disparity', uniquenessRatio, 50, update)
cv2.createTrackbar('disp12MaxDiff', 'disparity', disp12MaxDiff, 250, update)
stereo = cv2.StereoSGBM_create(
minDisparity = min_disp,
numDisparities = num_disp,
blockSize = window_size,
uniquenessRatio = uniquenessRatio,
speckleWindowSize = speckleWindowSize,
speckleRange = speckleRange,
disp12MaxDiff = disp12MaxDiff,
P1 = P1,
P2 = P2
)
update()
cv2.waitKey()
cv2.destroyAllWindows()