3. 相机模型与成像原理
做手眼标定,绕不开相机模型。说白了,相机就是把三维世界投影到二维图像上。这个投影过程怎么描述?就是针孔相机模型。我刚开始接触视觉时,觉得这东西太简单了,不就是小孔成像嘛。但真正做标定才发现,里面的门道不少。
3.1 针孔相机模型
针孔模型是最基础的相机模型。它假设光线通过一个小孔,在成像平面上形成倒像。实际相机用透镜代替小孔,但数学上我们仍然用针孔模型来近似。
关键参数就两个:焦距 f 和 光心位置。焦距决定了成像的缩放比例,光心是光轴与成像平面的交点。
核心公式:
三维点 P(X, Y, Z) 投影到图像点 p(x, y):
x = f * X / Z
y = f * Y / Z
Z 是深度,f 是焦距。注意这里忽略了单位,实际用像素表示。
嗯,这里要注意:针孔模型是理想情况。实际相机有畸变,像素也不是正方形。所以我们需要更完整的数学模型。
3.2 内参矩阵
内参矩阵描述了相机内部的几何参数。它把相机坐标系下的三维点映射到像素坐标系。
我习惯把内参矩阵写成这样:
K = [fx 0 cx
0 fy cy
0 0 1]
其中:
- fx, fy:x 和 y 方向的焦距(像素单位)
- cx, cy:光心在像素坐标系中的位置
为什么 fx 和 fy 可能不同?因为像素不一定是正方形。我在项目中遇到过用工业相机,像素是矩形的,fx 和 fy 差了 5%。如果不校正,标定结果会偏。
我的经验:内参矩阵是标定的核心。每次换相机或调焦距,都必须重新标定内参。别偷懒,否则手眼标定精度会大打折扣。
3.3 畸变模型
实际相机有畸变。主要分两类:径向畸变和切向畸变。
3.3.1 径向畸变
径向畸变是光线通过透镜边缘时弯曲造成的。越靠近图像边缘,畸变越明显。常见的有两种:
- 桶形畸变:图像向外凸出,像桶一样
- 枕形畸变:图像向内凹陷,像枕头
数学模型用泰勒级数展开:
x_corrected = x * (1 + k1*r^2 + k2*r^4 + k3*r^6)
y_corrected = y * (1 + k1*r^2 + k2*r^4 + k3*r^6)
r 是像素到光心的距离。k1, k2, k3 是径向畸变系数。一般用前两项就够了,鱼眼镜头才需要 k3。
避坑指南:我曾经在标定一个广角镜头时,只用了 k1 和 k2,结果边缘误差很大。后来加了 k3,精度提升明显。所以,如果镜头视角大,建议用三个参数。
3.3.2 切向畸变
切向畸变是透镜和成像平面不平行造成的。说白了,就是镜头装歪了。
数学模型:
x_corrected = x + [2*p1*x*y + p2*(r^2 + 2*x^2)]
y_corrected = y + [p1*(r^2 + 2*y^2) + 2*p2*x*y]
p1, p2 是切向畸变系数。这个畸变一般比较小,但也不能忽略。
你想想看,如果镜头安装有 0.5 度的倾斜,在图像边缘可能产生几个像素的误差。对于高精度手眼标定,这误差就大了。
3.4 张正友标定法简介
张正友标定法是目前最流行的相机标定方法。它只需要拍摄多张棋盘格图像,就能标定出内参和畸变参数。
核心思路:
- 拍摄不同角度的棋盘格图像(至少 3 张,建议 10-20 张)
- 提取棋盘格角点坐标
- 利用单应性矩阵求解内参初值
- 用最大似然估计优化所有参数
为什么张正友法好用?
- 不需要知道相机运动
- 只需要平面棋盘格
- 算法稳定,精度高
- OpenCV 直接支持
我在项目中用过很多次张正友法。有个经验:棋盘格要贴平,不能有褶皱。另外,拍摄角度要覆盖整个视场,别只拍中间区域。
实用建议:拍摄时让棋盘格占图像面积的 1/3 到 1/2。太小了角点检测不准,太大了容易超出视场。我一般拍 15 张左右,角度从 0 度到 45 度变化。
3.5 本章知识结构
下面这张图总结了相机模型的核心概念和关系:
3.6 参数对比表
为了方便查阅,我把相机模型的关键参数整理成表:
| 参数 | 符号 | 含义 | 典型值范围 |
|---|---|---|---|
| 焦距(x方向) | fx | 像素单位,与传感器尺寸相关 | 500-3000 |
| 焦距(y方向) | fy | 通常与 fx 接近 | 500-3000 |
| 光心 x | cx | 图像中心 x 坐标 | 图像宽度/2 |
| 光心 y | cy | 图像中心 y 坐标 | 图像高度/2 |
| 径向畸变 1 | k1 | 主要径向畸变系数 | -0.5 ~ 0.5 |
| 径向畸变 2 | k2 | 次要径向畸变系数 | -0.3 ~ 0.3 |
| 径向畸变 3 | k3 | 高阶径向畸变(鱼眼用) | -0.1 ~ 0.1 |
| 切向畸变 1 | p1 | 切向畸变系数 | -0.05 ~ 0.05 |
| 切向畸变 2 | p2 | 切向畸变系数 | -0.05 ~ 0.05 |
重要提醒:标定出的参数一定要验证。我习惯用重投影误差来评估,一般小于 0.5 像素就算合格。如果误差大于 1 像素,说明标定有问题,需要重新拍图。