3、目标检测基础:基于传统方法的障碍物检测(背景建模、光流法),基于深度学习的检测概览

3.1 传统方法:为什么还要学它?

说实话,现在做自动驾驶感知,大家一上来就谈深度学习。但我个人觉得,传统方法就像练武的扎马步——看着土,但底子得打牢。

我在2016年刚入行时,车载芯片算力还很有限。那时候跑个YOLOv1都费劲,帧率只有个位数。怎么办?只能靠传统方法顶上。你想想看,如果连背景建模和光流法都不懂,你很难理解为什么后来深度学习能做得更好。

传统方法的核心思路很简单:找变化。障碍物相对于静止的背景,一定有某种“不一样”。要么是像素值变了,要么是运动轨迹不同了。

3.2 背景建模:从“静态”中找“动态”

背景建模,说白了就是让摄像头记住“路应该长什么样”。然后,一旦出现和记忆不符的东西,那就是障碍物。

3.2.1 帧差法

最朴素的方法。拿当前帧减去上一帧,差值大的地方就是运动区域。

# 帧差法伪代码
def frame_diff(prev_frame, curr_frame, threshold=30):
    diff = cv2.absdiff(prev_frame, curr_frame)
    _, mask = cv2.threshold(diff, threshold, 255, cv2.THRESH_BINARY)
    return mask

嗯,这里要注意:帧差法对光照变化极其敏感。我曾在隧道出口吃过亏——车刚出隧道,光照突变,整个画面都在“动”,算法直接崩了。

3.2.2 混合高斯模型(GMM)

比帧差法聪明一点。它给每个像素点建一个高斯分布模型,描述“这个像素正常情况下应该是什么值”。

举个例子:路面的灰度值通常在120-140之间波动。GMM会记住这个范围。如果突然出现一个灰度值200的像素点,模型就会判定为前景。

关键参数:

  • 学习率α:控制背景更新的速度。α太大,慢速移动的物体会被“融入”背景;α太小,光照变化会导致大量误检。
  • 高斯分量个数K:一般取3-5个。我习惯取3,够用且速度快。

避坑指南:我曾经在雨天的项目中,GMM把雨滴也检测成了障碍物。后来加了形态学滤波(先腐蚀再膨胀),把小雨点过滤掉,效果好了很多。

3.3 光流法:追踪每一个像素的运动

背景建模看的是“像素值变了没”,光流法看的是“像素跑到哪去了”。

光流法的基本假设有两个:

  1. 亮度恒定:同一个点在前后两帧中,亮度不变。
  2. 小运动:物体移动的距离很小,可以用微分近似。

基于这两个假设,我们可以推导出光流基本方程:

Ix * u + Iy * v + It = 0

其中:
Ix, Iy 是图像梯度
It 是时间梯度
(u, v) 是光流向量

一个方程有两个未知数,解不了。所以有了Lucas-Kanade方法——它假设一个局部窗口内所有像素的运动相同,用最小二乘法求解。

3.3.1 稠密光流 vs 稀疏光流

类型 方法 计算量 适用场景
稀疏光流 Lucas-Kanade 低 特征点跟踪(如车辆角点)
稠密光流 Farneback 高 运动分割、障碍物轮廓提取

我个人在实际项目中,更常用稀疏光流。为什么?因为稠密光流虽然信息丰富,但计算量太大,在嵌入式平台上跑不动。我一般用Shi-Tomasi角点检测提取特征点,然后用LK光流跟踪这些点。

注意:光流法在纹理稀疏的区域(比如大片白色墙面)会失效。因为没有足够的梯度信息,光流方程解不出来。这时候需要结合其他传感器(如激光雷达)做补充。

3.4 传统方法的局限性

做了几年传统方法,我最大的感受是:它太“脆”了。

  • 光照变化、阴影、雨雪天气,都会导致大量误检
  • 无法区分“运动的树”和“运动的行人”——都是像素在动,但语义完全不同
  • 参数调优全靠经验,换个场景就得重新调

所以,当深度学习在2015年左右开始爆发时,整个行业都在往这个方向转。但别急着否定传统方法——在算力受限、场景简单的条件下,它依然有实用价值。

3.5 深度学习检测概览:从“找变化”到“理解内容”

深度学习的思路完全不同。它不再问“哪里变了”,而是问“这是什么”。

一个典型的深度学习目标检测流程分三步:

  1. 特征提取:用卷积神经网络(CNN)从图像中提取高维特征
  2. 区域提议:找出可能包含物体的区域(候选框)
  3. 分类+回归:判断候选框里是什么,并微调框的位置

3.5.1 两阶段检测器:Faster R-CNN

先提候选区域,再分类。精度高,但速度慢。

我记得第一次在自动驾驶数据集上跑Faster R-CNN,mAP确实高,但帧率只有5 FPS。车都开出去50米了,它还没检测完上一帧。

3.5.2 单阶段检测器:YOLO系列

一步到位,直接回归出类别和位置。速度快,但小目标检测效果差一些。

YOLOv3是我用得最多的版本。它在速度和精度之间取得了很好的平衡。后来出的v4、v5、v8,各有改进,但核心思想没变——把检测当成回归问题来做。

3.5.3 基于Transformer的检测器:DETR

最近两年火起来的。把目标检测当成“集合预测”问题,用Transformer的注意力机制来建模物体之间的关系。

说实话,DETR在自动驾驶场景下还没大规模落地。主要问题是训练收敛慢,而且对小目标不友好。但我觉得这是个方向,值得关注。

3.6 本章小结

传统方法和深度学习,不是非此即彼的关系。我现在的做法是:

  • 用传统方法做快速预处理(比如运动区域提取)
  • 用深度学习做精确分类和定位
  • 两者结合,取长补短

下一节,我们会深入讲深度学习的网络结构设计。但在此之前,我建议你把背景建模和光流法的代码亲手跑一遍。只有踩过传统方法的坑,你才能真正理解深度学习为什么“香”。

目标检测方法演进 传统方法 背景建模 帧差法 | 混合高斯模型(GMM) 光流法 稀疏光流(LK) | 稠密光流(Farneback) 局限性:光照敏感、缺乏语义理解 参数调优困难、场景泛化差 深度学习方法 两阶段检测器 Faster R-CNN → 高精度、低速度 单阶段检测器 YOLO系列 → 高速度、低精度 Transformer检测器:DETR 注意力机制、集合预测 传统方法做预处理 + 深度学习做精确检测 = 最佳实践

我的建议:初学者不要一上来就调YOLO。先花一周时间,把OpenCV里的背景建模和光流法demo跑通。你会发现,很多深度学习里的概念(如特征图、感受野)其实在传统方法里就有雏形。

可可精品资料库