4、相机模型与内参:针孔模型详解、畸变模型(径向与切向)、内参矩阵的数学含义

聊到相机标定,绕不开的就是相机模型。说白了,相机模型就是描述「三维世界里的点,是怎么跑到二维图像上」的一套数学规则。我刚开始接触视觉时,觉得这东西太抽象,直到有一次项目里标定结果总是不对,回头一查,才发现是对内参的理解出了偏差。嗯,今天咱们就把这块彻底捋清楚。

4.1 针孔模型:最朴素的成像原理

针孔模型是最基础的相机模型。你想象一个暗箱,前面戳一个小孔,光线穿过小孔,在后面的感光面上成像。这就是针孔模型的物理原型。

数学上,它描述的是这样一个关系:

  • 世界坐标系中的一点 P(X, Y, Z)
  • 经过小孔投影到图像平面上的点 p(u, v)
  • 两者之间满足相似三角形关系

公式长这样:

u = f * (X / Z) + u0
v = f * (Y / Z) + v0

其中 f 是焦距,(u0, v0) 是主点坐标(光轴与图像平面的交点)。

我的经验: 实际项目中,主点并不在图像正中心。因为镜头安装有偏差,传感器也有偏移。我见过有人直接拿图像中心当主点,结果标定误差大了好几个像素。

4.2 畸变模型:现实世界没有完美镜头

针孔模型是理想情况。现实中的镜头有畸变,光线不走直线。畸变主要分两类:径向畸变和切向畸变。

4.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)

其中 r 是像素到主点的距离,k1, k2, k3 是径向畸变系数。

避坑指南: 我曾经在一个项目中只用了 k1 和 k2,结果边缘区域始终对不准。后来发现镜头畸变很大,必须加上 k3 才能收敛。建议标定时至少用 3 个径向系数,除非你确定镜头畸变很小。

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

我个人习惯,标定时把 5 个畸变系数(k1, k2, k3, p1, p2)全开。如果某个系数标出来接近零,再考虑去掉它。别一开始就偷懒。

4.3 内参矩阵:把物理量翻译成像素

内参矩阵是相机内部参数的数学封装。它把相机坐标系下的三维点,映射到像素坐标系下的二维点。矩阵形式:

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

各参数含义:

参数 含义 单位
fx x 方向焦距(像素单位) pixel
fy y 方向焦距(像素单位) pixel
cx 主点 x 坐标 pixel
cy 主点 y 坐标 pixel

你想想看,fx 和 fy 为什么可能不一样?因为传感器像素不一定是正方形。有些工业相机,像素是矩形的,所以两个方向的焦距就不同。

核心理解: 内参矩阵的本质,是把「毫米/米」这样的物理长度,翻译成「像素」这样的图像坐标。没有这个翻译,你就没法把三维空间和二维图像对应起来。

4.4 完整投影流程:从世界点到像素点

一个三维点最终变成图像上的像素,经历了四步变换:

  1. 世界坐标系 → 相机坐标系(外参矩阵,旋转+平移)
  2. 相机坐标系 → 归一化平面(除以 Z,得到归一化坐标)
  3. 畸变修正(径向+切向)
  4. 归一化平面 → 像素坐标系(内参矩阵)

这四步缺一不可。我见过有人跳过畸变修正,直接拿针孔模型去算,结果标定出来的内参全是错的。

下面这张图,把整个流程串起来了:

相机成像完整流程 相机成像完整流程:从世界点到像素点 世界坐标系 (Xw, Yw, Zw) 外参 相机坐标系 (Xc, Yc, Zc) 除以Z 归一化平面 (x, y) 畸变修正 畸变修正 径向+切向 内参 像素坐标系 (u, v) 关键点 畸变修正在归一化平面进行 内参矩阵完成最后一步映射

4.5 HALCON 中的内参与畸变参数

在 HALCON 里,标定完成后,内参和畸变参数都存放在相机句柄中。你可以用 get_calib_data 把它们取出来。

HALCON 的相机参数顺序是固定的:

* 相机参数列表(顺序固定)
* [焦距, k1, k2, k3, p1, p2, cx, cy, 图像宽, 图像高]
CameraParam := [0.008, -1000, 2000, 0, 0, 0, 640, 512, 1280, 1024]

注意:HALCON 里的焦距单位是米,不是像素。它内部会自动结合像素尺寸换算成 fx、fy。

我的习惯: 标定完成后,我第一件事就是打印出畸变系数,看看 k1 的值。如果 k1 大于 0.1,说明镜头畸变比较明显,后续测量时要特别注意边缘区域。

4.6 内参矩阵的几何意义

内参矩阵不只是几个数字。它描述了相机的内部几何:

  • fx, fy:决定了物体在图像上的缩放比例。焦距越大,物体看起来越大。
  • cx, cy:决定了图像坐标系的原点偏移。如果标定出来的 cx 偏离图像中心很多,说明镜头安装有偏心。
  • fx/fy 比值:如果这个比值不等于 1,说明像素不是正方形。这在一些工业相机中很常见。

举个例子,假设你标定得到:

fx = 1200, fy = 1200, cx = 640, cy = 512

这意味着:

  • 焦距在像素单位下是 1200
  • 主点在 (640, 512),接近图像中心
  • 像素是正方形的(fx == fy)

如果标定出来 fx = 1200, fy = 1195,别慌。这可能是标定板没放平,或者标定图片不够多。我一般会重新标定一次,看看两次结果是否一致。

避坑指南: 我曾经遇到一个项目,标定出来的 fx 和 fy 差了 5%。一开始以为是相机问题,后来发现是标定板打印精度不够,棋盘格尺寸有误差。换了一块高精度标定板,结果就正常了。标定板的精度,直接影响内参的准确性。

4.7 小结

相机模型和内参,是标定的核心。针孔模型给了我们理想情况下的映射关系,畸变模型修正了现实镜头的缺陷,内参矩阵则把这一切翻译成像素坐标。理解这三者的关系,你就能看懂标定结果,也能在出问题时快速定位。