2. 相机成像模型

相机是怎么把三维世界变成二维图像的?这个问题,我刚开始做图像处理时也琢磨了很久。说白了,成像模型就是一套数学规则,告诉我们光线怎么走、像素怎么来。今天咱们就把针孔模型、透镜模型和坐标系转换这三块彻底讲透。

核心要点:所有镜头畸变校正和色彩校正的算法,都建立在理解成像模型的基础上。模型不对,后面的校正全是白搭。

2.1 针孔模型——最朴素的成像原理

针孔模型是相机成像的"理想状态"。你想想看,一个小孔,光线穿过它,在后面的平面上形成倒像。这就是最原始的相机。

数学上,针孔模型用四个坐标系来描述:世界坐标系、相机坐标系、图像坐标系、像素坐标系。我习惯把它们分成两组来理解:

  • 三维部分:世界坐标系 → 相机坐标系(刚体变换)
  • 二维部分:相机坐标系 → 图像坐标系(透视投影)→ 像素坐标系(离散化)

投影公式很简单:

// 从相机坐标系 (Xc, Yc, Zc) 到图像坐标系 (x, y)
x = f * Xc / Zc
y = f * Yc / Zc

// 其中 f 是焦距,单位是毫米

嗯,这里要注意:针孔模型假设光线是直线传播,没有畸变。但现实中的镜头不是这样的。我在一个手机摄像头项目里就吃过这个亏——直接用针孔模型标定,结果边缘畸变校正得一塌糊涂。

2.2 透镜模型——更接近真实世界

真实镜头用的是透镜组,不是小孔。透镜模型在针孔模型基础上,引入了两个关键修正:

  1. 径向畸变:光线通过透镜边缘时弯曲更厉害,产生"桶形"或"枕形"畸变
  2. 切向畸变:透镜与成像平面不平行,产生"梯形"畸变

我曾经在一个工业检测项目里,用广角镜头拍电路板。边缘的焊点都歪了,算法死活检测不准。后来一查,径向畸变系数 k1 都到 -0.35 了,不校正根本没法用。

畸变模型用多项式表示:

// 径向畸变
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)

// 切向畸变
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]

// 其中 r^2 = x^2 + y^2

我的经验:对于普通手机镜头,用 k1、k2 两个径向畸变参数就够了。k3 和切向畸变参数 p1、p2 通常只在鱼眼镜头或高精度测量时才需要。别一上来就求全,反而容易过拟合。

2.3 坐标系转换——把世界变成像素

坐标系转换是整个成像模型的"粘合剂"。我把它拆成三步走:

步骤 变换 参数 说明
1 世界 → 相机 旋转矩阵 R + 平移向量 t 刚体变换,6个自由度
2 相机 → 图像 焦距 f 透视投影,3D变2D
3 图像 → 像素 主点 (cx, cy) + 像素尺寸 (dx, dy) 离散化,单位从mm变pixel

完整的投影公式写成矩阵形式:

// 齐次坐标形式
s * [u]   [fx  0  cx]   [R11 R12 R13 t1]   [Xw]
    [v] = [ 0 fy cy] * [R21 R22 R23 t2] * [Yw]
    [1]   [ 0  0  1]   [R31 R32 R33 t3]   [Zw]
                                               [1 ]

// 简化写法:s * p_pixel = K * [R|t] * P_world
// K 是内参矩阵,[R|t] 是外参矩阵

避坑指南:我曾经在标定一个双目相机系统时,发现左右相机的内参差异很大。排查了半天,原来是标定板放得太近,导致外参估计不准。记住:标定板距离至少是镜头焦距的20倍以上,否则外参的平移向量会严重偏差。

2.4 知识体系总览

下面这张图把本章的核心逻辑串起来了。我建议你把它当作"地图",后面讲畸变校正和色彩校正时,随时回来对照。

相机成像模型知识体系 针孔模型 透镜模型 坐标系转换 理想投影公式 小孔成像原理 倒像与正像 径向畸变 k1,k2,k3 切向畸变 p1,p2 桶形/枕形畸变 世界→相机(外参) 相机→图像(内参) 图像→像素(离散化) 核心公式:s · p_pixel = K · [R|t] · P_world 内参K + 外参[R|t] + 畸变参数 = 完整相机模型 三个模型层层递进:针孔是理想基础,透镜是现实修正, 坐标系转换是连接三维世界与二维图像的桥梁

2.5 内参与外参——标定的核心

相机标定,说白了就是求内参和外参。我整理了一个对比表,方便你理解:

参数类型 包含内容 物理意义 标定方法
内参 fx, fy, cx, cy, 畸变系数 镜头本身的固有属性 张正友标定法(棋盘格)
外参 R (3x3), t (3x1) 相机在世界坐标系中的位姿 PnP / 直接线性变换

我的习惯:标定内参时,至少拍15-20张不同角度的棋盘格照片。角度要覆盖俯仰、偏航、旋转三个维度。我见过有人只拍5张就标定,结果畸变校正后图像边缘还是弯的——省事一时爽,后面调试火葬场。

2.6 从模型到校正——承上启下

理解了成像模型,畸变校正就变成了一个"反问题":已知畸变后的像素坐标,求它在理想针孔模型下的位置。具体来说:

  1. 用内参把像素坐标反投影到归一化平面
  2. 用畸变模型计算畸变后的坐标
  3. 用内参重新投影回像素坐标
  4. 双线性插值得到校正后的像素值

这个过程,说白了就是"先找到每个像素在理想图像中应该在哪,然后去原图里采样"。我在做实时视频畸变校正时,会把映射关系预先算好存成查找表(LUT),这样每帧只需要查表+插值,速度能快10倍以上。

避坑指南:我曾经在嵌入式平台上做畸变校正,直接逐像素计算映射关系,结果帧率只有5fps。后来改成离线生成LUT,运行时只做查表和插值,帧率直接飙到30fps。记住:能离线算的,别在线算。