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

说到车道线检测,绕不开的一个基础就是相机成像模型。你想想看,我们看到的图像是二维的,但真实世界是三维的。怎么把三维世界映射到二维图像上?这就是相机模型要解决的问题。

我个人习惯把相机模型拆成三块来理解:针孔模型(理想情况)、内外参矩阵(数学表达)、畸变模型(现实修正)。咱们一个一个来。

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

针孔相机模型,说白了就是小孔成像。光线穿过一个小孔,在后面的感光平面上形成倒立的像。嗯,这里要注意,我们通常把成像平面“虚拟”到小孔前面,这样图像就是正立的,计算起来也方便。

数学上,这个模型可以用一个简单的相似三角形关系来描述:

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

其中 (X, Y, Z) 是三维空间中的点坐标,(u, v) 是图像平面上的像素坐标,f 是焦距。这个公式看着简单,但它是整个相机模型的基石。

核心理解:针孔模型本质上是将三维点通过透视投影映射到二维平面。Z 值越大,物体在图像上越小——这就是“近大远小”的数学表达。

3.2 内参矩阵——从物理坐标到像素坐标

刚才的公式是理想情况。实际相机里,像素不是物理单位,而是离散的格子。而且主点(光轴与成像平面的交点)不一定在图像正中心。这时候就需要内参矩阵了。

内参矩阵 K 长这样:

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

其中 fx, fy 是焦距在 x 和 y 方向上的像素尺度,cx, cy 是主点坐标。这个矩阵把相机坐标系下的三维点映射到像素坐标系。

我在项目中遇到过一个问题:标定出来的 fx 和 fy 相差很大,一开始以为是标定板没放平。后来发现是相机传感器像素不是正方形,导致两个方向的尺度不一致。所以标定完一定要检查 fx/fy 的比值,如果偏离 1 太多,要确认是不是传感器本身的问题。

个人经验:内参矩阵一旦标定好,只要不换镜头、不调焦距,基本是固定的。我建议每次上车采集数据前,先拍几张标定板照片验证一下内参是否漂移。别问我为什么——有一次冬天温差大,镜头热胀冷缩,内参真变了。

3.3 外参矩阵——把世界坐标系转到相机坐标系

内参管的是“相机坐标系 → 像素坐标系”。但三维点通常是在世界坐标系下定义的,比如车道线的经纬度坐标。怎么把世界坐标转到相机坐标?这就是外参矩阵的活。

外参矩阵由旋转矩阵 R 和平移向量 t 组成:

[R | t]

它是一个 3×4 的矩阵,把世界坐标系下的点变换到相机坐标系下。说白了,就是描述相机在世界中的位置和朝向。

举个例子:你车上的摄像头装在挡风玻璃后面,它的外参就是相对于车体坐标系的位置和角度。这个外参一旦装车固定,理论上就不变了。但实际中,车辆颠簸可能导致摄像头松动,外参会慢慢漂移。我曾经遇到过车道线检测突然不准,排查了半天,最后发现是摄像头支架螺丝松了。

避坑指南:外参标定一定要在车辆满载状态下做。空车和满载时,悬架压缩量不同,摄像头高度和俯仰角都会变。我曾经吃过这个亏,标定完空车,满载上路后车道线全偏了。

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

针孔模型是理想情况。实际镜头有畸变,主要是两种:径向畸变和切向畸变。

径向畸变

径向畸变是光线通过镜头边缘时弯曲造成的。表现为图像边缘的直线变弯。分两种:

  • 桶形畸变:图像边缘向外凸出,像木桶一样
  • 枕形畸变:图像边缘向内凹陷,像枕头一样

数学上用多项式来修正:

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。

切向畸变

切向畸变是镜头和成像平面不平行造成的。说白了就是镜头装歪了。修正公式:

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

重要提醒:畸变参数是跟内参一起标定出来的。标定完成后,一定要做畸变校正验证——找一张棋盘格,看看边缘的直线是否变直了。我习惯在校正后的图像上画几条水平线和垂直线,肉眼检查弯曲程度。

3.5 知识体系总览

下面这张图把整个相机成像模型串起来了。从世界坐标到像素坐标,每一步都有对应的矩阵和参数:

相机成像模型:从世界坐标到像素坐标 世界坐标系 (Xw, Yw, Zw) 外参矩阵 [R | t] 相机坐标系 (Xc, Yc, Zc) 针孔投影 (X/Z, Y/Z) 归一化平面 (x, y) 内参矩阵 K 像素坐标系 (u, v) 畸变修正 (k1,k2,p1,p2) 关键参数总结: • 外参矩阵 [R | t]:描述相机在世界中的位置和朝向(6自由度) • 内参矩阵 K:fx, fy, cx, cy(焦距和主点) • 径向畸变:k1, k2, k3(修正镜头弯曲) • 切向畸变:p1, p2(修正镜头安装倾斜) 完整流程:世界坐标 → 外参 → 相机坐标 → 针孔投影 → 归一化坐标 → 畸变修正 → 内参 → 像素坐标

3.6 实际应用中的注意事项

讲完了理论,说说实际中怎么用。在车道线检测项目里,我一般按这个流程走:

  1. 离线标定:用棋盘格标定板,采集20-30张不同角度的图像,用OpenCV的calibrateCamera函数标定出内参和畸变系数
  2. 畸变校正:对每一帧图像做畸变校正,这一步必须在车道线检测之前做。否则弯道线会变成曲线,直道线也会弯曲
  3. 外参标定:用已知尺寸的标定物(比如车道线宽度已知),或者用PnP方法,标定出相机相对于车体的外参
  4. 验证:在校正后的图像上,检查车道线是否笔直,远处的标牌是否变形

我的习惯:标定完成后,我会保存一份标定报告,包含重投影误差(一般要小于0.5像素)、内参矩阵、畸变系数。每次换镜头或调整摄像头位置,都要重新标定。别偷懒,我见过有人用旧标定参数跑了半年,结果换了镜头没重标,车道线检测直接崩了。

好了,相机成像模型就讲到这里。这个模型是后续所有车道线检测算法的基础——无论是基于特征的方法还是基于深度学习的方法,最终都要把图像坐标映射回世界坐标。理解透了这个模型,后面的内容就好办了。

可可精品资料库