3、相机内参标定原理:针孔模型、畸变模型、内参矩阵K的物理意义

聊到相机标定,很多人第一反应就是「棋盘格、角点、张正友」。但说实话,如果你不理解背后的针孔模型和畸变模型,标定出来的参数也就是一堆数字,出了问题根本不知道从哪查起。

我个人习惯,在讲标定流程之前,先花点时间把相机成像的数学模型讲透。你想想看,相机说白了就是一个把三维世界投影到二维平面的装置。这个投影过程,我们用针孔模型来描述。

3.1 针孔模型:理想情况下的成像

针孔模型是最简单的相机模型。它假设光线通过一个小孔,在后面的成像平面上形成倒立的像。为了数学上方便处理,我们通常把成像平面「虚拟」到小孔前面,这样像就是正立的了。

这个模型的核心,就是相似三角形。空间中的一点 P(X, Y, Z),投影到图像上的点 p(u, v),它们之间的关系是:

u = f * X / Z
v = f * Y / Z

这里的 f 是焦距,单位是像素。注意,这个公式是理想情况,没有考虑任何畸变。

核心要点:针孔模型是一个线性模型,它假设光线是直线传播的。但在实际镜头中,光线会因为透镜的物理特性而发生弯曲,这就是畸变。

3.2 畸变模型:现实中的镜头缺陷

我在项目中遇到过很多次,标定出来的内参看起来没问题,但实际测量就是不准。后来发现,是畸变模型没选对,或者畸变参数没优化好。

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

3.2.1 径向畸变

径向畸变是光线在透镜边缘弯曲得更厉害造成的。它沿着镜头半径方向分布,离中心越远,畸变越明显。径向畸变有两种:

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

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

x_corrected = x * (1 + k1 * r^2 + k2 * r^4 + k3 * r^6)
y_corrected = y * (1 + k1 * r^2 + k2 * r^4 + k3 * r^6)

其中 (x, y) 是畸变后的坐标,r 是到光心的距离,k1、k2、k3 是径向畸变系数。对于大多数镜头,k1 和 k2 就够了。k3 通常用于鱼眼镜头这类大畸变镜头。

我的经验:标定时,先只标 k1 和 k2。如果重投影误差还很大,再考虑加 k3。不要一上来就标三个,容易过拟合。

3.2.2 切向畸变

切向畸变是由于镜头和成像平面不平行造成的。说白了,就是镜头装歪了。这种畸变在工业相机中比较常见,尤其是你用手拧镜头的时候。

切向畸变的数学模型:

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

p1 和 p2 是切向畸变系数。

注意:切向畸变通常比径向畸变小一个数量级。如果你发现标定出来的 p1、p2 很大,先检查一下镜头是不是没装正,而不是急着调参数。

3.3 内参矩阵K:把物理世界映射到像素

内参矩阵 K,就是把相机坐标系下的点,映射到像素坐标系下的矩阵。它包含了焦距、主点坐标等信息。

K 矩阵的标准形式:

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

各参数的物理意义:

参数 物理意义 单位
fx, fy 焦距在 x 和 y 方向上的像素值。fx = f / dx,其中 f 是物理焦距,dx 是像素尺寸。 像素
cx, cy 主点坐标,即光轴与成像平面的交点。理想情况下在图像中心。 像素
skew 像素坐标系的倾斜因子。现代相机几乎为 0,通常忽略。 无量纲

你想想看,fx 和 fy 如果不一样,说明像素不是正方形的。这在一些工业相机中很常见,尤其是 CMOS 传感器。

关键理解:内参矩阵 K 把相机坐标系下的归一化坐标 (X/Z, Y/Z, 1) 映射到像素坐标 (u, v, 1)。这个映射是线性的,但前提是去掉了畸变。

3.4 完整成像模型:从世界点到像素

把针孔模型、畸变模型、内参矩阵串起来,完整的成像过程是这样的:

  1. 世界坐标系到相机坐标系:通过外参矩阵 R 和 t 变换。
  2. 相机坐标系到归一化平面:除以 Z,得到归一化坐标 (x, y)。
  3. 加入畸变:用径向和切向畸变模型,对 (x, y) 进行修正。
  4. 内参映射:用 K 矩阵,把修正后的归一化坐标映射到像素坐标。

这个流程,就是相机标定要反推的过程。我们通过已知的棋盘格角点,反推出内参、外参和畸变系数。

下面这张图,把整个成像模型的结构画出来了:

相机成像模型:从世界点到像素 世界点 P(X,Y,Z) 相机坐标系 归一化平面 像素点 p(u,v) 畸变修正 标定过程:已知棋盘格角点的世界坐标和像素坐标,反推内参、外参、畸变系数 核心思想:最小化重投影误差,让模型预测的像素坐标和实际检测到的像素坐标尽可能接近

3.5 标定中的常见坑

我曾经在一个项目中,标定出来的内参 fx 和 fy 差了 5% 以上。一开始以为是传感器问题,后来发现是标定板没放平。你想想看,标定板如果倾斜,角点检测就会引入系统误差。

这里总结几个我踩过的坑:

  • 标定板不平整:打印的棋盘格贴在硬板上,不要贴软板上。我见过有人贴在三合板上,结果受潮变形了。
  • 图像数量不够:至少 15-20 张,覆盖不同角度和位置。不要只拍正对着的。
  • 忽略切向畸变:对于四线扫相机,镜头安装精度通常不高,切向畸变不能忽略。
  • 重投影误差过大:如果重投影误差超过 0.5 像素,检查一下角点检测是否准确,或者标定板是否有污损。

我的建议:标定完成后,一定要做一次验证。用标定好的内参去测量一个已知尺寸的物体,看看误差在不在容忍范围内。这一步很多人会跳过,但我觉得这是最关键的。

3.6 小结

相机内参标定的核心,就是理解针孔模型和畸变模型。针孔模型给出了理想情况下的投影关系,畸变模型修正了实际镜头的缺陷,内参矩阵 K 则把物理坐标映射到像素坐标。

嗯,这部分内容虽然偏理论,但它是后面所有标定流程的基础。你如果能把这三个概念吃透,后面的联合标定、手眼标定,理解起来就会轻松很多。