Path: blob/master/Depth-Perception-Using-Stereo-Camera/python/disparity2depth_calib.py
3142 views
import numpy as np1import cv22import matplotlib3import matplotlib.pyplot as plt456# Check for left and right camera IDs7# These values can change depending on the system8CamL_id = 2 # Camera ID for left camera9CamR_id = 0 # Camera ID for right camera1011CamL= cv2.VideoCapture(CamL_id)12CamR= cv2.VideoCapture(CamR_id)1314# Reading the mapping values for stereo image rectification15cv_file = cv2.FileStorage("../data/stereo_rectify_maps.xml", cv2.FILE_STORAGE_READ)16Left_Stereo_Map_x = cv_file.getNode("Left_Stereo_Map_x").mat()17Left_Stereo_Map_y = cv_file.getNode("Left_Stereo_Map_y").mat()18Right_Stereo_Map_x = cv_file.getNode("Right_Stereo_Map_x").mat()19Right_Stereo_Map_y = cv_file.getNode("Right_Stereo_Map_y").mat()20cv_file.release()2122# These parameters can vary according to the setup23# Keeping the target object at max_dist we store disparity values24# after every sample_delta distance.25max_dist = 230 # max distance to keep the target object (in cm)26min_dist = 50 # Minimum distance the stereo setup can measure (in cm)27sample_delta = 40 # Distance between two sampling points (in cm)2829Z = max_dist30Value_pairs = []3132disp_map = np.zeros((600,600,3))333435# Reading the stored the StereoBM parameters36cv_file = cv2.FileStorage("../data/depth_estmation_params_py.xml", cv2.FILE_STORAGE_READ)37numDisparities = int(cv_file.getNode("numDisparities").real())38blockSize = int(cv_file.getNode("blockSize").real())39preFilterType = int(cv_file.getNode("preFilterType").real())40preFilterSize = int(cv_file.getNode("preFilterSize").real())41preFilterCap = int(cv_file.getNode("preFilterCap").real())42textureThreshold = int(cv_file.getNode("textureThreshold").real())43uniquenessRatio = int(cv_file.getNode("uniquenessRatio").real())44speckleRange = int(cv_file.getNode("speckleRange").real())45speckleWindowSize = int(cv_file.getNode("speckleWindowSize").real())46disp12MaxDiff = int(cv_file.getNode("disp12MaxDiff").real())47minDisparity = int(cv_file.getNode("minDisparity").real())48M = cv_file.getNode("M").real()49cv_file.release()5051# Defining callback functions for mouse events52def mouse_click(event,x,y,flags,param):53global Z54if event == cv2.EVENT_LBUTTONDBLCLK:55if disparity[y,x] > 0:56Value_pairs.append([Z,disparity[y,x]])57print("Distance: %r cm | Disparity: %r"%(Z,disparity[y,x]))58Z-=sample_delta59606162cv2.namedWindow('disp',cv2.WINDOW_NORMAL)63cv2.resizeWindow('disp',600,600)64cv2.namedWindow('left image',cv2.WINDOW_NORMAL)65cv2.resizeWindow('left image',600,600)66cv2.setMouseCallback('disp',mouse_click)6768# Creating an object of StereoBM algorithm69stereo = cv2.StereoBM_create()7071while True:7273# Capturing and storing left and right camera images74retR, imgR= CamR.read()75retL, imgL= CamL.read()7677# Proceed only if the frames have been captured78if retL and retR:79imgR_gray = cv2.cvtColor(imgR,cv2.COLOR_BGR2GRAY)80imgL_gray = cv2.cvtColor(imgL,cv2.COLOR_BGR2GRAY)8182# Applying stereo image rectification on the left image83Left_nice= cv2.remap(imgL_gray,84Left_Stereo_Map_x,85Left_Stereo_Map_y,86cv2.INTER_LANCZOS4,87cv2.BORDER_CONSTANT,880)8990# Applying stereo image rectification on the right image91Right_nice= cv2.remap(imgR_gray,92Right_Stereo_Map_x,93Right_Stereo_Map_y,94cv2.INTER_LANCZOS4,95cv2.BORDER_CONSTANT,960)9798# Setting the updated parameters before computing disparity map99stereo.setNumDisparities(numDisparities)100stereo.setBlockSize(blockSize)101stereo.setPreFilterType(preFilterType)102stereo.setPreFilterSize(preFilterSize)103stereo.setPreFilterCap(preFilterCap)104stereo.setTextureThreshold(textureThreshold)105stereo.setUniquenessRatio(uniquenessRatio)106stereo.setSpeckleRange(speckleRange)107stereo.setSpeckleWindowSize(speckleWindowSize)108stereo.setDisp12MaxDiff(disp12MaxDiff)109stereo.setMinDisparity(minDisparity)110111# Calculating disparity using the StereoBM algorithm112disparity = stereo.compute(Left_nice,Right_nice)113# NOTE: compute returns a 16bit signed single channel image,114# CV_16S containing a disparity map scaled by 16. Hence it115# is essential to convert it to CV_16S and scale it down 16 times.116117# Converting to float32118disparity = disparity.astype(np.float32)119120# Scaling down the disparity values and normalizing them121disparity = (disparity/16.0 - minDisparity)/numDisparities122123# Displaying the disparity map124cv2.imshow("disp",disparity)125cv2.imshow("left image",imgL)126127if cv2.waitKey(1) == 27:128break129130if Z < min_dist:131break132133else:134CamL= cv2.VideoCapture(CamL_id)135CamR= cv2.VideoCapture(CamR_id)136137# solving for M in the following equation138# || depth = M * (1/disparity) ||139# for N data points coeff is Nx2 matrix with values140# 1/disparity, 1141# and depth is Nx1 matrix with depth values142143value_pairs = np.array(Value_pairs)144z = value_pairs[:,0]145disp = value_pairs[:,1]146disp_inv = 1/disp147148# Plotting the relation depth and corresponding disparity149fig, (ax1,ax2) = plt.subplots(1,2,figsize=(12,6))150ax1.plot(disp, z, 'o-')151ax1.set(xlabel='Normalized disparity value', ylabel='Depth from camera (cm)',152title='Relation between depth \n and corresponding disparity')153ax1.grid()154ax2.plot(disp_inv, z, 'o-')155ax2.set(xlabel='Inverse disparity value (1/disp) ', ylabel='Depth from camera (cm)',156title='Relation between depth \n and corresponding inverse disparity')157ax2.grid()158plt.show()159160161# Solving for M using least square fitting with QR decomposition method162coeff = np.vstack([disp_inv, np.ones(len(disp_inv))]).T163ret, sol = cv2.solve(coeff,z,flags=cv2.DECOMP_QR)164M = sol[0,0]165C = sol[1,0]166print("Value of M = ",M)167168169# Storing the updated value of M along with the stereo parameters170cv_file = cv2.FileStorage("../data/depth_estmation_params_py.xml", cv2.FILE_STORAGE_WRITE)171cv_file.write("numDisparities",numDisparities)172cv_file.write("blockSize",blockSize)173cv_file.write("preFilterType",preFilterType)174cv_file.write("preFilterSize",preFilterSize)175cv_file.write("preFilterCap",preFilterCap)176cv_file.write("textureThreshold",textureThreshold)177cv_file.write("uniquenessRatio",uniquenessRatio)178cv_file.write("speckleRange",speckleRange)179cv_file.write("speckleWindowSize",speckleWindowSize)180cv_file.write("disp12MaxDiff",disp12MaxDiff)181cv_file.write("minDisparity",minDisparity)182cv_file.write("M",M)183cv_file.release()184185