Load in the image Pair
import cv2
import numpy as np
# The filnames
dirPathLeft = "tokt1_L_181.jpg"
dirPathRight = "tokt1_R_181.jpg"
# load the image
imgsLeft = cv2.imread(dirPathLeft)
imgsRight = cv2.imread(dirPathRight)
cv2.imshow("imageLeft" , imgsLeft)
cv2.imshow("imageRight" , imgsRight)
cv2.waitKey(0)
-1
Run the DisparityImage class process
1 - Load Camera parameters
2 - undistort image pair
3 - make image pair gray scale
4 - block matching
5 - remmove error margin (from challenging claibration parameters)
Load the camera parameters
The camera parameters come from a camera calibration done in matlab. We need theese camera parameters in order to undistort/rectify the image pair before we can use "Block Matching"
#def loadCameraParameters(self):
# left
fxL = 2222.72426
fyL = 2190.48031
k1L = 0.27724
k2L = 0.28163
k3L = -0.06867
k4L = 0.00358
k5L = 0.00000
cxL = 681.42537
cyL = -22.08306
skewL = 0
p1L = 0
p2L = 0
p3L = 0
p4L = 0
# right
fxR = 2226.10095
fyR = 2195.17250
k1R = 0.29407
k2R = 0.29892
k3R = 0 - 0.08315
k4R = -0.01218
k5R = 0.00000
cxR = 637.64260
cyR = -33.60849
skewR = 0
p1R = 0
p2R = 0
p3R = 0
p4R = 0
# x0 and y0 is zero
x0 = 0
y0 = 0
intrinsic_matrixL = np.matrix([[fxL, skewL, x0], [0, fyL, y0], [0, 0, 1]])
intrinsic_matrixR = np.matrix([[fxR, skewR, x0], [0, fyR, y0], [0, 0, 1]])
distCoeffL = np.matrix([k1L, k2L, p1L, p2L, k3L])
distCoeffR = np.matrix([k1R, k2R, p1R, p2R, k3R])
# Parameters
base_offset = 30.5 # b:= base offset, (the distance *between* your cameras)
# f:= focal length of camera,
fx = 2222
focal_length = (fx * 35) / 1360 # 1360 is the width of the image, 35 is width of old camera film in mm (10^-3 m)
Block matching
There is several important parameters: - SADWindowSize - preFilterType - preFilterSize - preFilterCap - minDisparity - numberOfDisparities - textureThreshold - uniquenessRatio - speckleRange - speckleWindowSize
It is important to note disparity = cv2.cv.CreateMat(c, r, cv2.cv.CV_32F) cv2.cv.FindStereoCorrespondenceBM(gray_left, gray_right, disparity, sbm)
disparity_visual = cv2.cv.CreateMat(c, r, cv2.cv.CV_8U) cv2.cv.Normalize(disparity, disparity_visual, 0, 255, cv2.cv.CV_MINMAX)
Normalization
def getDisparity(imgLeft, imgRight, method="BM"):
# 1 make the images grayscale
gray_left = cv2.cvtColor(imgLeft, cv2.cv.CV_BGR2GRAY)
gray_right = cv2.cvtColor(imgRight, cv2.cv.CV_BGR2GRAY)
# 2 preform "BM" --> "Block Matching"
c, r = gray_left.shape
if method == "BM":
sbm = cv2.cv.CreateStereoBMState()
disparity = cv2.cv.CreateMat(c, r, cv2.cv.CV_32F)
sbm.SADWindowSize = 9
sbm.preFilterType = 1
sbm.preFilterSize = 5
sbm.preFilterCap = 61
sbm.minDisparity = -39
sbm.numberOfDisparities = 112
sbm.textureThreshold = 507
sbm.uniquenessRatio = 0
sbm.speckleRange = 8
sbm.speckleWindowSize = 0
gray_left = cv2.cv.fromarray(gray_left)
gray_right = cv2.cv.fromarray(gray_right)
cv2.cv.FindStereoCorrespondenceBM(gray_left, gray_right, disparity, sbm)
disparity_visual = cv2.cv.CreateMat(c, r, cv2.cv.CV_8U)
cv2.cv.Normalize(disparity, disparity_visual, 0, 255, cv2.cv.CV_MINMAX)
disparity_visual = np.array(disparity_visual)
elif method == "SGBM":
sbm = cv2.StereoSGBM()
sbm.SADWindowSize = 9
sbm.numberOfDisparities = 96
sbm.preFilterCap = 63
sbm.minDisparity = -21
sbm.uniquenessRatio = 7
sbm.speckleWindowSize = 0
sbm.speckleRange = 8
sbm.disp12MaxDiff = 1
sbm.fullDP = False
disparity = sbm.compute(gray_left, gray_right)
disparity_visual = cv2.normalize(disparity, alpha=0, beta=255, norm_type=cv2.cv.CV_MINMAX,
dtype=cv2.cv.CV_8U)
return disparity_visual
Doing it all in a pipeline:
Undistort images
def disparityCalc():
# 1 undistort the image pair
undistorted_image_L = cv2.undistort(imgsLeft, intrinsic_matrixL, distCoeffL, None)
undistorted_image_R = cv2.undistort(imgsRight, intrinsic_matrixR, distCoeffR, None)
# 2 --> calculate disparity images
disparity_visual = getDisparity(imgLeft=undistorted_image_L, imgRight=undistorted_image_R, method="BM")
disparity_visual = disparity_visual.astype(np.uint8)
return disparity_visual
Display the disparity image
disparity_visual = disparityCalc()
cv2.imshow("disparity", disparity_visual)
cv2.waitKey(0)
-1
Remove the error margin
disparity_visual = disparityCalc()
#disparity_visual = disparity_visual.astype(np.float32)
# this part is to remove the error from the calibration
width, height = disparity_visual.shape[:2][::-1]
margin = 200
y1 = 0
y2 = height
x1 = margin
x2 = width - margin
# "Croping the image"
disparity_visual = disparity_visual[y1:y2, x1:x2]
cv2.imshow("disparity", disparity_visual)
cv2.waitKey(0)
-1