3. 相机成像模型:针孔相机模型、畸变模型、内参矩阵与外参矩阵

各位同学,今天我们来聊聊相机成像模型。说实话,这是整个视觉定位的基石。你想想看,如果连相机怎么把三维世界变成二维图像都搞不清楚,后面谈什么定位、建图?

我在做第一个SLAM项目时,就吃过这个亏。当时觉得相机模型太简单,直接拿OpenCV的标定结果就用。结果呢?定位误差大得离谱。后来才发现,我对畸变模型的理解太肤浅了。嗯,今天咱们就把这块彻底讲透。

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

针孔相机模型,说白了就是小孔成像。光从物体上反射过来,穿过一个小孔,在后面的感光平面上形成倒像。这个模型虽然简单,但它是所有复杂相机模型的基础。

数学上怎么描述?我们设世界坐标系中有一个点 P = (X, Y, Z),它通过针孔投影到成像平面上的点 p = (x, y)。根据相似三角形原理:

x = f * (X / Z)
y = f * (Y / Z)

这里的 f 是焦距。注意,这个模型假设了:

  • 光线沿直线传播(不考虑衍射)
  • 小孔无限小(不考虑光圈大小)
  • 成像平面完全平整

实际相机当然不完美,但针孔模型给了我们一个很好的起点。我个人习惯把针孔模型看作「理想状态」,后面所有的畸变补偿,都是在修正现实与理想的偏差。

核心要点:针孔模型建立了3D点到2D点的映射关系,是透视投影的数学表达。

3.2 畸变模型——现实总是不完美的

现实中的镜头不是针孔,而是透镜组。透镜会带来各种畸变。我遇到过最夸张的一次,一个广角镜头在边缘处的畸变达到了几十个像素。如果不做补偿,你算出来的位姿全是错的。

畸变主要分两类:径向畸变和切向畸变。

3.2.1 径向畸变

径向畸变是镜头形状引起的。说白了,就是光线经过透镜边缘时,弯曲程度和中心不一样。这导致图像边缘的直线会变弯。

径向畸变有两种:

  • 桶形畸变:图像向外膨胀,直线向外弯曲。常见于广角镜头。
  • 枕形畸变:图像向内收缩,直线向内弯曲。常见于长焦镜头。

数学上,我们用多项式来建模径向畸变:

x_corrected = x * (1 + k1 * r² + k2 * r⁴ + k3 * r⁶)
y_corrected = y * (1 + k1 * r² + k2 * r⁴ + k3 * r⁶)

其中 r 是像素点到图像中心的距离,k1、k2、k3 是径向畸变系数。一般用 k1、k2 就够了,k3 只在畸变特别严重时才需要。

我的经验:标定径向畸变时,一定要拍足够多的棋盘格图像。我建议至少20张,覆盖图像的不同区域和角度。少于10张的话,标定结果往往不稳定。

3.2.2 切向畸变

切向畸变是镜头和成像平面不平行造成的。说白了,就是镜头装歪了。这在工业相机中比较常见,尤其是那些便宜货。

切向畸变的数学模型:

x_corrected = x + [2 * p1 * x * y + p2 * (r² + 2 * x²)]
y_corrected = y + [p1 * (r² + 2 * y²) + 2 * p2 * x * y]

p1、p2 是切向畸变系数。说实话,切向畸变通常比径向畸变小得多。我在项目中一般只标定径向畸变,除非发现图像有明显的梯形变形。

避坑指南:我曾经在一个项目中,发现标定后的图像边缘还是有扭曲。查了半天,原来是镜头和相机之间的螺纹没拧紧。所以,硬件上的机械问题,软件是补偿不了的。先检查硬件,再谈算法。

3.3 内参矩阵——相机的「身份证」

内参矩阵描述了相机内部的几何特性。它把相机坐标系中的3D点映射到像素坐标系。说白了,就是告诉你:一个三维点,在图像上对应哪个像素。

内参矩阵 K 的形式:

K = [fx,  0, cx]
    [ 0, fy, cy]
    [ 0,  0,  1]

其中:

  • fx, fy:焦距在x和y方向上的像素度量。如果像素是正方形,fx = fy。
  • cx, cy:主点坐标,即光轴与成像平面的交点。理想情况下在图像中心。

你想想看,内参矩阵为什么重要?因为它是每个相机独有的。换一个相机,内参就变了。所以做视觉定位时,第一步就是标定内参。

注意:内参矩阵中的 fx、fy 不是物理焦距 f,而是 f 除以像素尺寸。单位是像素。所以同样的物理焦距,像素尺寸越小,fx 越大。

3.4 外参矩阵——相机在哪儿?朝哪儿看?

外参矩阵描述的是相机在世界坐标系中的位置和朝向。它由旋转矩阵 R 和平移向量 t 组成。

外参矩阵的形式:

[R | t]

其中 R 是 3×3 的旋转矩阵,t 是 3×1 的平移向量。

外参矩阵的作用,是把世界坐标系中的点转换到相机坐标系。数学表达:

P_camera = R * P_world + t

然后,再通过内参矩阵投影到图像上。

我在做多相机系统时,经常需要标定外参。比如一个机器人上有两个相机,我需要知道它们之间的相对位置和朝向。这就是外参标定。

小技巧:外参矩阵有6个自由度(3个旋转 + 3个平移)。标定时,我习惯用棋盘格作为参考物,拍摄多组图像,然后用PnP算法求解。注意,旋转矩阵必须是正交矩阵,行列式为+1。

3.5 完整成像流程——从世界到像素

好了,我们把所有东西串起来。一个3D点从世界坐标系到像素坐标系的完整流程:

  1. 世界坐标系 → 相机坐标系:用外参矩阵 [R|t] 变换
  2. 相机坐标系 → 归一化平面:除以 Z 坐标,得到归一化坐标 (x, y)
  3. 畸变校正:对归一化坐标应用径向和切向畸变模型
  4. 归一化平面 → 像素坐标系:用内参矩阵 K 映射

这个流程,我建议你背下来。因为所有视觉定位算法,无论是特征点法还是直接法,都绕不开这个流程。

一句话总结:外参告诉你相机在哪儿,内参告诉你相机怎么成像,畸变模型告诉你现实和理想的偏差。

3.6 知识体系结构图

下面我用一张图来总结本章的知识体系。这张图是我自己画的,你可以把它当作学习地图。

相机成像模型知识体系 相机成像模型 针孔相机模型 畸变模型 内参矩阵 外参矩阵 相似三角形 透视投影 径向畸变 切向畸变 fx, fy, cx, cy 像素映射 旋转矩阵 R 平移向量 t

这张图展示了本章的四个核心模块。它们不是孤立的,而是串联成一个完整的成像流水线。你学完这一章,应该能闭着眼睛画出这张图。


公众号:蓝海资料掘金营,微信deep3321