3. 相机成像模型:从光线到像素的数学映射

相机是怎么把三维世界变成二维图像的?这个问题,我当年刚入行时也琢磨了很久。说白了,就是一套从世界坐标到像素坐标的数学变换。今天咱们就把它拆开揉碎了讲清楚。

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

针孔相机模型是所有成像模型的基础。它假设光线沿直线传播,穿过一个小孔后在成像平面上形成倒立的像。虽然真实相机复杂得多,但这个模型能解决90%的几何标定问题。

核心公式:

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

其中:λ 是尺度因子,[u,v] 是像素坐标,K 是内参矩阵,[R|t] 是外参矩阵,[X,Y,Z] 是世界坐标。

这个公式看着唬人,其实就三步:

  1. 世界坐标 → 相机坐标:通过旋转矩阵 R 和平移向量 t
  2. 相机坐标 → 归一化平面:除以 Z 值,得到归一化坐标 (x, y)
  3. 归一化平面 → 像素坐标:通过内参矩阵 K 映射到像素

我个人习惯把第一步叫"摆相机",第二步叫"透视投影",第三步叫"数字化"。这样好记。

3.2 内参矩阵:相机的"身份证"

内参矩阵 K 描述了相机内部的几何特性。它长这样:

K = [fx,  0, cx;
      0, fy, cy;
      0,  0,  1]
参数 含义 典型值(1080p相机)
fx, fy 焦距(像素单位) ~1400 px
cx, cy 主点坐标(光轴与像面交点) ~960, 540

实战经验:fx 和 fy 理论上应该相等,但实际生产中传感器像素不是完美的正方形,所以会有微小差异。我遇到过一台工业相机,fx=1423.7,fy=1425.1,差了1.4个像素——这在亚像素精度测量中必须修正。

3.3 外参矩阵:相机在哪儿?朝哪儿看?

外参矩阵 [R | t] 描述了相机在世界坐标系中的位姿。R 是3×3旋转矩阵,t 是3×1平移向量。

举个例子:假设相机放在桌子上,距离地面1米,正对着前方。那么:

  • t = [0, 0, 1]^T(相机在Z轴方向偏移1米)
  • R = 单位矩阵(没有旋转)

但实际项目中,相机很少摆得这么规矩。我记得有一次在产线上装相机,安装支架有0.5度的倾斜,结果测量误差直接超了0.3mm。后来我养成了一个习惯:每次装完相机,先用标定板跑一遍外参,确认旋转角小于0.1度再干活。

3.4 透镜畸变:理想很丰满,现实很骨感

针孔模型假设光线完美直线传播,但真实镜头有畸变。主要分两类:

3.4.1 径向畸变

光线通过透镜边缘时弯曲更厉害,导致图像边缘向内或向外偏移。

  • 桶形畸变:图像边缘向外凸出,像桶一样。常见于广角镜头。
  • 枕形畸变:图像边缘向内凹陷。常见于长焦镜头。

数学模型(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^2 = x^2 + y^2,是归一化坐标到光心的距离。

避坑指南:我曾经用过一个廉价镜头,k1 达到 -0.35,边缘畸变超过15个像素。如果不校正,在图像边缘做测量,误差能到毫米级。所以,做高精度测量时,一定要用低畸变镜头,或者做完整的畸变校正。

3.4.2 切向畸变

镜头和传感器不平行时产生。说白了,就是镜头装歪了。

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 是切向畸变系数。

切向畸变在工业相机中比较少见,因为镜头座都是精密加工的。但我在手机摄像头项目里遇到过——手机镜头模组组装时,胶水固化不均匀,导致传感器倾斜,切向畸变系数 p1 达到 0.002。虽然看着不大,但在图像边缘能产生2-3个像素的偏移。

3.5 完整畸变模型:五参数模型

实际标定时,我们通常用5个畸变参数:[k1, k2, p1, p2, k3]。k3 只在畸变特别严重时才用,比如鱼眼镜头。

参数 范围 说明
k1 -0.5 ~ 0.5 主要径向畸变,绝对值越大畸变越严重
k2 -0.2 ~ 0.2 高阶径向畸变,通常比k1小一个数量级
p1, p2 -0.01 ~ 0.01 切向畸变,好的镜头接近0
k3 -0.1 ~ 0.1 更高阶径向畸变,非必要不用

3.6 知识体系总览

下面这张图把整个相机成像模型串起来了。你想想看,从世界坐标到像素坐标,每一步都有明确的数学对应。

相机成像模型知识体系 世界坐标 (X, Y, Z) 外参 [R|t] 相机坐标 (Xc, Yc, Zc) 除以 Zc 归一化平面 (x, y) 畸变模型 畸变校正 径向: k1, k2, k3 切向: p1, p2 内参 K 像素坐标 (u, v) 关键概念 • 内参:相机固有属性 • 外参:相机位姿 • 畸变:镜头物理缺陷 • 标定:求解以上参数 应用场景 • 三维重建 • 视觉测量 • 机器人导航 世界 → 相机 → 归一化 → 像素 完整成像链路

3.7 标定流程:从理论到实践

理论讲完了,怎么拿到这些参数?我一般走这四步:

  1. 采集标定板图像:至少15-20张,覆盖不同角度和位置
  2. 提取角点:用OpenCV的 findChessboardCorners 或 findCirclesGrid
  3. 求解参数:用 calibrateCamera 函数,得到内参、外参、畸变系数
  4. 验证精度:重投影误差小于0.5像素才算合格

我的习惯:标定完成后,我会拍一张棋盘格放在图像中心,再拍一张放在边缘。分别计算角点坐标的理论值和实际值,看看误差分布。如果边缘误差比中心大很多,说明畸变模型没拟合好,需要增加标定板在边缘位置的图像。

3.8 常见问题与避坑

  • 标定板不平:打印的棋盘格贴在玻璃板上,不要贴纸板上。纸板会弯曲。
  • 图像太少:少于10张标定结果不稳定。我一般拍25张。
  • 忽略切向畸变:大部分工业镜头切向畸变很小,但手机摄像头必须考虑。
  • 焦距单位搞混:fx = f / dx,其中 f 是物理焦距(mm),dx 是像素尺寸(mm/pixel)。

嗯,相机成像模型就讲到这里。这套东西我用了十年,从最初的死记硬背到现在的条件反射,中间踩过不少坑。希望你能一次搞明白,少走弯路。