公司因为成本原因,让我做一个传统的双目避障。没办法磕一下吧。
双目避障流程
**问题:**速度特别慢,我发现,comput这一步(左右相机计算视差)会特别慢,还在想加速的办法。
下面上代码:
这个代码,在深度图上点击鼠标可以输出坐标和距离(网上抄的(doge))。
import cv2
import numpy as np
import time
import random
import math
left_camera_matrix = np.array([[1.041391360906410e+03, -0.497373958828725, 6.529633882697765e+02],
[0, 1.041945256148336e+03, 5.011346138132716e+02],
[0, 0, 1]])
left_distortion = np.array([[-0.038865939454924, 0.141434746390239, 0.002010222102729, 0.002010222102729, 0]])
right_camera_matrix = np.array([[1.040740304791424e+03, -0.745746463223811, 6.214512440664031e+02],
[0, 1.041706604301214e+03, 4.936376604155090e+02],
[0, 0, 1]])
right_distortion = np.array([[-0.042478429626748, 0.149801715580196, 4.679743572389913e-04, 3.157700181865255e-04, 0]])
R = np.array([[0.999998129286225, -8.830788262094638e-04, -0.001720928771787],
[8.814580091946381e-04, 0.999999167496347, -9.423578887644861e-04],
[0.001721759515406, 9.408391994334367e-04, 0.999998075181034]])
T = np.array([-1.202972148785817e+02, 0.244005292586265, 0.294722278253404])
size = (1280, 720)
R1, R2, P1, P2, Q, validPixROI1, validPixROI2 = cv2.stereoRectify(left_camera_matrix, left_distortion,
right_camera_matrix, right_distortion, size, R,
T)
# 校正查找映射表,将原始图像和校正后的图像上的点一一对应起来
left_map1, left_map2 = cv2.initUndistortRectifyMap(left_camera_matrix, left_distortion, R1, P1, size, cv2.CV_16SC2)
right_map1, right_map2 = cv2.initUndistortRectifyMap(right_camera_matrix, right_distortion, R2, P2, size, cv2.CV_16SC2)
print(Q)
capture = cv2.VideoCapture("./Capture00004.avi")
ret,img = capture.read()
def onmouse_pick_points(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
threeD = param
print('\n像素坐标 x = %d, y = %d' % (x, y))
print("世界坐标xyz 是:", threeD[y][x][0] / 1000.0, threeD[y][x][1] / 1000.0, threeD[y][x][2] / 1000.0, "m")
distance = math.sqrt(threeD[y][x][0] ** 2 + threeD[y][x][1] ** 2 + threeD[y][x][2] ** 2)
distance = distance / 1000.0 # mm -> m
print("距离是:", distance, "m")
fps = 0.0
flag = 0
while True:
t1 = time.time()
ret,img = capture.read()
imgl = img[0:720,0:1280]
imgr = img[0:720,1280:2560]
imgl = cv2.cvtColor(imgl,cv2.COLOR_BGR2GRAY)
imgr = cv2.cvtColor(imgr,cv2.COLOR_BGR2GRAY)
imgl_rectified = cv2.remap(imgl,left_map1,left_map2,cv2.INTER_LINEAR)
imgr_rectified = cv2.remap(imgr,right_map1,right_map2,cv2.INTER_LINEAR)
imagel = cv2.cvtColor(imgl_rectified,cv2.COLOR_GRAY2BGR)
imager = cv2.cvtColor(imgr_rectified,cv2.COLOR_GRAY2BGR)
blockSize = 8
img_channels = 3
stereo = cv2.StereoSGBM_create(minDisparity=1,numDisparities=112,
blockSize=blockSize,
P1=8 * img_channels * blockSize * blockSize,
P2=32 * img_channels * blockSize * blockSize,
disp12MaxDiff=-1,preFilterCap=1,uniquenessRatio=10,
speckleWindowSize=100,speckleRange=100,
mode=cv2.STEREO_SGBM_MODE_HH)
disparity = stereo.compute(imgl_rectified,imgr_rectified)
disp = cv2.normalize(disparity,disparity,alpha=0,beta=255,norm_type=cv2.NORM_MINMAX,dtype=cv2.CV_8U)
threeD = cv2.reprojectImageTo3D(disparity,Q,handleMissingValues=True)
threeD = threeD * 16
cv2.setMouseCallback("before_threeD", onmouse_pick_points, threeD)
for i in range(disp.shape[0]):
for j in range(disp.shape[1]):
Y = threeD[i][j][1] / 1000.0
if Y < -1.0 or Y > 0.55:
disp[i][j] = 0
k = np.ones((10,10),dtype=np.uint8)
disp = cv2.morphologyEx(disp,op=cv2.MORPH_CLOSE,kernel=k)
disp = cv2.morphologyEx(disp,op=cv2.MORPH_OPEN,kernel=k)
# disparity = cv2.GaussianBlur(disparity,(15,15),0,0)
disp = cv2.medianBlur(disp,15,-1)
before_threeD = disp.copy()
ret,disp = cv2.threshold(disp,20,255,type=cv2.THRESH_BINARY)
contours,hierarchy = cv2.findContours(disp,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for i in range(len(contours)):
area = cv2.contourArea(contours[i])
if 15000 < area < 230400:
x,y,w,h = cv2.boundingRect(contours[i])
distance = math.sqrt(threeD[y+int(h/2)][x+int(w/2)][0] ** 2 + threeD[y+int(h/2)][x+int(w/2)][1] ** 2 + threeD[y+int(h/2)][x+int(w/2)][2] ** 2)
distance = distance / 1000.0
cv2.rectangle(imagel,(x,y),(x + w,y + h),(255,255,0),2)
cv2.putText(imagel,str(distance),(x,y+50),fontFace=cv2.FONT_HERSHEY_COMPLEX_SMALL,fontScale=2,color=(225,0,0),thickness=2)
cv2.circle(imagel,(x+int(w/2),y+int(h/2)),3,(255,0,0),-1)
fps = (fps + (1. / (time.time() - t1))) / 2
cv2.namedWindow("dis",cv2.WINDOW_NORMAL)
cv2.namedWindow("imagel",cv2.WINDOW_NORMAL)
cv2.namedWindow("before_threeD",cv2.WINDOW_NORMAL)
cv2.imshow("dis",disp)
cv2.imshow("imagel",imagel)
cv2.imshow("before_threeD",before_threeD)
if cv2.waitKey(10) & 0xff == ord('q'):
break
print(fps)
cv2.destroyAllWindows()