1、Occupancy网络基础:什么是Occupancy网络、3D空间表示方法、体素(Voxel)概念、Occupancy网络与BEV感知的区别
1.1 什么是Occupancy网络?
Occupancy网络,说白了就是让自动驾驶车辆学会「猜」——猜某个3D空间位置到底有没有东西。
我刚开始接触这个概念时,觉得它跟语义分割差不多。后来踩了坑才明白,Occupancy网络解决的是一个更本质的问题:在连续的三维空间里,每个点到底是「占据」还是「空闲」。
举个例子。你开车经过一个路口,前方有一辆大货车。传统检测方法会给你一个3D框,告诉你「这里有一辆车」。但Occupancy网络会告诉你更细粒度的信息:这个位置有物体,那个位置是空的,甚至连物体内部的空洞都能感知到。
嗯,这里要注意,Occupancy网络输出的不是「这是什么物体」,而是「这里有没有东西」。它更像是一种空间占用率的估计。
1.2 3D空间表示方法
做自动驾驶感知,绕不开一个问题:怎么用计算机表示我们周围的三维世界?
我个人习惯把3D空间表示方法分成三类:
- 点云表示:用一堆离散的3D点来描述空间。LiDAR数据就是典型。优点是精度高,缺点是数据稀疏、不连续。
- 网格表示:把空间切成一个个小方块(体素),每个方块存信息。Occupancy网络用的就是这种。
- 隐式表示:用一个神经网络直接编码整个场景的几何信息。NeRF就是代表,但实时性差,不适合车端。
我在项目中遇到过一个问题:用点云表示做感知,遇到远距离物体时点太稀疏,根本检测不到。后来换成Occupancy网格表示,虽然分辨率有限,但至少能给出「那个区域可能有东西」的提示。
1.3 体素(Voxel)概念
体素,就是3D版本的像素。你想想看,一张2D图片被切成很多小格子,每个格子叫像素。那3D空间被切成很多小立方体,每个小立方体就叫体素。
体素有几个关键参数:
| 参数 | 说明 | 典型值 |
|---|---|---|
| 分辨率 | 每个体素的边长 | 0.1m ~ 0.5m |
| 感知范围 | X/Y/Z方向覆盖的距离 | 前后60m,左右30m,上下6m |
| 体素数量 | 总共有多少个格子 | 几百万到几千万不等 |
分辨率设得太小,计算量爆炸。设得太大,细节全丢。我曾经试过0.05m的分辨率,结果一张GPU卡跑不动,直接OOM。后来妥协到0.2m,效果还能接受。
1.4 Occupancy网络与BEV感知的区别
这个问题,我面试时经常被问到。很多人搞混这两者,其实它们有本质区别。
BEV感知,全称是Bird's Eye View,鸟瞰视角。它把3D空间投影到2D平面,相当于从天上往下看。你得到的是一个俯视图,每个位置告诉你「这里有什么物体」。
Occupancy网络,保留的是完整的3D信息。它不投影,不压缩,直接在三维空间里做预测。你得到的是一个立体网格,每个体素告诉你「这里有没有东西」。
我打个比方你就明白了:
- BEV感知像是一张地图,告诉你路上哪里有车、哪里有行人。但你看不到高度信息,不知道桥上有没有东西。
- Occupancy网络像是一个3D模型,连头顶的树枝、路边的路沿都能感知到。它不关心是什么,只关心有没有。
实际项目中,我建议这样选:
- 如果只做道路上的车辆、行人检测,BEV就够了,效率高。
- 如果要做复杂场景(地下车库、施工路段、越野环境),Occupancy网络更靠谱。
- 最理想的是两者结合——BEV做目标检测,Occupancy做通用障碍物感知。
BEV感知 = 2D俯视图 + 语义分类(这是什么)
Occupancy网络 = 3D体素网格 + 占用概率(有没有东西)
两者不是替代关系,是互补关系。
我记得有一次做项目,用BEV感知在高速上跑得好好的,一进隧道就抓瞎。隧道里光线暗,视觉BEV效果差。后来加上Occupancy网络,用LiDAR数据做3D占用预测,隧道里的墙、柱子、甚至地上的减速带都能感知到。嗯,从那以后我就再也不敢只用BEV了。