什么是 相机标定(Camera Calibration)?
相机标定(CameraCalibration)是确定相机内部参数(如焦距、光学中心、畸变系数等)和外部参数(如相机在世界坐标系中的位置和姿态)的一种过程
相机标定的主要内容
内参数(Intrinsic Parameters):
焦距(focal length):相机镜头的焦距。
主点(principal point):图像中心(光学中心)的坐标。
畸变系数(distortion coefficients):描述相机镜头的畸变,通常包括径向畸变和切向畸变。
外参数(Extrinsic Parameters):
旋转矩阵(rotation matrix):描述相机坐标系相对于世界坐标系的旋转。
平移向量(translation vector):描述相机坐标系相对于世界坐标系的平移。
相机标定的方法
棋盘格法(Checkerboard Method):
最常用的方法,通过拍摄多个角度下的棋盘格图片,利用棋盘格的几何特性来确定相机的内外参数。
标定板法(Calibration Board Method):
使用特定设计的标定板,如圆点阵列或条纹板,通过拍摄标定板的多张图片进行标定。
单点标定法(Single Point Method):
通过移动一个已知位置的点在相机视野中的位置变化来进行标定。
标定步骤
图像采集:
使用相机拍摄多张包含标定图案(如棋盘格或标定板)的图像,图像应覆盖不同的角度和位置。
特征点提取:
在每张图像中,检测并提取标定图案上的特征点(如棋盘格的角点)。
参数估计:
使用特征点的图像坐标和实际坐标,通过算法(如Tsai’s两步法、Zhang’s自标定法)估计相机的内参数和外参数。
非线性优化:
使用非线性优化算法(如Levenberg-Marquardt算法)进一步优化估计的参数,以最小化重投影误差。
畸变校正:
根据畸变系数,校正图像中的畸变,获取校正后的图像。
标定工具和软件
OpenCV:
一个开源的计算机视觉库,提供了丰富的相机标定函数,如cv2.findChessboardCorners、cv2.calibrateCamera等。
MATLAB:
提供了Camera Calibration Toolbox,可以方便地进行相机标定和畸变校正。
ROS(Robot Operating System):
提供了相机标定包camera_calibration,适用于机器人视觉系统。
示例代码(使用OpenCV)
import cv2
import numpy as np
import glob
# 设置棋盘格尺寸
chessboard_size = (9, 6)
frame_size = (640, 480)
# 设置标定板世界坐标系中的三维点
objp = np.zeros((chessboard_size[0] * chessboard_size[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:chessboard_size[0], 0:chessboard_size[1]].T.reshape(-1, 2)
objpoints = [] # 世界坐标系中的三维点
imgpoints = [] # 图像平面的二维点
# 读取棋盘格图像
images = glob.glob('calibration_images/*.jpg')
for image in images:
img = cv2.imread(image)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 查找棋盘格角点
ret, corners = cv2.findChessboardCorners(gray, chessboard_size, None)
if ret:
objpoints.append(objp)
imgpoints.append(corners)
# 绘制并显示角点
cv2.drawChessboardCorners(img, chessboard_size, corners, ret)
cv2.imshow('img', img)
cv2.waitKey(500)
cv2.destroyAllWindows()
# 标定相机
ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, frame_size, None, None)
print("Camera matrix: \n", camera_matrix)
print("Distortion coefficients: \n", dist_coeffs)
# 畸变校正
for image in images:
img = cv2.imread(image)
h, w = img.shape[:2]
new_camera_matrix, roi = cv2.getOptimalNewCameraMatrix(camera_matrix, dist_coeffs, (w, h), 1, (w, h))
# 畸变校正
dst = cv2.undistort(img, camera_matrix, dist_coeffs, None, new_camera_matrix)
# 裁剪图像
x, y, w, h = roi
dst = dst[y:y+h, x:x+w]
cv2.imshow('undistorted image', dst)
cv2.waitKey(500)
cv2.destroyAllWindows()