1. 相机成像原理:小孔成像模型、透镜畸变、相机坐标系与像素坐标系
相机标定这件事,说白了就是搞清楚「三维世界里的点,是怎么跑到二维照片上的」。我刚开始做视觉项目时,总觉得标定就是拍几张棋盘格、跑个函数完事。直到有一次在产线上,标定出来的内参死活不对,投影误差大得离谱……后来才发现,是我没搞懂最基础的成像模型。
这一节,咱们就把相机成像的底子打牢。你理解了小孔成像、畸变、坐标系变换,后面的角点提取和标定才能做得稳。
1.1 小孔成像模型
相机最原始的模型,就是小孔成像。你想想看,一个暗箱,前面戳个小孔,外面的光线穿过小孔,在后面的感光面上形成一个倒立的像。这就是最朴素的成像原理。
核心公式(小孔成像):
X_image = -f * (X_world / Z_world)
Y_image = -f * (Y_world / Z_world)
其中 f 是焦距(小孔到成像面的距离),负号表示像是倒立的。
实际相机为了处理方便,会把倒像「正过来」,所以公式里通常省略负号。现代相机用透镜代替小孔,但核心思想没变——世界坐标到图像坐标,是一个透视投影关系。
我的习惯:在推导标定公式时,我总把成像模型画成「针孔-成像面-物体」三条线,这样坐标系关系一目了然。别嫌简单,这步画错了,后面全白搭。
1.2 透镜畸变
理想的小孔模型没有畸变,但真实相机用的是透镜。透镜有厚度、有曲率,光线穿过时会发生折射偏移。这就导致了畸变。
畸变主要分两类:
| 畸变类型 | 现象 | 产生原因 |
|---|---|---|
| 径向畸变 | 直线变弯,越靠近边缘越明显 | 透镜曲率不完美,光线偏折角度随距离变化 |
| 切向畸变 | 图像倾斜、梯形失真 | 透镜与成像面不平行(装配误差) |
径向畸变又分两种:
- 桶形畸变:图像向外鼓,像鱼眼镜头那样。我最早用广角摄像头做室内定位时,就被桶形畸变坑过——墙角明明是直的,拍出来却是弯的。
- 枕形畸变:图像向内缩,长焦镜头容易出现。
畸变的数学模型长这样:
// 径向畸变(k1, k2, k3 是畸变系数)
x_distorted = x * (1 + k1*r^2 + k2*r^4 + k3*r^6)
y_distorted = y * (1 + k1*r^2 + k2*r^4 + k3*r^6)
// 切向畸变(p1, p2 是畸变系数)
x_distorted = x + [2*p1*x*y + p2*(r^2 + 2*x^2)]
y_distorted = y + [p1*(r^2 + 2*y^2) + 2*p2*x*y]
我曾经踩过的坑:标定畸变系数时,棋盘格图像必须覆盖整个视场。如果你只拍了中间区域,边缘畸变没被约束,标出来的 k1、k2 会严重偏离真实值。后来我每次标定都至少拍 20 张图,四角和边缘必须到位。
1.3 相机坐标系与像素坐标系
搞懂坐标系,是标定的基本功。我见过不少新手,把世界坐标、相机坐标、图像坐标、像素坐标混在一起算,结果怎么算都不对。咱们一个一个捋清楚。
一共涉及四个坐标系:
- 世界坐标系 (Xw, Yw, Zw):你自定义的全局参考系。棋盘格标定板上的角点坐标,就是在这个系里定义的。
- 相机坐标系 (Xc, Yc, Zc):以相机光心为原点,Zc 轴沿光轴方向。世界坐标到相机坐标,靠的是旋转矩阵 R 和平移向量 t。
- 图像坐标系 (x, y):在成像面上,以光轴与成像面交点为原点,单位是毫米。相机坐标到图像坐标,靠的是小孔成像的透视投影。
- 像素坐标系 (u, v):在图像上,以左上角为原点,单位是像素。图像坐标到像素坐标,靠的是缩放和平移(内参矩阵 K 的一部分)。
整个变换链条是这样的:
世界坐标 (Xw,Yw,Zw)
→ [R|t] 外参
→ 相机坐标 (Xc,Yc,Zc)
→ 透视投影
→ 图像坐标 (x,y)
→ 内参矩阵 K
→ 像素坐标 (u,v)
内参矩阵 K 长这样:
K = [ fx 0 cx
0 fy cy
0 0 1 ]
fx, fy 是焦距的像素表示(f / 像元尺寸),cx, cy 是光心在像素坐标系中的位置。标定的核心任务之一,就是算出这 4 个参数 + 畸变系数。
1.4 知识结构总览
下面这张图,把这一节的核心逻辑串起来了。我建议你把它存下来,后面学标定流程时随时回来对照。
1.5 坐标系变换的数学表达
把上面的链条写成矩阵形式,就是标定里最核心的公式:
s * [u, v, 1]^T = K * [R|t] * [Xw, Yw, Zw, 1]^T
其中:
- s 是尺度因子(因为透视投影丢失了深度信息)
- K 是内参矩阵(3×3)
- [R|t] 是外参矩阵(3×4)
- [Xw, Yw, Zw, 1]^T 是世界坐标的齐次形式
我的建议:刚开始学标定的人,我建议你亲手把上面这个矩阵乘法展开一次。把 K 和 [R|t] 的每个元素写出来,算一遍 u 和 v 是怎么由 Xw、Yw、Zw 表达出来的。这一步做通了,后面张正友标定法的推导你就不会晕。
1.6 为什么需要标定?
说白了,相机出厂时内参和畸变系数是未知的。就算厂家给了标称值,也跟实际有偏差——温度、装配、镜头批次都会影响。我遇到过最夸张的一次,同一型号的两台相机,fx 差了 15 个像素。不标定直接做三维重建,误差能偏到天上去。
标定的目的,就是通过拍摄已知几何结构的标定物(比如棋盘格),用数学方法反算出 K 和畸变系数。有了这些参数,你才能:
- 把像素坐标还原成相机坐标(去畸变 + 逆透视)
- 做三维重建、视觉定位、测距
- 保证多相机系统的空间一致性
注意:标定不是一劳永逸的。如果相机被摔过、镜头重新拧过、或者温度变化剧烈,内参可能会变。我每做一个新项目,都会重新标一次,哪怕用的是同一台相机。