Python做事情就是简洁, C++干一天的事情, Python一个小时就搞完了。 相机的双目标定, 用python做就大约100行代码:
mport numpy as np
import cv2
import glob
w=11
h=8
class StereoCalibration(object):
def __init__(self, filepath):
# termination criteria
self.criteria = (cv2.TERM_CRITERIA_EPS +
cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
self.criteria_cal = (cv2.TERM_CRITERIA_EPS +
cv2.TERM_CRITERIA_MAX_ITER, 100, 1e-5)
# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
self.objp = np.zeros((w*h, 3), np.float32)
self.objp[:, :2] = np.mgrid[0:w, 0:h].T.reshape(-1, 2)
# Arrays to store object points and image points from all the images.
self.objpoints = [] # 3d point in real world space
self.imgpoints_l = [] # 2d points in image plane.
self.imgpoints_r = [] # 2d points in image plane.
self.cal_path = filepath
self.read_images(self.cal_path)
def read_images(self, cal_path):
images_right = glob.glob(cal_path + 'RIGHT/*.BMP')
images_left = glob.glob(cal_path + 'LEFT/*.BMP')
images_left.sort()
images_right.sort()
for i, fname in enumerate(images_right):
img_l = cv2.imread(images_left[i])
img_r = cv2.imread(images_right[i])
gray_l = cv2.cvtColor(img_l, cv2.COLOR_BGR2GRAY)
gray_r = cv2.cvtColor(img_r, cv2.COLOR_BGR2GRAY)
# Find the chess board corners
ret_l, corners_l = cv2.findChessboardCorners(gray_l, (w, h), None)
ret_r, corners_r = cv2.findChessboardCorners(gray_r, (w, h), None)
# If found, add object points, image points (after refining them)
self.objpoints.append(self.objp)
if ret_l is True:
rt = cv2.cornerSubPix(gray_l, corners_l, (11, 11),
(-1, -1), self.criteria)
self.imgpoints_l.append(corners_l)
# Draw and display the corners
#ret_l = cv2.drawChessboardCorners(img_l, (w, h), corners_l, ret_l)
#cv2.imshow(images_left[i], img_l)
#cv2.waitKey(500)
if ret_r is True:
rt = cv2.cornerSubPix(gray_r, corners_r, (11, 11),
(-1, -1), self.criteria)
self.imgpoints_r.append(corners_r)
# Draw and display the corners
#ret_r = cv2.drawChessboardCorners(img_r, (w, h), corners_r, ret_r)
#cv2.imshow(images_right[i], img_r)
#cv2.waitKey(500)
img_shape = gray_l.shape[::-1]
rt, self.M1, self.d1, self.r1, self.t1 = cv2.calibrateCamera(
self.objpoints, self.imgpoints_l, img_shape, None, None)
rt, self.M2, self.d2, self.r2, self.t2 = cv2.calibrateCamera(
self.objpoints, self.imgpoints_r, img_shape, None, None)
self.camera_model = self.stereo_calibrate(img_shape)
def stereo_calibrate(self, dims):
flags = 0
flags |= cv2.CALIB_FIX_INTRINSIC
# flags |= cv2.CALIB_FIX_PRINCIPAL_POINT
flags |= cv2.CALIB_USE_INTRINSIC_GUESS
flags |= cv2.CALIB_FIX_FOCAL_LENGTH
# flags |= cv2.CALIB_FIX_ASPECT_RATIO
flags |= cv2.CALIB_ZERO_TANGENT_DIST
# flags |= cv2.CALIB_RATIONAL_MODEL
# flags |= cv2.CALIB_SAME_FOCAL_LENGTH
# flags |= cv2.CALIB_FIX_K3
# flags |= cv2.CALIB_FIX_K4
# flags |= cv2.CALIB_FIX_K5
stereocalib_criteria = (cv2.TERM_CRITERIA_MAX_ITER +
cv2.TERM_CRITERIA_EPS, 100, 1e-5)
ret, M1, d1, M2, d2, R, T, E, F = cv2.stereoCalibrate(
self.objpoints, self.imgpoints_l,
self.imgpoints_r, self.M1, self.d1, self.M2,
self.d2, dims,
criteria=stereocalib_criteria, flags=flags)
print('Intrinsic_mtx_1', M1)
print('dist_1', d1)
print('Intrinsic_mtx_2', M2)
print('dist_2', d2)
print('R', R)
print('T', T)
print('E', E)
print('F', F)
camera_model = dict([('M1', M1), ('M2', M2), ('dist1', d1),
('dist2', d2), ('rvecs1', self.r1),
('rvecs2', self.r2), ('R', R), ('T', T),
('E', E), ('F', F)])
cv2.destroyAllWindows()
return camera_model
cal = StereoCalibration('E:/test/stereoImages/')
cal.camera_model
内外参数矩阵输出如下
dist_2 [[-2.55286082e-02 8.56411589e-02 -5.63590998e-05 -1.09355660e-04
-1.31001765e+00]]
R [[ 8.50996117e-01 1.91702683e-03 5.25168482e-01]
[ 1.00591467e-04 9.99992724e-01 -3.81328259e-03]
[-5.25171971e-01 3.29791614e-03 8.50989732e-01]]
T [[-4.28699204e+01]
[-4.08354702e-02]
[ 1.31494607e+01]]
E [[ 2.01229208e-02 -1.31494997e+01 1.53920437e-02]
[-1.13239406e+01 1.66589271e-01 4.33875444e+01]
[ 3.04384784e-02 -4.28695302e+01 1.84920623e-01]]
F [[-1.96974087e-10 1.28728825e-07 -1.93506447e-04]
[ 1.10873358e-07 -1.63126736e-09 -4.26440083e-03]
[-1.78586942e-04 3.75962382e-03 1.00000000e+00]]