Path: blob/master/Depth-Perception-Using-Stereo-Camera/python/obstacle_avoidance.py
3142 views
import numpy as np1import cv2234# Check for left and right camera IDs5# These values can change depending on the system6CamL_id = 2 # Camera ID for left camera7CamR_id = 0 # Camera ID for right camera8910CamL= cv2.VideoCapture(CamL_id)11CamR= cv2.VideoCapture(CamR_id)1213# Reading the mapping values for stereo image rectification14cv_file = cv2.FileStorage("../data/stereo_rectify_maps.xml", cv2.FILE_STORAGE_READ)15Left_Stereo_Map_x = cv_file.getNode("Left_Stereo_Map_x").mat()16Left_Stereo_Map_y = cv_file.getNode("Left_Stereo_Map_y").mat()17Right_Stereo_Map_x = cv_file.getNode("Right_Stereo_Map_x").mat()18Right_Stereo_Map_y = cv_file.getNode("Right_Stereo_Map_y").mat()19cv_file.release()2021disparity = None22depth_map = None2324# These parameters can vary according to the setup25max_depth = 400 # maximum distance the setup can measure (in cm)26min_depth = 50 # minimum distance the setup can measure (in cm)27depth_thresh = 100.0 # Threshold for SAFE distance (in cm)2829# Reading the stored the StereoBM parameters30cv_file = cv2.FileStorage("../data/depth_estmation_params_py.xml", cv2.FILE_STORAGE_READ)31numDisparities = int(cv_file.getNode("numDisparities").real())32blockSize = int(cv_file.getNode("blockSize").real())33preFilterType = int(cv_file.getNode("preFilterType").real())34preFilterSize = int(cv_file.getNode("preFilterSize").real())35preFilterCap = int(cv_file.getNode("preFilterCap").real())36textureThreshold = int(cv_file.getNode("textureThreshold").real())37uniquenessRatio = int(cv_file.getNode("uniquenessRatio").real())38speckleRange = int(cv_file.getNode("speckleRange").real())39speckleWindowSize = int(cv_file.getNode("speckleWindowSize").real())40disp12MaxDiff = int(cv_file.getNode("disp12MaxDiff").real())41minDisparity = int(cv_file.getNode("minDisparity").real())42M = cv_file.getNode("M").real()43cv_file.release()4445# mouse callback function46def mouse_click(event,x,y,flags,param):47global Z48if event == cv2.EVENT_LBUTTONDBLCLK:49print("Distance = %.2f cm"%depth_map[y,x])505152cv2.namedWindow('disp',cv2.WINDOW_NORMAL)53cv2.resizeWindow('disp',600,600)54cv2.setMouseCallback('disp',mouse_click)5556output_canvas = None5758# Creating an object of StereoBM algorithm59stereo = cv2.StereoBM_create()6061def obstacle_avoid():6263# Mask to segment regions with depth less than threshold64mask = cv2.inRange(depth_map,10,depth_thresh)6566# Check if a significantly large obstacle is present and filter out smaller noisy regions67if np.sum(mask)/255.0 > 0.01*mask.shape[0]*mask.shape[1]:6869# Contour detection70contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)71cnts = sorted(contours, key=cv2.contourArea, reverse=True)7273# Check if detected contour is significantly large (to avoid multiple tiny regions)74if cv2.contourArea(cnts[0]) > 0.01*mask.shape[0]*mask.shape[1]:7576x,y,w,h = cv2.boundingRect(cnts[0])7778# finding average depth of region represented by the largest contour79mask2 = np.zeros_like(mask)80cv2.drawContours(mask2, cnts, 0, (255), -1)8182# Calculating the average depth of the object closer than the safe distance83depth_mean, _ = cv2.meanStdDev(depth_map, mask=mask2)8485# Display warning text86cv2.putText(output_canvas, "WARNING !", (x+5,y-40), 1, 2, (0,0,255), 2, 2)87cv2.putText(output_canvas, "Object at", (x+5,y), 1, 2, (100,10,25), 2, 2)88cv2.putText(output_canvas, "%.2f cm"%depth_mean, (x+5,y+40), 1, 2, (100,10,25), 2, 2)8990else:91cv2.putText(output_canvas, "SAFE!", (100,100),1,3,(0,255,0),2,3)9293cv2.imshow('output_canvas',output_canvas)949596while True:97retR, imgR= CamR.read()98retL, imgL= CamL.read()99100if retL and retR:101102output_canvas = imgL.copy()103104imgR_gray = cv2.cvtColor(imgR,cv2.COLOR_BGR2GRAY)105imgL_gray = cv2.cvtColor(imgL,cv2.COLOR_BGR2GRAY)106107# Applying stereo image rectification on the left image108Left_nice= cv2.remap(imgL_gray,109Left_Stereo_Map_x,110Left_Stereo_Map_y,111cv2.INTER_LANCZOS4,112cv2.BORDER_CONSTANT,1130)114115# Applying stereo image rectification on the right image116Right_nice= cv2.remap(imgR_gray,117Right_Stereo_Map_x,118Right_Stereo_Map_y,119cv2.INTER_LANCZOS4,120cv2.BORDER_CONSTANT,1210)122123# Setting the updated parameters before computing disparity map124stereo.setNumDisparities(numDisparities)125stereo.setBlockSize(blockSize)126stereo.setPreFilterType(preFilterType)127stereo.setPreFilterSize(preFilterSize)128stereo.setPreFilterCap(preFilterCap)129stereo.setTextureThreshold(textureThreshold)130stereo.setUniquenessRatio(uniquenessRatio)131stereo.setSpeckleRange(speckleRange)132stereo.setSpeckleWindowSize(speckleWindowSize)133stereo.setDisp12MaxDiff(disp12MaxDiff)134stereo.setMinDisparity(minDisparity)135136# Calculating disparity using the StereoBM algorithm137disparity = stereo.compute(Left_nice,Right_nice)138# NOTE: compute returns a 16bit signed single channel image,139# CV_16S containing a disparity map scaled by 16. Hence it140# is essential to convert it to CV_16S and scale it down 16 times.141142# Converting to float32143disparity = disparity.astype(np.float32)144145# Normalizing the disparity map146disparity = (disparity/16.0 - minDisparity)/numDisparities147148depth_map = M/(disparity) # for depth in (cm)149150mask_temp = cv2.inRange(depth_map,min_depth,max_depth)151depth_map = cv2.bitwise_and(depth_map,depth_map,mask=mask_temp)152153obstacle_avoid()154155cv2.resizeWindow("disp",700,700)156cv2.imshow("disp",disparity)157158if cv2.waitKey(1) == 27:159break160161else:162CamL= cv2.VideoCapture(CamL_id)163CamR= cv2.VideoCapture(CamR_id)164165