Attempting to calibrate a stereo rig, I am failing at the very beginning … findChessboardCorners()
The images I am using for calibration are underwater photographs of a chessboard and I made them available at [1]
The code I use to create left/right images from the single frame is:
import os
import cv2
import pathlib
import glob
import numpy as np
imagepath = '/root/notebooks/PHD/STEREO/CALIBRATION/Images2015/'
imgs = list(sorted(glob.glob(f'{imagepath}/*.png')))
pathlib.Path(pathlib.Path(imagepath) / 'left').mkdir(parents=True, exist_ok=True)
pathlib.Path(pathlib.Path(imagepath) / 'right').mkdir(parents=True, exist_ok=True)
for i in imgs:
image = cv2.imread(i)
h, w, d = image.shape
# left = cv2.cvtColor(image[:, 0:int(w/2), :], cv2.COLOR_BGR2RGB)
# right = cv2.cvtColor(image[:, int(w/2):, :], cv2.COLOR_BGR2RGB)
left = image[:, 0:int(w/2), :]
right = image[:, int(w/2):, :]
cv2.imwrite(str(pathlib.Path( pathlib.Path(pathlib.Path(imagepath) / 'left') / str(pathlib.Path(i).stem+'_left.png'))), left)
cv2.imwrite(str(pathlib.Path( pathlib.Path(pathlib.Path(imagepath) / 'right') / str(pathlib.Path(i).stem+'_right.png'))), right)
I then attempt the first step of the calibration which should consist of finding the chessboard points with:
PATTERN_SIZE = (6, 5)
left_imgs = list(sorted(glob.glob('/root/notebooks/PHD/STEREO/CALIBRATION/Images2015/left/*.png')))
right_imgs = list(sorted(glob.glob('/root/notebooks/PHD/STEREO/CALIBRATION/Images2015/right/*.png')))
assert len(left_imgs) == len(right_imgs)
PATTERN_SIZE = (6, 5)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 1e-3)
left_pts, right_pts = [], []
img_size = None
for left_img_path, right_img_path in zip(left_imgs[1:], right_imgs[1:]):
left_img = cv2.imread(left_img_path, cv2.IMREAD_GRAYSCALE)
right_img = cv2.imread(right_img_path, cv2.IMREAD_GRAYSCALE)
if img_size is None:
img_size = (left_img.shape[1], left_img.shape[0])
res_left, corners_left = cv2.findChessboardCorners(left_img, PATTERN_SIZE)
res_right, corners_right = cv2.findChessboardCorners(right_img, PATTERN_SIZE)
corners_left = cv2.cornerSubPix(left_img, corners_left, (10, 10), (-1,-1),
criteria)
corners_right = cv2.cornerSubPix(right_img, corners_right, (10, 10), (-1,-1),
criteria)
left_pts.append(corners_left)
right_pts.append(corners_right)
But that steps fails with the following errro:
error: OpenCV(4.5.1-pre) /src/opencv/modules/imgproc/src/cornersubpix.cpp:58: error: (-215:Assertion failed) count >= 0 in function 'cornerSubPix'
I checked on the web for similar errors and seems the reason is a failure in findChessboardCorners
And that seems to be the cause of it:
for i in range(len(left_imgs)):
image_left = left_imgs[i]
image_right = right_imgs[i]
res_left, corners_left = cv2.findChessboardCorners(cv2.imread(image_left,
cv2.IMREAD_GRAYSCALE),
(6, 5))
res_right, corners_right = cv2.findChessboardCorners(cv2.imread(image_right,
cv2.IMREAD_GRAYSCALE),
(6, 5))
print(i, res_left, res_right)
Is returning the following:
0 False True
1 False True
2 False False
3 False True
4 True False
5 False False
6 False False
7 False False
8 False False
9 False False
I double-checked the pattern size (number of inner corners in the chessboard), I also tried to invert the width/height size, as I wasn’t sure about the order … but that didn’t help)
Images used for calibration:
[1] stereo_rig.zip (63.6 MB)
The zip file contains the ‘stereo frames’ as a single image for left+right frame, and two directories (left/right) whit the single images for convenience.
Have you any hints on what I am doing wrong?
Is it possible that my images need some sort of “pre-processing” due to the shade/colors in them? If that could be the case, what do you suggest?
Thanks for any help!