4. 相机成像模型:针孔相机模型、畸变模型
相机成像模型,说白了就是回答一个问题:三维世界里的一个点,是怎么跑到二维照片上的?
我刚开始接触视觉SLAM时,觉得这玩意儿太简单了——不就是小孔成像嘛。后来真上手做外参标定,才发现里面坑不少。今天咱们就把这个基础打牢。
4.1 针孔相机模型
针孔相机模型是最经典的成像模型。它假设光线通过一个小孔,在成像平面上形成倒像。嗯,这里要注意,实际相机为了便于计算,我们会把成像平面前移到相机前方,这样图像就是正的了。
数学上,一个三维点 P(X, Y, Z) 投影到像素坐标 (u, v) 的过程,可以拆成三步:
- 世界坐标系 → 相机坐标系:通过旋转和平移(这就是外参!)
- 相机坐标系 → 归一化平面:除以 Z 坐标,得到 (x, y) = (X/Z, Y/Z)
- 归一化平面 → 像素坐标系:乘以内参矩阵 K
写成矩阵形式就是:
Z * [u] = [fx 0 cx] [X]
[v] [ 0 fy cy] * [Y]
[1] [ 0 0 1] [Z]
这个公式我建议你背下来。我在项目中遇到过好几次,有人把 fx 和 fy 搞混了,结果标定出来的外参全是错的。
关键参数说明:
- fx, fy:焦距在像素坐标系下的表示,单位是像素
- cx, cy:光心在像素坐标系下的位置
- Z:点在相机坐标系下的深度值
4.2 畸变模型
理想很丰满,现实很骨感。实际相机用的都是透镜,不是针孔。透镜会带来畸变,说白了就是图像变形了。
畸变主要分两种:径向畸变和切向畸变。
4.2.1 径向畸变
径向畸变是沿着镜头半径方向的变形。你想想看,光线经过透镜边缘时,折射角度和中心不一样,所以图像边缘会扭曲。
有两种情况:
- 桶形畸变:图像向外凸出,像桶一样。广角镜头常见。
- 枕形畸变:图像向内凹陷,像枕头。长焦镜头常见。
数学上,我们用三个参数 k1, k2, k3 来描述径向畸变:
x_distorted = x * (1 + k1*r² + k2*r⁴ + k3*r⁶)
y_distorted = y * (1 + k1*r² + k2*r⁴ + k3*r⁶)
其中 r² = x² + y²,是点到光心的距离。
我的经验:对于普通工业相机,k3 通常设为 0,只用 k1 和 k2 就够了。k3 主要是给鱼眼镜头用的。我曾经为了省事,给一个普通镜头也用了 k3,结果标定结果反而更差了。
4.2.2 切向畸变
切向畸变是因为透镜和成像平面不平行造成的。说白了就是镜头装歪了,或者传感器贴歪了。
切向畸变用两个参数 p1, p2 来描述:
x_distorted = x + (2*p1*x*y + p2*(r² + 2*x²))
y_distorted = y + (p1*(r² + 2*y²) + 2*p2*x*y)
避坑指南:我曾经遇到过一个项目,标定出来的重投影误差总是很大。查了两天才发现,是相机模组在组装时传感器歪了,切向畸变参数 p1, p2 特别大。这种情况下,光靠标定是救不回来的,得返厂维修。
4.3 完整的畸变校正流程
实际做外参标定时,我们通常先做畸变校正,再做投影。流程是这样的:
- 从图像上提取特征点,得到像素坐标 (u, v)
- 用内参反算到归一化平面,得到 (x, y)
- 用畸变参数对 (x, y) 做校正,得到 (x_corrected, y_corrected)
- 再用外参把 (x_corrected, y_corrected) 和世界坐标对应起来
这个顺序不能乱。我见过有人先做外参投影再做畸变校正,结果全乱了。
4.4 知识体系结构图
下面这张图总结了相机成像模型的完整流程:
4.5 实际标定中的注意事项
| 参数 | 常见问题 | 我的建议 |
|---|---|---|
| k1, k2 | 数值过大或过小 | k1 通常在 -0.5 ~ 0.5 之间,超出这个范围要检查标定板 |
| p1, p2 | 数值异常大 | 如果 p1, p2 > 0.1,大概率是镜头装歪了 |
| fx, fy | 两者差异大 | fx 和 fy 差异在 5% 以内正常,太大说明传感器像素不是正方形 |
| cx, cy | 偏离图像中心 | 偏离 10 个像素以内正常,偏离太多说明光心没对准 |
总结一下:针孔模型是基础,畸变模型是修正。做外参标定前,一定要先确认内参和畸变参数是准的。否则外参标出来也是错的,白费功夫。
嗯,这一章的内容就到这儿。记住一句话:模型是死的,但参数是活的。每个相机都有自己的脾气,多标定几次,你就能摸透它的性格了。