如果让刚接触自动驾驶的人猜哪类目标最难识别,十有八九会说是“移动的、速度快的东西”。真实情况恰恰相反。过去几年公开报道过的自动驾驶测试事故,观察下来大多指向同一个画面:车直直撞上了停在主车道上的事故车、施工设备,或者一片根本算不上“车”的散落物。静止的东西,恰恰是感知系统最典型的盲区,也是我从做感知工程以来被问得最多的一个问题。这篇文章不打算泛泛讲“自动驾驶怎么识别物体”,而是把“为什么静止目标最难”真正拆开——从传感器的物理限制、检测算法的设计惯性、训练数据分布的偏差,再到多传感器融合里的逻辑取舍,尽量讲透。读完你至少能回答一个问题:为什么一辆120km/h的测试车能躲开横穿的行人,却撞上一辆停在路中间打着双闪的事故车。
1. 传感器底层机制:静止目标在感知链路上的“先天失明”
先说结论:三种主流传感器——摄像头、毫米波雷达、激光雷达——各有各的问题,但加在一起,对静止目标仍然存在系统性缺陷。这个缺陷不是某一个传感器的精度不够,而是它们从物理原理上就对“静止”这件事不友好。要理解后面的所有问题,得先从传感器看懂这个世界的方式说起。
1.1 毫米波雷达的多普勒盲区:速度为零等于不存在
毫米波雷达测速度靠的是多普勒效应:目标朝雷达靠近时,反射波频率变高,远离时变低,频率变化量跟相对速度成正比。运动目标因此有“速度签名”,而静止目标的速度签名是零。雷达信号处理里有个常规操作叫动目标显示,把多普勒频移接近零的回波当成杂波抑制掉,因为地面、护栏、灯杆、桥墩全都在这个类别里。
这套思路最早来自防空雷达,目的是从复杂地物回波里找出飞行的目标,用在车载场景却埋下了隐患:停在路中间的事故车,对雷达来说和桥墩没有本质区别。部分前向雷达会用恒虚警率(CFAR)检测器把静态强回波保留下来,但接下来的问题是区分——它到底是可通行的路侧护栏,还是必须避让的障碍物?传统雷达只有几十厘米到米级的角分辨率,距离和角度信息都不足以回答这个问题。
还有一个工程细节常被忽略:很多雷达目标跟踪模块会直接在速度维上做门控,多普勒速度的绝对值低于某个阈值(比如0.5m/s)就认为“不是动态目标”,直接不输出。这个阈值防的是把路牌和铁桥误报成障碍物引发幽灵刹停,代价就是把真正的静止车辆也一并丢掉了。我在实际调参时对这个阈值的感受特别深:调小了,高速上碰到龙门架就急刹;调大了,静止事故车在雷达眼里彻底消失。两头都是事故。
1.2 激光雷达点云里“静止”和“噪声”的模糊边界
激光雷达在物理上对动静一视同仁,它发出去的光脉冲不管照到停着的车还是跑着的车都会有回波。问题出在数据处理环节,尤其是地面分割。感知pipeline第一步通常是把地面点滤掉,只保留障碍物点。地面分割算法(比如射线法、平面拟合、Patchwork这类)在处理低矮物时会翻车——竖着的锥桶可能没问题,但一个掉在路面上的轮胎、一个斜躺的杆件,或者一辆底盘特别低的车,很容易被当成地面点抹掉。
另一个问题是远距离点数稀疏。一辆车在100米外,对16线激光雷达来说可能只有十几个点甚至更少。稀疏点云做聚类时本来就抖,再做分类器(现在多是PointPillars、CenterPoint这类),特征不够,置信度自然低。动态目标还有个优势:它在连续帧里位置变化明显,可以在关联阶段用多帧信息补足单帧特征的不足;静止目标每帧都长一样,反而没有这个“时间积分”的便宜可占。更麻烦的是,静止点云和地面、背景点云混在一起,一旦聚类时把这个目标并进了背景簇,后面就不会再有人提起它。
1.3 摄像头:有外观没有物理量,靠“认脸”吃饭
摄像头是唯一能真正“认出”物体是什么的传感器,但它没有直接的速度概念。单帧图像里,停着的车和正在走的人只是图像,系统只能在连续帧里通过特征匹配去推算运动。这就意味着摄像头对静止目标并无先天优势。更要命的是深度:单目相机对距离的估计是从目标在图像里的位置、尺寸、先验知识反推的,误差随距离急剧放大。一辆静止车在100米外可能只占图像几十个像素,分类置信度和距离估计都会崩。
人眼为什么能轻松分辨路中间的静止车?靠的其实不是“车长什么样”,而是它和周围环境的相对关系:别的车都在动,它在动流场里是静止点;它挡在车道的行驶轨迹上。摄像头单帧算法恰恰没有这些上下文,它只能“看脸”,距离、运动、物理上下文全得靠别的模块补。三种传感器各自的短板,可以压在下面这张表里看:
| 传感器 | 对静止目标感知能力 | 主要受限点 |
|---|---|---|
| 毫米波雷达 | 弱 | 多普勒盲区,无法与桥墩、护栏等环境杂波区分 |
| 激光雷达 | 中等 | 地面分割误删低矮物,远距离点云稀疏 |
| 摄像头 | 中等 | 无直接速度信息,单目深度弱,缺少场景上下文 |
2. 从检测算法看静止目标:网络结构并不天然理解“静止”
传感器拿到原始数据后,算法层的设计惯性也在放大这个问题。早期ADAS的思路和现在的深度学习检测网络之间,其实有一条明显的断层线:前者从根上排斥静止目标,后者虽然理论上不排斥,但工程pipeline里残留的运动偏好,让静止目标始终处于弱势地位。
2.1 两帧差分与运动目标检测的路径依赖
传统视觉感知有经典三件套:帧间差分、光流、背景建模。核心思想都是“变了才算东西”。这种思路从根上就把静止目标推到了感知盲区——镜头里一切不变的东西都被归为背景。很多最早的量产ADAS,前向碰撞预警只对相对速度异常的目标响应,本质上是运动目标检测(MOD)思路。
现代深度学习目标检测已经是单帧的端到端识别,理论上不再依赖运动线索。但工程落地时,大量pipeline仍然保留了“先检测出物体,再用运动属性做验证”的环节。追踪模块尤其如此:卡尔曼滤波器里的状态向量通常包含速度和加速度,关联时用马氏距离做门控。一个静止目标在状态空间里速度为零,如果某帧检测置信度波动导致漏检,这个track很容易被删掉;动态目标因为持续有“运动轨迹”支撑,track生命周期反而长得多。你让一个主力做动态目标追踪的工程师去改静止目标召回,他大概率会先愣一下,因为整套工具链都是为动态设计的。
2.2 锚框、中心点和NMS:静态小目标的系统偏见
检测网络对目标尺寸、位置天然有偏。Anchor-based时代,小目标锚框召回的运气成分居多;CenterPoint这类无锚框范式虽然提升了整体精度,但类别预测头对静态小目标(锥桶、碎片、低矮障碍物)的样本量不足,输出概率仍然不稳定。再加上后处理NMS:如果一个低置信度的静态真值框和一个高置信度的背景误检框重叠,NMS会把低置信度的真值框直接抑制掉。这类问题在单帧推理上几乎无解,只能靠后续的时序和融合模块补救,而正如前面说的,时序和融合模块对静止目标并不友善。
2.3 速度分支与分类器的耦合:类别标签绑架了行为判断
还有个更隐蔽的问题:很多多任务检测头会同时预测类别和速度(相对本车的速度)。这个速度分支的训练目标来自标注中的“瞬时运动状态”,而类别分支的监督来自“语义是什么”。两者耦合之后,模型会学到一种隐含关联——“车”这个类别往往伴随非零速度,“静止”更常和“障碍物”“其他”这类模糊标签绑定。结果就是:同样一辆车,停着的时候模型输出的类别置信度往往比它开着的时候低。这不是玄学,是数据分布的直接投影。我在跑实验时见过很典型的曲线:同一个模型,对“行驶中的轿车”AP能到90以上,对“静止轿车”掉到70不到。类别没变,变的只是运动状态,精度就差出一个量级。
3. 数据分布决定识别上限:静态目标在训练集里的长期弱势
不管传感器和算法怎么设计,模型最终是被数据喂出来的。静态目标难识别的第三个原因,藏在训练数据本身。这部分最容易被忽视,因为它不在代码里、不在网络结构里,却在源头决定了系统能力的上限。
3.1 开源数据集里的静止样本占比
看几大公开数据集——KITTI、nuScenes、Waymo Open Dataset、Argoverse——标注规范各有各的体系,但趋势一致:动态交通参与者的标注密度远高于静止障碍物。原因很简单,数据集的首要任务是支撑“多目标跟踪”和“轨迹预测”评测,这两项都需要动态目标。于是你会发现:路边停的车有框,但路中间的静止障碍物、散落物、作业区设备经常被归到ignore区域或者干脆不标。
更具体一点,nuScenes这类城市数据集里,车辆标注框绝大多数来自行驶中的交通流,静止车辆大量集中在路边泊位;而高速公路上“停在车道正中间”这种真正要命的目标,在公开数据里占比极小。模型没见过,自然认不出。这也是为什么很多感知团队拿公开数据集训出来的模型,一到自己车队回传的高速数据上就露馅。
3.2 标注一致性难题:同一个“静止”在不同人眼里不是一回事
即便是被标出来的静止目标,类别定义也充满争议。一辆停在路肩的车,A标注员标“静止车辆”,B标“停泊车”,C可能因为它旁边站了人就标“其他”。红灯路口排队等灯的车,瞬时速度为零,但它不是“障碍物”,可模型从单帧里根本区分不了“等一下要走的静止”和“永远不走的静止”。标注层面的语义混乱,会让分类器学出一堆矛盾信号。
我参与过数据质检,这类case几乎是每天的争论焦点。标注规范写得再细,也挡不住真实世界的边界情况。最后大家只能妥协:把“是否占用行驶轨迹”作为标注的主要依据,但轨迹是动态的,标出来就已经过时了。这种模糊性直接传导给模型,表现为静止目标检测结果在时间维度上极不稳定。
3.3 类别不均衡制造“看不见的墙”
自动驾驶的感知评价有个核心矛盾:漏报(FN)和误报(FP)要去哪一边。静止障碍物容易引发幽灵刹停(高速上对桥墩、路牌突然急刹),所以量产系统在标定上强烈倾向压FP。压FP最直接的办法是提高检测置信度阈值、加运动门控。这套组合拳下去,模型对那些“长得很像背景的静止真目标”的漏报,几乎无人问责——因为公开评测集里这类样本本来就少。
于是系统对静止目标的召回,就成了那道所有人都知道、但没人愿意先动的墙。做算法的人KPI是公开集上的mAP和NDS,做功能的人KPI是幽灵刹停投诉率,两个数字打架,最后牺牲的必然是没有专门评测指标支撑的静止目标召回。
4. 多传感器融合中的静止目标“惨案”:融合策略如何把本该检测到的目标删掉
单个传感器有短板正常,融合的核心价值就是互补。但具体到静止目标,融合逻辑反而可能放大缺陷。这一节我想还原一条完整的误删链路,你会发现每个环节单独看都合理,串起来却是闭环的盲区。
4.1 融合的优先级与置信度投票机制
主流量产方案是视觉+毫米波雷达的后期融合,L2++以上再加激光雷达。后期融合的基本单位是“track”:每个传感器各自输出目标列表,融合模块再按位置、尺寸、速度做关联和ID管理。关联阶段通常要求多帧一致。静止目标在这个机制里天然吃亏:上一帧检测置信度不高,这一帧刚好被雨滴干扰漏了一次,关联不上的track直接消亡。
动态目标得益于持续运动,坐标变换误差对它的轨迹连续性影响小;静止目标只要有一帧掉链子,后面就没它了。更隐蔽的是置信度投票机制:多个传感器对同一个目标的置信度取加权甚至取最大,雷达对静止目标本身就不输出,等于投票从一开始就少了一票,剩下相机一票,还要扛过阈值和时序关联两道关卡。
4.2 一条完整的误删链路:从雷达过滤到高置信度删除
拿高速前向场景举例,以典型量产融合方案为例:
- 第一步,雷达CFAR检测器把多普勒为零的回波判成静态杂波,事故车没有进入雷达目标列表。常见工程代码长这样:
# 雷达目标速度门控(示意,ADAS工程中常见的静态杂波过滤逻辑) GATE_V = 0.5 # m/s,低于该速度视为静态杂波 def radar_gate(detection): if abs(detection.relative_speed_ms) < GATE_V: return None # 不输出,防止桥墩/路牌误报 return detection- 第二步,进入相机检测:模型检出了车,但距离远、置信度只有0.6,低于融合设定的0.7阈值。
- 第三步,融合模块做交叉验证,要求视觉目标有雷达目标支撑,雷达列表里没有这个目标,于是相机目标因为没有“交叉验证”被丢弃。
- 第四步,规划模块拿到的就是一个干净的前方道路,一切正常,直到撞上。
四个环节里没有一个是“坏了”的,但串起来就是灾难。这种系统性偏见,靠纯调某一个模块参数解决不了,必须有人站在整条链路上做专项治理。
4.3 高精地图先验的双刃剑
L2++系统还会引入高精地图:车道边界、红绿灯位置、路沿都是先验。先验帮系统把静态目标“应该在哪”框定了——路边的车不需要管,车道内的物体才危险。这很大程度降低了误报率,让系统的行为变得更像人:知道哪里能走、哪里不能走。
但副作用同样明显:地图里没有的静止目标(刚落下的树、刚发生的事故车、刚围起来的施工挡板)会被当作“地图外噪声”。静态感知变成先验的忠实执行者,而不是独立观察者。这也是为什么很多量产系统“平时挺好,一遇到地图没更新的路段就露馅”。我在测试里遇到过一次前方100米刚发生追尾、两辆车横在车道上的case,系统直到80米才开始减速,因为它此前完全相信地图里“这里应该是一条畅通车道”。
5. 真实道路上的静止目标误判复盘:三种典型场景
前面讲机制,这一节把机制落到具体场景。以下三类场景出现频率最高,我在工程和测试中也反复看到。每个场景都不是单一原因,而是前面几节提到的传感器、算法、数据、融合问题在不同比例下的组合。
5.1 高速主车道上的静止事故车
高速场景是静止目标误判的重灾区。车距100米以上时,摄像头里事故车的成像高度可能不到20像素,分类器给出的几乎都是低置信度。同时高速AEB的触发阈值通常只覆盖“运动目标”,很多量产法规和NCAP测试场景也只考核相对速度较大的前车切入、前车减速,静止目标测试速度普遍不超过中低速。
把这几件事叠加,结果就是:系统在120km/h下能稳定识别300米外的龙门架(因为它是强反射加高置信语义),却识别不了100米外的事故车。这不是某一个模块能解决的,是传感器分辨率、算法置信度和功能安全标定共同决定的。最讽刺的是,事故车打的双闪灯在夜间反而会造成相机的过曝、眩光,进一步压低检测置信度。越是危险的场景,系统表现越差。
5.2 施工区域的锥桶与路障
施工区是最典型的“语义缺失”场景。锥桶对毫米波雷达来说反射截面太小,回的波弱得跟噪声一样;LiDAR能看到,但上百米外的锥桶点也就几个;摄像头能认出锥桶,但训练集里“施工锥桶”类别本来就少,加上颜色、磨损程度各异,置信度飘忽不定。
更麻烦的是施工区通常伴随改道:规划模块依赖的车道线断了、实时地图没更新,于是系统对“前方有一个需要绕行的障碍物”这个判断迟迟不做。常见的结果是车辆在锥桶前减速到很低,但不知道该不该变道,最后需要驾驶员接管。这类case里感知其实已经“看见了”锥桶,但语义层和规划层没有给足够的响应权重,等于看见了等于没看见。
5.3 路面散落物与异形障碍物
散落物是另一个“不属于任何类别”的难题。掉落的轮胎、木板、纸箱、货物绑带,模型里往往没有对应类别,输出只能是低置信度的“unknown”。规划模块对“unknown”的处理策略大多是“保守但不作为”——不主动撞它,但也不给你做出明确的避让动作。
更麻烦的是,散落物又小又矮时,地面分割和分类器双重失效:LiDAR可能直接把它当路面起伏滤掉,雷达更是几乎无回波。等驾驶员肉眼看到时,制动距离往往已经不够了。这类场景我在测试中见过好几次,每次都是系统的至暗时刻。它不像事故车还有“车辆”类别可以往上面靠,散落物连类别都没有,整套目标检测范式对它就失效。
6. 正在发生的技术修补:从传感器升级到范式转换
说完问题,聊点实际的。业界这几年其实已经在做系统性修补,方向有几个,各有取舍。没有哪一个方案能单独解决全部问题,但组合起来,静止目标的处境确实在改善。
6.1 4D毫米波雷达:让静止目标在速度维之外多一个维度
4D成像雷达在传统距离、速度、方位角之外加了俯仰角,输出点云密度接近低线数LiDAR。它对静止目标的提升在于:有了高度和几何形状,系统可以把“路面上的一个凸起柱状物”和“远处桥墩”区分开。多家供应商的4D雷达方案已经把静止目标检测距离拉到了200米以上。
但它不是银弹——点云仍然稀疏,角分辨率远不如LiDAR,目标分类仍然依赖相机。实际工程里更常见的做法是4D雷达+LiDAR+相机的冗余组合,而不是指望某一颗传感器。我在选型时最大的体会是:4D雷达把“雷达看不见静止目标”这个硬伤治好了,但把“雷达分不清静止目标是什么”这个难题留给了融合层。
6.2 时序融合与占据网络:放弃“认物体”转而“认空间”
一个更根本的转变是从“目标检测”走向“占据感知”。占据网络不再是输出“这里有一辆车,置信度0.8”,而是输出“这个栅格被占了”,直接把空间分成可通行和不可通行。它不需要知道目标是什么类别,只要知道它挡住了路。国内外多家方案的BEV感知都在走这条路。
对静止目标而言这几乎是解药——散落物、锥桶、事故车不再需要精确分类,它们的“不可通行属性”本身就能被规划模块拿到。后融合阶段再把占据栅格和语义类别结合,既保留了“是什么”的信息,又绕开了“先分类再避障”的死胡同。这套范式的代价是算力和标注方式都要重来,但方向我判断是对的。
6.3 静止目标专用数据集与难例挖掘
数据侧的补课同样关键。现在的趋势是:从车队回传的海量clip里做自动难例挖掘,专门挑出“系统漏检的静止目标”帧做标注回流训练;同时在仿真里大规模插入虚拟锥桶、施工区、散落物,做场景增强。这条路比较慢,但很扎实。
我个人的经验是:单纯加静态样本对精度的提升有限,更有效的是把“类别”和“瞬时运动状态”解耦成两个独立head来监督,让模型不再被“车=动态”这层隐含关联绑架。数据标注规范也要改:不要把“静止车辆”和“停泊车辆”混在一个标签里,分开标、分开评测,模型才不会自相矛盾。
6.4 系统层面的兜底:功能安全标定与能力边界
最后说说系统工程层面的兜底。静止目标召回率短期内不可能拉满,所以量产方案普遍用运行设计域(ODD)来兜底:高速场景明确限制对静止目标AEB的速度上限;在有限度自动驾驶里,ODD会排除无地图更新的施工路段。这些限制看着“退步”,其实是用户安全与系统能力之间的合理折中。
做感知的人如果只盯着模型精度,很容易忽略:真正让系统安全的,往往是清晰的能力边界。与其让系统在能力边缘硬撑,不如把边界说清楚,让驾驶员知道什么时候该接管。这个思路在整车失效安全设计里叫“安全退场”,放到静止目标这个难题上,同样适用。
做了这么多年感知,我越来越觉得“静止目标难识别”不是一个单一技术点,而是传感器、算法、数据、系统标定四条线共同作用的结果。每次看到类似的测试事故,我第一反应不是“某个模块不行”,而是“这条链路上有没有一个环节其实在有意无意地抛弃静止目标”。如果你也在做相关方向,建议从数据集里单独拉一版“静态障碍物”的召回率曲线看看,多数情况下你会被结果吓一跳。先把这条曲线盯起来,很多问题才有机会被真正看见。