在使用相机进行视觉测量时,获取相机的内参(Intrinsic Parameters)和畸变系数(Distortion Coefficients)是核心步骤,通常需要通过相机标定(Camera Calibration)完成。以下是详细的获取方法及流程:
1. 标定前的准备工作
标定工具
- 标定板:选择高精度、高对比度的标定板,如:
- 棋盘格标定板(Chessboard Pattern):黑白交替的方格,适合角点检测(OpenCV常用)。
- 圆点标定板(Dot Pattern):圆心中心检测更鲁棒,适用于透视变形较大的场景。
- 软件工具:推荐使用 OpenCV(开源)、MATLAB Camera Calibrator 或专业标定软件(如Halcon)。
数据采集要求
- 图像数量:建议拍摄 10-20张 不同角度、位置的标定板图像,覆盖整个视场(边缘区域必须包含)。
- 标定板姿态:标定板需在三维空间中倾斜、旋转,避免所有图像中平面平行于相机传感器。
- 环境条件:标定时的光照、焦距、对焦距离需与实际测量环境一致。
2. 标定流程(以OpenCV为例)
步骤1:采集标定板图像
- 用相机拍摄多张标定板图像(如图示例):
!棋盘格标定板
步骤2:检测标定板特征点
- 棋盘格:使用
cv2.findChessboardCorners()
检测角点。
- 圆点标定板:使用
cv2.findCirclesGrid()
检测圆心。
- 亚像素优化:通过
cv2.cornerSubPix()
提高角点精度(需输入灰度图)。
import cv2
# 读取图像并检测角点
image = cv2.imread("calib_image.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(gray, (cols, rows), None)
# 亚像素优化(提高精度)
if ret:
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
corners_refined = cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)
步骤3:构建标定输入数据
- 对象点(Object Points):标定板在真实世界中的3D坐标(通常假设标定板在Z=0平面)。
- 图像点(Image Points):标定板在图像中的2D角点坐标。
import numpy as np
# 标定板实际尺寸(单位:mm或任意物理单位)
square_size = 25.0 # 每个方格的边长
objp = np.zeros((rows*cols, 3), np.float32)
objp[:, :2] = np.mgrid[0:cols, 0:rows].T.reshape(-1, 2) * square_size
# 存储所有图像的对象点和图像点
objpoints = [] # 3D点
imgpoints = [] # 2D点
# 对每张标定图像重复此过程
objpoints.append(objp)
imgpoints.append(corners_refined)
步骤4:计算内参和畸变系数
调用 cv2.calibrateCamera()
进行标定:
# 标定相机
ret, K, D, rvecs, tvecs = cv2.calibrateCamera(
objpoints, imgpoints, gray.shape[::-1], None, None
)
# 输出结果
print("内参矩阵 K:\n", K)
print("畸变系数 D (k1, k2, p1, p2, k3):\n", D)
print("重投影误差 (越低越好):", ret)
参数说明
-
内参矩阵(K):
[[fx, 0, cx],
[0, fy, cy],
[0, 0, 1]]
fx, fy
: 焦距(像素单位)
cx, cy
: 光心(图像中心坐标)
-
畸变系数(D):[k1, k2, p1, p2, k3]
(径向畸变 k1~k3,切向畸变 p1~p2)
3. 验证标定结果
关键指标
- 重投影误差(Reprojection Error):
- 计算标定板角点的理论投影位置与实际检测位置的均方误差。
- 要求:一般需 < 0.5像素,误差过大需重新标定。
直观验证
-
使用 cv2.undistort()
矫正图像,观察直线是否恢复平直:
undistorted = cv2.undistort(image, K, D)
4. 特殊情况处理
广角/鱼眼镜头
-
若畸变严重(如广角镜头),需使用 鱼眼模型:
# 使用 cv2.fisheye.calibrate()
flags = cv2.fisheye.CALIB_RECOMPUTE_EXTRINSIC
ret, K, D, rvecs, tvecs = cv2.fisheye.calibrate(...)
无标定板的替代方法
- 基于已知物体的标定:利用场景中已知尺寸的物体(如A4纸、标准零件)手动输入对象点。
- 自标定(Self-Calibration):通过多视图几何约束估计参数(精度较低,不推荐)。
5. 保存与加载参数
将标定结果保存为文件(如JSON、YAML),便于后续使用:
import json
calib_data = {
"K": K.tolist(),
"D": D.tolist(),
"reprojection_error": ret
}
with open("camera_calib.json", "w") as f:
json.dump(calib_data, f)
总结
- 标定板准备:覆盖视场,多角度拍摄。
- 特征点检测:角点或圆心,亚像素优化。
- 参数计算:通过OpenCV或MATLAB工具。
- 验证与优化:重投影误差 + 直观图像矫正。
注意事项:
- 标定过程中需固定焦距和对焦。
- 动态环境(如温度变化大)需定期重新标定。
- 避免使用模糊、过曝或欠曝的图像。