先来介绍两个基本概念:
深度摄像头(比如微软的Kinect)将传统摄像头和一个红外传感器相结合来帮助摄像头区别相似物体并计算它们与摄像头之间的距离。
深度摄像头虽好但却比较昂贵。我们还可以根据同一物体在不同视角下拍摄的两幅图像计算视差图来进行深度估计。但是要注意这两幅图像需是距物体相同距离拍摄的,否则计算将会失败。其中的原理涉及到几何学中的极几何(Epipolar Geomerty)。
可参考网上的这篇博文:http://www.elecfans.com/d/863829.html
下面的代码我们对左右两张图片使用OpenCV中的StereoSGBM算法来计算视差。
左图:
右图:
代码如下:
import numpy as npimport cv2
def update(): stereo.setBlockSize(cv2.getTrackbarPos('window_size','disparity')) stereo.setUniquenessRatio(cv2.getTrackbarPos('uniquenessRatio','disparity')) stereo.setSpeckleWindowSize(cv2.getTrackbarPos('speckleWindowSize','disparity')) stereo.setSpeckleRange(cv2.getTrackbarPos('speckleRange', 'disparity')) stereo.setDisp12MaxDiff(cv2.getTrackbarPos('disp12MaxDiff','disparity')) print("computing disparity...") disp= stereo.compute(imgL, imgR).astype(np.float32)/16.0 result = (disp /disp.max()*255).astype(np.uint8) print(imgL.shape) print(disp) print(result.shape) print(result) cv2.imshow('imgL',imgL ) cv2.imshow('disparity',result)
window_size =5min_disp = 16num_disp = 64 #与视差图左边黑色区域的大小 正相关blockSize =window_sizeuniquenessRatio = 16speckleRange =3speckleWindowSize = 50disp12MaxDiff = 200P1= 600P2 =2400imgL=cv2.imread("L0.jpg")imgR=cv2.imread("R0.jpg")#imgL= cv2.cvtColor(cv2.imread("L0.jpg"), cv2.COLOR_BGR2GRAY) #不必要,输入可以是彩图#imgR= cv2.cvtColor(cv2.imread("R0.jpg"), cv2.COLOR_BGR2GRAY)
cv2.namedWindow('disparity')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, speckleRange = speckleRange, speckleWindowSize = speckleWindowSize, disp12MaxDiff = disp12MaxDiff, P1= P1, P2 =P2)update()cv2.waitKey()
上述代码在OpenCV图形界面绘制了若干滑动条,用以动态调整函数参数。视差图的计算结果如下:
视差图中明亮的部分更靠近摄像头(是前景),阴暗的部分远离摄像头(是背景)。
所获取的视差图总是在左侧和右侧有明显的黑色区域,这些区域没有有效的视差数据。视差图有效像素区域与视差窗口(ndisp,一般取正值且能被16整除)和最小视差值(mindisp,一般取0或负值)相关,视差窗口越大,视差图左侧的黑色区域越大,最小视差值越小,视差图右侧的黑色区域越大。其原因是为了保证参考图像(一般是左视图)的像素点能在目标图像(右视图)中按照设定的视差匹配窗口匹配对应点,OpenCV 只从参考图像的第 (ndisp - 1 + mindisp) 列开始向右计算视差,第 0 列到第 (ndisp - 1 + mindisp) 列的区域视差统一设置为 (mindisp - 1) *16;视差计算到第 width + mindisp 列时停止,余下的右侧区域视差值也统一设置为 (mindisp - 1) *16。
简单介绍一下StereoSGBM()中的几个参数的意义:
本文分享自 Python可视化编程机器学习OpenCV 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!