I am trying to select a point in the left image and get the corresponding point in the right image.
To start with, I did the stereo calibration and rectified the images, and proceeded to find the disparity map. I used the StereoSGBM in OpenCV. Since disparity refers to the distance between two corresponding points in the left and right image of a stereo pair then:
x_right = x_left - Disparity
The problem is that when I implement this it doesn't work. Is the problem my interpretation of the disparity map or its output?
import numpy as np
import cv2 as cv
def mouseCallback(event, x, y, flags, param):
global mouseX, mouseY
if event == cv.EVENT_LBUTTONDOWN:
mouseX = x
mouseY = y
# Images
img_left = cv2.imread(img_path1)
img_right = cv2.imread(img_path2)
# Grayscale
frame_left = cv.cvtColor(img_left,cv.COLOR_BGR2GRAY)
frame_right = cv.cvtColor(img_right,cv.COLOR_BGR2GRAY)
# Retification
...
# Calculate disparity
cv.namedWindow("Stereo Pair Distance")
while True:
# SGBM Parameters -----------------
window_size = 3
left_matcher = cv.StereoSGBM_create(
minDisparity=-16, numDisparities=16+16,
blockSize=window_size,
P1=8 * 2 * window_size**2,
P2=32 * 2 * window_size**2,
disp12MaxDiff=0,
uniquenessRatio=5,
speckleWindowSize=200,
speckleRange=2,
preFilterCap=63,
mode=cv.STEREO_SGBM_MODE_SGBM_3WAY
)
right_matcher = cv.ximgproc.createRightMatcher(left_matcher)
# FILTER Parameters
lmbda = 8000
sigma = 1.4
# WLS Filter
wls_filter = cv.ximgproc.createDisparityWLSFilter(matcher_left=left_matcher)
wls_filter.setLambda(lmbda)
wls_filter.setSigmaColor(sigma)
# Compute disparity
displ = left_matcher.compute(left_gray_image, right_gray_image)
dispr = right_matcher.compute(right_gray_image, left_gray_image)
displ = np.int16(displ)
dispr = np.int16(dispr)
filteredImg = wls_filter.filter(displ, left_gray_image, None, dispr)
filteredImg = cv.normalize(src=filteredImg, dst=filteredImg, beta=0, alpha=255, norm_type=cv.NORM_MINMAX);
filteredImg = np.uint8(filteredImg)
imOut = cv.line(imOut, (640, mouseY),(640*2, mouseY), (0, 0, 255), 2)
# Left Point
imOut = cv.circle(imOut, (mouseX,mouseY), 5,(0,255,0), 3)
# Right Point
Right_X = round(mouseX-filteredImg[mouseX,mouseY])
imOut = cv.circle(imOut, (Right_X+640,mouseY), 5,(0,255,), 3)
cv.imshow("Stereo Pair Distance",imOut)
key = cv.waitKey(1)
if key == ord('q'):
# Quit when q is pressed
break
cv.destroyAllWindows()
Stereo Pair Rectified
Stereo Correspondence
Disparity Map