So for starters, I'm using a raspberry Pi B with 2 Logitech C170 webcams this is a little project I'm trying to do for weeks and can't seem to get a good result. Here is what I came up to while reading plenty of tutorials and sample codes(it is a combination of calibrate.py and stereo_match.py from python samples which works perfectly fine):
from __future__ import print_function
import numpy as np
import cv2
from common import splitfn
import os
if __name__ == '__main__':
import sys
import getopt
from glob import glob
img_mask = '../../project/left*.png'
img_mask2 = '../../project/right*.png'
img_names = glob(img_mask)
img_names2 = glob(img_mask2)
square_size = 2.3
pattern_size = (9, 6)
pattern_points = np.zeros((np.prod(pattern_size), 3), np.float32)
pattern_points[:, :2] = np.indices(pattern_size).T.reshape(-1, 2)
pattern_points *= square_size
obj_points = []
obj_points2 = []
img_points = []
img_points2 = []
h, w = 0, 0
img_names_undistort = []
#calibrate1
for fn in img_names:
print('processing %s... ' % fn, end='')
img = cv2.imread(fn, 0)
if img is None:
print("Failed to load", fn)
continue
h, w = img.shape[:2]
found, corners = cv2.findChessboardCorners(img, pattern_size)
if found:
term = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_COUNT, 30, 0.1)
cv2.cornerSubPix(img, corners, (5, 5), (-1, -1), term)
cv2.drawChessboardCorners(img, pattern_size, corners, found)
path, name, ext = splitfn(fn)
outfile = './output/' + name + '_chess.png'
cv2.imwrite(outfile, img)
if found:
img_names_undistort.append(outfile)
if not found:
print('chessboard not found')
continue
img_points.append(corners.reshape(-1, 2))
obj_points.append(pattern_points)
print('ok')
#calibrate2
for fn in img_names2:
print('processing %s... ' % fn, end='')
img = cv2.imread(fn, 0)
if img is None:
print("Failed to load", fn)
continue
found, corners = cv2.findChessboardCorners(img, pattern_size)
if found:
term = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_COUNT, 30, 0.1)
cv2.cornerSubPix(img, corners, (5, 5), (-1, -1), term)
cv2.drawChessboardCorners(img, pattern_size, corners, found)
path, name, ext = splitfn(fn)
outfile = './output/' + name + '_chess.png'
cv2.imwrite(outfile, img)
if found:
img_names_undistort.append(outfile)
if not found:
print('chessboard not found')
continue
img_points2.append(corners.reshape(-1, 2))
obj_points2.append(pattern_points)
print('ok')
rms, camera_matrix, dist_coefs, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, (w, h), None, None)
print('calib1done\n')
rms2, camera_matrix2, dist_coefs2, rvecs2, tvecs2 = cv2.calibrateCamera(obj_points2, img_points2, (w, h), None, None)
print('calib2done\n')
print('\nFirst camera:\n')
print("RMS:\n", rms)
print("camera matrix:\n", camera_matrix)
print("distortion coefficients: ", dist_coefs.ravel())
print('\nSecond camera:\n')
print("RMS:\n", rms2)
print("camera matrix:\n", camera_matrix2)
print("distortion coefficients: ", dist_coefs2.ravel())
#depth map
print('loading images...')
imgL = cv2.imread('left0.png')
imgR = cv2.imread('right0.png')
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(camera_matrix, dist_coefs, (w, h), 1, (w, h))
newcameramtx2, roi2 = cv2.getOptimalNewCameraMatrix(camera_matrix2, dist_coefs2, (w, h), 1, (w, h))
newimgL = cv2.undistort(imgL, camera_matrix, dist_coefs, None, newcameramtx)
newimgR = cv2.undistort(imgR, camera_matrix2, dist_coefs2, None, newcameramtx2)
newimgL = cv2.cvtColor(newimgL, cv2.COLOR_BGR2GRAY)
newimgR = cv2.cvtColor(newimgR, cv2.COLOR_BGR2GRAY)
cv2.imwrite("undistortedleft0.png", newimgL)
cv2.imwrite("undistortedright0.png", newimgR)
window_size = 3
min_disp = 16
num_disp = 112-min_disp
stereo = cv2.StereoSGBM_create(minDisparity = min_disp,
numDisparities = num_disp,
blockSize = 16,
P1 = 8*1*window_size**2,
P2 = 32*1*window_size**2,
disp12MaxDiff = 1,
uniquenessRatio = 10,
speckleWindowSize = 100,
speckleRange = 32
)
print('computing disparity...')
disp = stereo.compute(newimgR, newimgL).astype(np.float32) / 16.0
cv2.imshow('disparity', (disp-min_disp)/num_disp)
cv2.waitKey()
cv2.destroyAllWindows()
Codes compiles just fine but what I'm worried about are the results:

My script comes with seperate calibration for left camera and right camera, next it takes 2 images that i have took and undistorts them, final step is creating disparity map (im using SGBM algorithm). From what i've read RMS values are just fine with 0,15 on each camera so (all data can be seen on screenshot) I think the calibration went good and I have nothing to worry about, also I checked if every image has a good chessboard points and it was all right, but still results aren't satisfying.
Here are the undistorted images:


What I have tried to do is swap left and right image but disparity was pretty much the same and also I was trying to change SGBM algorithm values but I'm not sure if that is the problem because I followed opencv documentation. Please help I don't know what can I do.
↧