Created
April 23, 2023 14:53
-
-
Save fxprime/dc9ea4bcba2ee6aa7a69dce2da6cca6c to your computer and use it in GitHub Desktop.
calibrate_fisheye_camera using KB8 for VI
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cv2 | |
#assert cv2.__version__[0] == '3', 'The fisheye module requires opencv version >= 3.0.0' | |
import numpy as np | |
import os | |
import glob | |
CHECKERBOARD = (7,10) | |
subpix_criteria = (cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER, 30, 0.1) | |
calibration_flags = cv2.fisheye.CALIB_RECOMPUTE_EXTRINSIC+cv2.fisheye.CALIB_CHECK_COND+cv2.fisheye.CALIB_FIX_SKEW | |
# calibration_flags = cv2.fisheye.CALIB_RECOMPUTE_EXTRINSIC+cv2.fisheye.CALIB_FIX_SKEW | |
objp = np.zeros((1, CHECKERBOARD[0]*CHECKERBOARD[1], 3), np.float32) | |
objp[0,:,:2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2) | |
_img_shape = None | |
objpoints = [] # 3d point in real world space | |
imgpoints = [] # 2d points in image plane. | |
images = glob.glob('*.png') | |
images.sort() | |
for fname in images: | |
img = cv2.imread(fname) | |
if _img_shape == None: | |
_img_shape = img.shape[:2] | |
else: | |
assert _img_shape == img.shape[:2], "All images must share the same size." | |
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) | |
# Find the chess board corners | |
ret, corners = cv2.findChessboardCorners(gray, CHECKERBOARD, cv2.CALIB_CB_ADAPTIVE_THRESH+cv2.CALIB_CB_FAST_CHECK+cv2.CALIB_CB_NORMALIZE_IMAGE) | |
# If found, add object points, image points (after refining them) | |
if ret == True: | |
objpoints.append(objp) | |
cv2.cornerSubPix(gray,corners,(3,3),(-1,-1),subpix_criteria) | |
imgpoints.append(corners) | |
N_OK = len(objpoints) | |
K = np.zeros((3, 3)) | |
D = np.zeros((4, 1)) | |
print("finished processing images") | |
rvecs = [np.zeros((1, 1, 3), dtype=np.float64) for i in range(N_OK)] | |
tvecs = [np.zeros((1, 1, 3), dtype=np.float64) for i in range(N_OK)] | |
rms, _, _, _, _ = \ | |
cv2.fisheye.calibrate( | |
objpoints, | |
imgpoints, | |
gray.shape[::-1], | |
K, | |
D, | |
rvecs, | |
tvecs, | |
calibration_flags, | |
(cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER, 30, 1e-6) | |
) | |
print("Found " + str(N_OK) + " valid images for calibration") | |
print("DIM=" + str(_img_shape[::-1])) | |
print("K=np.array(" + str(K.tolist()) + ")") | |
print("D=np.array(" + str(D.tolist()) + ")") | |
K2=np.array([[2.4734003025545465e+02, 0.0, 3.3626570042116441e+02], [0.0, 2.4738056560443138e+02, 2.0050730427749909e+02], [0.0, 0.0, 1.0]]) | |
D2=np.array([[5.5420483333080472e-01], [3.4851549830571299e-01], [-8.5237465089897979e-01], [3.9202413479288289e-01]]) | |
def draw_lines(img, corners, pattern_size): | |
for i in range(pattern_size[1]): | |
cv2.line(img, tuple(corners[i*pattern_size[0]].ravel()), tuple(corners[(i+1)*pattern_size[0]-1].ravel()), (0, 255, 0), 2) | |
for i in range(pattern_size[0]): | |
cv2.line(img, tuple(corners[i].ravel()), tuple(corners[pattern_size[0]*(pattern_size[1]-1)+i].ravel()), (0, 255, 0), 2) | |
map1, map2 = cv2.fisheye.initUndistortRectifyMap(K, D, np.eye(3), K, _img_shape[::-1], cv2.CV_16SC2) | |
map12, map22 = cv2.fisheye.initUndistortRectifyMap(K2, D2, np.eye(3), K2, _img_shape[::-1], cv2.CV_16SC2) | |
for fname in images: | |
img = cv2.imread(fname) | |
undistorted_img = cv2.remap(img, map1, map2, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT) | |
undistorted_img2 = cv2.remap(img, map12, map22, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT) | |
gray = cv2.cvtColor(undistorted_img,cv2.COLOR_BGR2GRAY) | |
gray2 = cv2.cvtColor(undistorted_img2,cv2.COLOR_BGR2GRAY) | |
ret, corners = cv2.findChessboardCorners(gray, CHECKERBOARD, cv2.CALIB_CB_ADAPTIVE_THRESH+cv2.CALIB_CB_FAST_CHECK+cv2.CALIB_CB_NORMALIZE_IMAGE) | |
ret2, corners2 = cv2.findChessboardCorners(gray2, CHECKERBOARD, cv2.CALIB_CB_ADAPTIVE_THRESH+cv2.CALIB_CB_FAST_CHECK+cv2.CALIB_CB_NORMALIZE_IMAGE) | |
# Draw lines on the undistorted images | |
if corners is not None and corners2 is not None: | |
draw_lines(undistorted_img, corners, CHECKERBOARD) | |
draw_lines(undistorted_img2, corners2, CHECKERBOARD) | |
if ret and ret2: # If the checkerboard is found | |
cv2.cornerSubPix(gray, corners, (3, 3), (-1, -1), subpix_criteria) | |
cv2.drawChessboardCorners(undistorted_img, CHECKERBOARD, corners, ret) | |
cv2.cornerSubPix(gray2, corners2, (3, 3), (-1, -1), subpix_criteria) | |
cv2.drawChessboardCorners(undistorted_img2, CHECKERBOARD, corners2, ret2) | |
# Display the rectified image with the checkerboard pattern | |
cv2.imshow('Rectified Image with Checkerboard', np.hstack((undistorted_img, undistorted_img2))) | |
cv2.waitKey(0) | |
cv2.destroyAllWindows() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment