Created
June 23, 2018 10:24
-
-
Save mesutpiskin/0412c44bae399adf1f48007f22bdd22d to your computer and use it in GitHub Desktop.
OpenCV fisheye calibration and undistortion
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
# -*- coding: utf-8 -*- | |
""" | |
Created on Sun Jun 17 19:59:33 2018 | |
@author: mesut | |
""" | |
import yaml | |
import cv2 | |
assert cv2.__version__[0] == '3', 'The fisheye module requires opencv version >= 3.0.0' | |
import numpy as np | |
import glob | |
CHECKERBOARD = (6,9) | |
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 | |
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('images/*.png') | |
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)) | |
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()) + ")") | |
DIM=_img_shape[::-1] | |
balance=1 | |
dim2=None | |
dim3=None | |
img = cv2.imread("db/2.png") | |
dim1 = img.shape[:2][::-1] #dim1 is the dimension of input image to un-distort | |
assert dim1[0]/dim1[1] == DIM[0]/DIM[1], "Image to undistort needs to have same aspect ratio as the ones used in calibration" | |
if not dim2: | |
dim2 = dim1 | |
if not dim3: | |
dim3 = dim1 | |
scaled_K = K * dim1[0] / DIM[0] # The values of K is to scale with image dimension. | |
scaled_K[2][2] = 1.0 # Except that K[2][2] is always 1.0 | |
# This is how scaled_K, dim2 and balance are used to determine the final K used to un-distort image. OpenCV document failed to make this clear! | |
new_K = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(scaled_K, D, dim2, np.eye(3), balance=balance) | |
map1, map2 = cv2.fisheye.initUndistortRectifyMap(scaled_K, D, np.eye(3), new_K, dim3, cv2.CV_16SC2) | |
undistorted_img = cv2.remap(img, map1, map2, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT) | |
data = {'dim1': dim1, | |
'dim2':dim2, | |
'dim3': dim3, | |
'K': np.asarray(K).tolist(), | |
'D':np.asarray(D).tolist(), | |
'new_K':np.asarray(new_K).tolist(), | |
'scaled_K':np.asarray(scaled_K).tolist(), | |
'balance':balance} | |
import json | |
with open("fisheye_calibration_data.json", "w") as f: | |
json.dump(data, f) | |
cv2.imshow("undistorted", undistorted_img) | |
img2 = cv2.imread("2.png") | |
cv2.imshow("none 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