版权声明:欢迎转载,请注明来源 https://blog.csdn.net/linghugoolge/article/details/85104570
一、效果
使用两个单目相机实现深度测量
二、思路
1、使用opencv自带函数:stereo.compute(imgL,imgR)
1)效果
2)代码
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()
3)官方文档
https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_calib3d/py_depthmap/py_depthmap.html
2、自己匹配算法
1)效果
2)过程
- 摄像机标定(包括内参和外参)
- 双目图像的校正(包括畸变校正和立体校正)
- SGBM算法匹配算法获取视差图,以及深度图
- 利用视差图,或者深度图进行虚拟视点的合成
3)参考
真实场景的双目立体匹配(Stereo Matching)获取深度图详解
4)两份很好的参考
a)【opencv学习】使用opencv与两个摄像头实现双目标定与测距:https://blog.csdn.net/hysteric314/article/details/51357318
b)opencv实现双目视觉测距:https://blog.csdn.net/xiao__run/article/details/78900652
这个文档特别详细:对于小白,特别不容易上手,在这里我提供一个傻瓜式教程吧,利用matlab来进行标注,图形界面,无须任何代码,然后利用C++实现测距与深度图,原理太多我就不提了,小白直接照做就OK
三、实现的代码
#原始jpg已经畸变矫正
import numpy as np
import cv2
IMAGE_WIDTH = 800
IMAGE_HEIGHT = 600
capL = cv2.VideoCapture(2)
capR = cv2.VideoCapture(0)
imgL = np.zeros((IMAGE_WIDTH, IMAGE_HEIGHT, 3), np.uint8)
imgR = np.zeros((IMAGE_WIDTH, IMAGE_HEIGHT, 3), np.uint8)
stereo = None
opencv_measure_version = int(cv2.__version__.split('.')[0])
windowSize = 5
minDisp = 10
numDisp = 250 - minDisp
# for OpenCV3
stereo = cv2.StereoSGBM_create(
minDisparity=minDisp,
numDisparities=numDisp,
blockSize=16,
P1=8*3*windowSize**2,
P2=32*3*windowSize**2,
disp12MaxDiff=1,
uniquenessRatio=10,
speckleWindowSize=100,
speckleRange=32
)
capL.set(cv2.CAP_PROP_FRAME_WIDTH, IMAGE_WIDTH)
capL.set(cv2.CAP_PROP_FRAME_HEIGHT, IMAGE_HEIGHT)
capR.set(cv2.CAP_PROP_FRAME_WIDTH, IMAGE_WIDTH)
capR.set(cv2.CAP_PROP_FRAME_HEIGHT, IMAGE_HEIGHT)
imgL = cv2.imread('./assets/left.jpg')
imgR = cv2.imread('./assets/right.jpg')
# create gray images
imgGrayL = cv2.cvtColor(imgL, cv2.COLOR_BGR2GRAY)
imgGrayR = cv2.cvtColor(imgR, cv2.COLOR_BGR2GRAY)
# calculate histogram
imtGrayL = cv2.equalizeHist(imgGrayL)
imtGrayR = cv2.equalizeHist(imgGrayR)
# through gausiann filter
imgGrayL = cv2.GaussianBlur(imgGrayL, (5, 5), 0)
imgGrayR = cv2.GaussianBlur(imgGrayR, (5, 5), 0)
cv2.imshow("image left", imgGrayL)
cv2.imshow("image right", imgGrayR)
# calculate disparity
disparity = stereo.compute(imgGrayL, imgGrayR).astype(np.float32)/16
disparity = (disparity - minDisp) / numDisp
cv2.imshow("disparity", disparity)
cv2.waitKey(0)