python实现双目相机的棋盘格标定代码
时间: 2023-07-23 15:08:19 浏览: 164
双目相机标定代码
下面是一个简单的双目相机棋盘格标定的 Python 代码示例:
```python
import numpy as np
import cv2
import glob
# 棋盘格尺寸
CHESSBOARD_SIZE = (9, 6)
# 棋盘格三维坐标
objpoints = []
for i in range(CHESSBOARD_SIZE[1]):
for j in range(CHESSBOARD_SIZE[0]):
objpoints.append([j, i, 0])
objpoints = np.array(objpoints, dtype=np.float32)
# 存储棋盘格角点坐标的数组
imgpoints_l = []
imgpoints_r = []
# 获取所有棋盘格图片的文件名
images_l = glob.glob('left/*.jpg')
images_r = glob.glob('right/*.jpg')
for fname_l, fname_r in zip(images_l, images_r):
# 读取左右相机的图片
img_l = cv2.imread(fname_l)
img_r = cv2.imread(fname_r)
# 转换为灰度图像
gray_l = cv2.cvtColor(img_l, cv2.COLOR_BGR2GRAY)
gray_r = cv2.cvtColor(img_r, cv2.COLOR_BGR2GRAY)
# 查找棋盘格角点
ret_l, corners_l = cv2.findChessboardCorners(gray_l, CHESSBOARD_SIZE, None)
ret_r, corners_r = cv2.findChessboardCorners(gray_r, CHESSBOARD_SIZE, None)
# 如果找到了棋盘格角点
if ret_l and ret_r:
# 绘制棋盘格角点
cv2.drawChessboardCorners(img_l, CHESSBOARD_SIZE, corners_l, ret_l)
cv2.drawChessboardCorners(img_r, CHESSBOARD_SIZE, corners_r, ret_r)
# 添加角点坐标到数组中
imgpoints_l.append(corners_l)
imgpoints_r.append(corners_r)
# 标定相机
ret_l, mtx_l, dist_l, rvecs_l, tvecs_l = cv2.calibrateCamera(objpoints, imgpoints_l, gray_l.shape[::-1], None, None)
ret_r, mtx_r, dist_r, rvecs_r, tvecs_r = cv2.calibrateCamera(objpoints, imgpoints_r, gray_r.shape[::-1], None, None)
# 双目标定
flags = 0
flags |= cv2.CALIB_FIX_INTRINSIC
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 1e-5)
ret, M1, d1, M2, d2, R, T, E, F = cv2.stereoCalibrate(objpoints, imgpoints_l, imgpoints_r, mtx_l, dist_l, mtx_r, dist_r, gray_l.shape[::-1], criteria=criteria, flags=flags)
# 计算校正参数
R1, R2, P1, P2, Q, _, _ = cv2.stereoRectify(M1, d1, M2, d2, gray_l.shape[::-1], R, T, alpha=0)
# 计算映射矩阵
map_l_x, map_l_y = cv2.initUndistortRectifyMap(M1, d1, R1, P1, gray_l.shape[::-1], cv2.CV_32FC1)
map_r_x, map_r_y = cv2.initUndistortRectifyMap(M2, d2, R2, P2, gray_l.shape[::-1], cv2.CV_32FC1)
# 保存校正参数
np.savez('calibration.npz', M1=M1, d1=d1, M2=M2, d2=d2, R=R, T=T, E=E, F=F, R1=R1, R2=R2, P1=P1, P2=P2, Q=Q)
# 显示校正结果
while True:
# 读取左右相机的图片
img_l = cv2.imread(images_l[0])
img_r = cv2.imread(images_r[0])
# 校正左右相机的图像
img_l_rectified = cv2.remap(img_l, map_l_x, map_l_y, cv2.INTER_LINEAR)
img_r_rectified = cv2.remap(img_r, map_r_x, map_r_y, cv2.INTER_LINEAR)
# 绘制校正结果
img_rectified = np.hstack((img_l_rectified, img_r_rectified))
cv2.imshow('rectified', img_rectified)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
```
这个代码使用 OpenCV 库实现了棋盘格标定和双目相机标定,同时也演示了如何使用标定参数进行图像校正。请注意,为了获得更好的标定效果,应该使用多组不同角度和位置的棋盘格图片来进行标定。
阅读全文