4. 相机成像模型:从三维世界到二维像素
相机是怎么把三维世界“拍”成一张二维照片的?
这个问题,我当年刚入行时也琢磨了很久。说白了,相机成像就是一个坐标变换的过程——把现实中的点,一步步映射到像素坐标系上。今天咱们就把它彻底讲透。
4.1 针孔相机模型:最朴素的成像原理
针孔相机模型,是所有相机模型的基础。它假设光线沿直线传播,穿过一个小孔,在成像平面上形成倒立的像。
嗯,这里要注意:实际相机用的是透镜,不是针孔。但针孔模型足够简单,也足够精确,所以成了行业标准。
数学上,针孔模型描述的是从三维世界坐标到二维图像坐标的映射关系。我习惯把它拆成三步:
- 世界坐标系 → 相机坐标系(刚体变换,旋转+平移)
- 相机坐标系 → 图像坐标系(透视投影)
- 图像坐标系 → 像素坐标系(离散化采样)
这三步,每一步都有对应的矩阵运算。咱们一个一个来看。
4.2 内参矩阵:相机自己的“基因”
内参矩阵描述的是相机内部的光学特性。它决定了:一个三维点投影到图像上,到底落在哪个像素位置。
内参矩阵 K 长这样:
K = [fx 0 cx
0 fy cy
0 0 1]
其中:
- fx, fy:焦距在 x 和 y 方向上的像素尺度。说白了,就是焦距除以像元尺寸。
- cx, cy:主点坐标,也就是光轴与成像平面的交点。理想情况下在图像中心,但实际总有偏差。
我在项目中遇到过一件事:某次标定完发现 cx 偏了 5 个像素,一开始以为是标定板没放正。后来查了查,其实是镜头装配时传感器没对准。嗯,这种偏差很常见,但必须标定出来。
4.3 外参矩阵:相机在哪儿?朝哪儿看?
外参矩阵描述的是相机在世界坐标系中的位置和朝向。它由两部分组成:
- 旋转矩阵 R:3×3,描述相机的朝向
- 平移向量 t:3×1,描述相机的位置
外参矩阵通常写作 [R | t],是一个 3×4 的矩阵。
你想想看,自动驾驶车上装了 6 个摄像头,每个摄像头的外参都不一样。前视相机朝前看,侧视相机朝侧看。这些外参必须精确标定,否则融合出来的点云全是错的。
4.4 畸变模型:镜头不是完美的
现实中的镜头不是针孔,而是透镜。透镜会引入畸变,导致图像变形。畸变主要分两种:
4.4.1 径向畸变
径向畸变是沿着镜头半径方向的变形。离光心越远,畸变越明显。它又分两种:
- 桶形畸变:图像向外凸出,像桶一样。广角镜头常见。
- 枕形畸变:图像向内凹陷,像枕头一样。长焦镜头常见。
数学上,径向畸变用三个参数描述:k1, k2, k3。其中 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)
其中 r 是像素点到光心的距离。
4.4.2 切向畸变
切向畸变是由于镜头和传感器不平行造成的。说白了,就是镜头装歪了。
切向畸变用两个参数描述: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]
我记得有一次标定完,发现切向畸变参数特别大。检查了一下,果然是镜头没拧紧。拧紧后再标定,参数就正常了。
4.5 完整成像模型:从世界到像素
把上面所有东西串起来,完整的成像过程是这样的:
- 世界坐标系下的点 P_w = [X, Y, Z, 1]^T
- 通过外参矩阵变换到相机坐标系:P_c = [R | t] * P_w
- 透视投影到归一化平面:x = X_c / Z_c, y = Y_c / Z_c
- 加入畸变:x', y' = distort(x, y)
- 通过内参矩阵映射到像素:u = fx * x' + cx, v = fy * y' + cy
这个过程,我建议你写成一个函数。每次标定完,用这个函数验证一下,看看投影误差有多大。
4.6 知识体系结构图
下面这张图,是我自己整理的相机成像模型知识体系。你可以把它当作学习路线图:
4.7 总结
相机成像模型,说白了就是一套数学公式。但理解它背后的物理意义,比死记公式重要得多。
我个人习惯把内参、外参、畸变参数分开理解。内参是相机自己的事,外参是相机和世界的关系,畸变是镜头不完美的补偿。三者合在一起,才能把三维世界准确地映射到二维像素上。
下一节,咱们会讲怎么用 OpenCV 实际标定这些参数。到时候,我会分享一些我踩过的坑,帮你少走弯路。
可可精品资料库