3. 相机模型与内参标定:针孔相机模型、畸变模型、使用 ROS camera_calibration 包进行内参标定
相机内参标定是手眼标定流程中不可或缺的前置步骤。只有准确获取了相机的内参矩阵和畸变系数,才能将像素坐标可靠地映射到归一化相机坐标系,进而与机器人坐标系建立关联。本节从针孔相机模型出发,逐步引入畸变模型,并给出基于 ROS camera_calibration 包的完整标定流程。
3.1 针孔相机模型
针孔相机模型是计算机视觉中最基础的投影模型。它假设光线通过一个无限小的孔径(光心)在成像平面上形成倒立的像。为简化数学表达,通常将成像平面对称到光心前方,形成虚拟成像平面。
设空间点 P = (X, Y, Z) 在相机坐标系下的坐标为 (Xc, Yc, Zc),其投影到像素平面上的坐标为 (u, v)。投影过程分为两步:
- 归一化平面投影:将三维点投影到归一化平面 (Z=1) 上,得到归一化坐标 (x, y) = (Xc/Zc, Yc/Zc)。
- 像素坐标映射:通过内参矩阵 K 将归一化坐标转换为像素坐标。
内参矩阵 K 的标准形式为:
K = [fx 0 cx
0 fy cy
0 0 1 ]
其中:
- fx, fy:分别为 x 和 y 方向上的归一化焦距(单位:像素),fx = f / dx,fy = f / dy,f 为物理焦距,dx、dy 为像元尺寸。
- cx, cy:主点坐标,即光轴与成像平面的交点(单位:像素)。
完整的投影方程可写为:
s * [u, v, 1]^T = K * [Xc, Yc, Zc, 1]^T
其中 s 为尺度因子(即 Zc)。
3.2 畸变模型
实际相机镜头并非理想针孔,光线通过透镜时会发生折射,导致图像产生畸变。畸变主要分为两类:径向畸变和切向畸变。
| 畸变类型 | 产生原因 | 数学模型 | 典型参数 |
|---|---|---|---|
| 径向畸变 | 透镜形状不完美,光线在透镜边缘弯曲更严重 | xdist = x(1 + k1r² + k2r⁴ + k3r⁶) | k1, k2, k3 |
| 切向畸变 | 透镜与成像平面不平行(安装误差) | xdist = x + [2p1xy + p2(r² + 2x²)] | p1, p2 |
其中 r² = x² + y²,(x, y) 为归一化平面上的理想坐标。畸变校正的目标是找到从畸变坐标到理想坐标的映射关系。在 ROS 中,畸变参数通常以 5 维向量形式存储:[k1, k2, p1, p2, k3]。
3.3 使用 ROS camera_calibration 包进行内参标定
ROS 提供了 camera_calibration 包,基于 OpenCV 的棋盘格标定算法,实现了半自动化的内参标定流程。该包以节点形式运行,订阅相机图像话题,通过交互式界面引导用户采集不同位姿的棋盘格图像,最终生成相机内参和畸变系数。
3.3.1 标定前准备
- 打印棋盘格标定板:推荐使用 7×9 或 8×6 的内角点棋盘格,方格边长需精确测量(如 25mm 或 30mm)。
- 启动相机驱动:确保相机节点已启动,并发布
/camera/image_raw话题(或类似话题)。 - 安装 camera_calibration 包:
sudo apt install ros-noetic-camera-calibration
3.3.2 启动标定节点
运行以下命令启动标定节点:
rosrun camera_calibration cameracalibrator.py \
--size 7x9 \
--square 0.025 \
image:=/camera/image_raw \
camera:=/camera
参数说明:
--size:棋盘格内角点数量(列×行)。--square:方格边长,单位:米。image:=:图像话题名称。camera:=:相机命名空间。
3.3.3 标定操作流程
标定节点启动后会打开一个 GUI 窗口,实时显示相机画面。用户需在视野中移动棋盘格,使标定板覆盖图像的各个区域(左上、右上、左下、右下、中心、倾斜、远近)。GUI 窗口右下角的进度条会显示当前数据采集状态:
| 进度条 | 含义 | 建议操作 |
|---|---|---|
| X(水平方向覆盖) | 棋盘格在图像水平方向上的分布 | 将棋盘格左右移动 |
| Y(垂直方向覆盖) | 棋盘格在图像垂直方向上的分布 | 将棋盘格上下移动 |
| Size(尺度覆盖) | 棋盘格在图像中的大小变化 | 将棋盘格前后移动(靠近/远离相机) |
| Skew(倾斜覆盖) | 棋盘格相对于成像平面的倾斜角度 | 将棋盘格绕 X/Y 轴倾斜 |
当所有进度条变为绿色时,表示数据采集充分。此时 CALIBRATE 按钮变为可用,点击即可开始计算内参。
3.3.4 标定结果与保存
标定完成后,GUI 窗口会显示重投影误差(RMS),通常应小于 0.5 像素。点击 SAVE 按钮,标定结果会以 YAML 格式保存到 /tmp/calibrationdata.tar.gz 中。解压后得到 ost.yaml 和 ost.txt 文件。
ost.yaml 文件内容示例:
image_width: 640
image_height: 480
camera_name: camera
camera_matrix:
rows: 3
cols: 3
data: [532.45, 0.0, 320.12, 0.0, 534.78, 240.56, 0.0, 0.0, 1.0]
distortion_model: plumb_bob
distortion_coefficients:
rows: 1
cols: 5
data: [-0.2834, 0.0735, 0.0012, -0.0008, 0.0]
rectification_matrix:
rows: 3
cols: 3
data: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]
projection_matrix:
rows: 3
cols: 3
data: [532.45, 0.0, 320.12, 0.0, 534.78, 240.56, 0.0, 0.0, 1.0]
将 ost.yaml 复制到相机驱动的配置目录(如 ~/.ros/camera_info/camera.yaml),相机节点启动后会自动加载内参,实现实时畸变校正。
3.4 标定质量评估
标定完成后,建议从以下维度评估标定质量:
| 评估指标 | 合格标准 | 检查方法 |
|---|---|---|
| 重投影误差 (RMS) | < 0.5 像素 | 标定结果窗口直接显示 |
| 主点偏移 | cx ≈ 图像宽度/2,cy ≈ 图像高度/2 | 对比内参矩阵中的 cx、cy |
| 焦距一致性 | fx 与 fy 差异 < 5% | 计算 |fx - fy| / fx |
| 畸变校正效果 | 图像边缘直线不再弯曲 | 在 Rviz 或 image_view 中观察校正后图像 |