3、相机模型:针孔相机模型、畸变模型、图像坐标系与像素坐标系

好,咱们进入相机模型这一节。说实话,这是整个传感器模型里最基础、也最容易被忽视的一块。很多刚入行的同学觉得相机嘛,拍个照而已,有什么好讲的?但等你真正做感知联调的时候,就会发现——相机模型没搞懂,后面所有的工作都是空中楼阁。

我个人习惯把相机模型拆成三块来讲:针孔模型、畸变模型、还有坐标系转换。这三块搞明白了,你就能理解相机到底是怎么把三维世界映射到一张二维图片上的。

3.1 针孔相机模型:最朴素的成像原理

针孔相机模型,说白了就是小孔成像。你想想看,一个暗箱,前面戳个小孔,光线穿过小孔在后面的感光面上成像。这就是最原始的相机。

数学上怎么描述?我们通常用这个公式:

λ * [u, v, 1]^T = K * [R|t] * [X, Y, Z, 1]^T

这里λ是尺度因子,K是内参矩阵,[R|t]是外参矩阵。嗯,看着有点复杂,但核心思想就一句话:世界坐标系下的一个点,经过旋转平移,再投影到图像平面上。

核心要点:针孔模型假设光线是直线传播的,没有畸变。但现实中的镜头不可能这么完美,所以我们需要畸变模型来修正。

我在项目中遇到过一个问题:用标定板算出来的内参,放到实际场景里总是有偏差。后来发现,是因为标定板离相机太近了,导致投影模型不准确。所以我的建议是——标定的时候,尽量让标定板覆盖整个视场,而且距离要跟实际使用场景接近。

3.2 畸变模型:镜头不是完美的

现实中的镜头,尤其是广角镜头,会有明显的畸变。最常见的两种:径向畸变和切向畸变。

径向畸变:就是画面边缘的直线变弯了。桶形畸变和枕形畸变,你肯定见过。数学上我们用多项式来拟合:

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)

这里r是像素点到光心的距离,k1、k2、k3是畸变系数。一般用前两个就够了,k3是给大畸变镜头准备的。

切向畸变:这个是因为镜头和感光芯片不平行造成的。公式长这样:

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]

p1、p2是切向畸变系数。

避坑指南:我曾经在标定一个鱼眼镜头时,只用了径向畸变模型,结果去畸变后的图像边缘还是有明显的扭曲。后来加上切向畸变模型,效果就好多了。所以,如果你的镜头畸变比较大,建议两个模型都用上。

3.3 图像坐标系与像素坐标系

这个其实是个很容易搞混的点。我刚开始做感知的时候,就经常把图像坐标和像素坐标弄反。

图像坐标系:以图像中心为原点,单位是毫米或米。坐标轴是x向右,y向下。

像素坐标系:以图像左上角为原点,单位是像素。坐标轴是u向右,v向下。

它们之间的转换关系很简单:

u = x / dx + u0
v = y / dy + v0

其中dx、dy是每个像素的物理尺寸,u0、v0是图像中心在像素坐标系下的坐标。

你想想看,为什么要有这两个坐标系?因为相机硬件输出的是像素,但算法处理的时候需要物理尺寸。所以这个转换是必须的。

坐标系 原点 单位 用途
图像坐标系 图像中心 毫米/米 物理尺寸计算
像素坐标系 左上角 像素 图像处理、显示

注意:在OpenCV中,默认使用的是像素坐标系。但如果你用相机标定工具箱,输出的往往是图像坐标系下的坐标。这个转换一定要做对,否则后续的感知算法全都会偏。

3.4 知识体系结构图

下面这张图,是我自己总结的相机模型知识体系。你可以把它当作一个快速索引:

相机模型知识体系 相机模型 针孔相机模型 畸变模型 坐标系转换 小孔成像原理 内参矩阵K 径向畸变 切向畸变 图像坐标系 像素坐标系 感知联调中的应用:标定、去畸变、坐标转换 最终输出:准确的像素坐标 → 感知算法

这张图把整个相机模型的知识脉络理清楚了。从针孔模型到畸变修正,再到坐标系转换,最后落到感知联调的实际应用中。我个人习惯在做项目前,先画这么一张图,确保每个环节都覆盖到了。

总结一下:相机模型是感知系统的眼睛。针孔模型告诉你理想情况下的成像规律,畸变模型修正了镜头的物理缺陷,坐标系转换则把物理世界和像素世界连接起来。这三块缺一不可。

嗯,今天就先聊到这儿。下一节我们会讲激光雷达模型,到时候再跟大家分享一些我在多传感器融合中踩过的坑。

可可精品资料库