2、感知模块基础:传感器融合与目标检测
感知模块,说白了就是自动驾驶汽车的「眼睛」和「耳朵」。我刚开始接触这个领域时,总觉得传感器越多越好,恨不得把激光雷达、摄像头、毫米波雷达全堆上去。后来踩过坑才明白——传感器融合不是简单的数据堆砌,而是让它们互相补位、协同工作。
今天我们就来聊聊感知模块的核心:传感器怎么融合?算法流程怎么走?目标检测和跟踪又该怎么调?
2.1 三大传感器的「性格」差异
先说说这三种传感器的脾气。你想想看,它们各有各的长处,也各有各的短板。
| 传感器类型 | 优势 | 劣势 |
|---|---|---|
| 激光雷达(LiDAR) | 测距精准,3D点云数据丰富,不受光照影响 | 成本高,雨雾天气性能下降,无法识别颜色 |
| 摄像头(Camera) | 纹理信息丰富,能识别车道线、交通标志、颜色 | 受光照影响大,测距精度差,单目无法直接获取深度 |
| 毫米波雷达(Radar) | 全天候工作,测速精准,穿透性强 | 角分辨率低,无法识别物体类别,对静止目标不敏感 |
我在项目中遇到过这样的情况:纯用摄像头做感知,傍晚逆光时直接「失明」;纯用激光雷达,遇到大雨天点云稀疏得像筛子。所以,融合是必须的。
2.2 传感器融合的三种层次
传感器融合不是一股脑把数据倒进一个模型里。我个人习惯把它分成三个层次:
- 数据级融合:直接把原始数据拼在一起。比如把激光雷达点云和摄像头图像对齐,生成RGB-D数据。优点是信息损失少,缺点是计算量大,对时间同步要求极高。
- 特征级融合:先各自提取特征,再融合。比如摄像头检测出目标框,激光雷达检测出点云簇,然后做关联匹配。这是目前工业界的主流做法。
- 决策级融合:每个传感器独立输出结果,最后投票或加权。比如摄像头说「前面有车」,雷达说「前面有车」,那就确认有车。优点是鲁棒性好,缺点是信息利用率低。
我的经验之谈:实际工程中,特征级融合用得最多。数据级融合太「重」,决策级融合太「轻」。折中方案往往最实用。
2.3 感知算法流程:从原始数据到目标列表
一个典型的感知流程长什么样?我画个简化的流程图给你看:
原始数据 → 预处理 → 目标检测 → 目标跟踪 → 输出目标列表
↑ ↑ ↑ ↑
传感器 去噪/校准 检测网络 卡尔曼滤波
嗯,这里要注意几个关键点:
- 时间同步:不同传感器的采样频率不同。激光雷达一般是10Hz,摄像头30Hz,雷达20Hz。不做时间同步,融合出来的结果就是「时空错乱」的。
- 空间对齐:每个传感器有自己的坐标系。需要标定出外参矩阵,把点云投影到图像平面,或者把图像特征映射到3D空间。
- 数据预处理:去噪、滤波、ROI裁剪。我见过有人直接拿原始点云跑检测,结果被地面点干扰得不行。
小技巧:做时间同步时,我习惯用「最近邻插值」——以激光雷达的时间戳为基准,找最近的摄像头帧。简单有效,延迟可控。
2.4 目标检测:从2D到3D的跨越
目标检测是感知模块的核心。摄像头做2D检测,激光雷达做3D检测,两者各有千秋。
2D检测(摄像头):
- 常用网络:YOLO系列、Faster R-CNN、CenterNet
- 输出:目标类别、2D边界框(x, y, w, h)
- 难点:小目标检测、遮挡处理、光照变化
3D检测(激光雷达):
- 常用网络:PointPillars、VoxelNet、CenterPoint
- 输出:目标类别、3D边界框(x, y, z, w, l, h, yaw)
- 难点:点云稀疏性、远距离目标、计算效率
我曾经踩过一个坑:直接用2D检测框投影到3D空间来估计距离,结果误差大得离谱。后来改用激光雷达点云做3D检测,精度才上来。
避坑指南:我曾经在雨雾天气测试时,发现激光雷达的3D检测召回率骤降。后来加了毫米波雷达的辅助检测,才把召回率拉回来。记住:没有完美的传感器,只有互补的融合方案。
2.5 目标跟踪:让检测结果「连贯」起来
检测是单帧的,跟踪是时序的。为什么需要跟踪?因为单帧检测会有漏检、误检,跟踪可以平滑轨迹、维持ID一致性。
常用的跟踪框架:
- SORT(Simple Online and Realtime Tracking):基于卡尔曼滤波和匈牙利匹配。简单、快,适合实时场景。
- Deep SORT:在SORT基础上加了外观特征(ReID),能更好地处理遮挡和ID切换。
- AB3DMOT:针对3D点云的跟踪框架,用3D卡尔曼滤波。
我个人习惯用Deep SORT做摄像头跟踪,用AB3DMOT做激光雷达跟踪,最后在决策层做融合。为什么?因为不同传感器的跟踪结果可以互相校验——摄像头跟丢了,雷达可能还锁着。
# 伪代码:简单的卡尔曼滤波跟踪
class KalmanTracker:
def __init__(self, bbox):
self.kf = KalmanFilter(dim_x=7, dim_z=4)
self.kf.F = np.eye(7) # 状态转移矩阵
self.kf.H = np.eye(4, 7) # 观测矩阵
self.kf.P *= 1000 # 初始协方差
self.hits = 0
self.no_losses = 0
def predict(self):
self.kf.predict()
return self.kf.x[:4]
def update(self, bbox):
self.kf.update(bbox)
self.hits += 1
self.no_losses = 0
这段代码看着简单,但实际调参时坑不少。比如卡尔曼滤波的噪声协方差矩阵Q和R,设大了轨迹抖动,设小了跟不上快速移动的目标。我一般先用仿真数据跑一遍,再根据实车数据微调。
2.6 融合策略:什么时候信谁?
传感器融合的核心问题:什么时候该信摄像头?什么时候该信激光雷达?什么时候该信毫米波雷达?
我总结了一个简单的规则:
- 白天、光照好:摄像头为主,激光雷达为辅
- 夜晚、逆光:激光雷达为主,摄像头为辅
- 雨雾天气:毫米波雷达为主,激光雷达为辅
- 高速场景:毫米波雷达测速优势明显,优先用
- 城区场景:摄像头和激光雷达联合检测,毫米波雷达做补充
说白了,就是根据场景动态调整权重。我做过一个简单的置信度加权融合:每个传感器输出一个置信度分数,然后根据当前环境条件调整权重,最后加权平均得到最终结果。
核心原则:传感器融合不是「1+1=2」,而是「1+1>2」。好的融合方案,能让系统在单一传感器失效时依然保持基本功能。
2.7 实战中的调优建议
最后,分享几个我在项目中积累的调优经验:
- 先跑通单传感器,再做融合:别一上来就搞融合。先把摄像头检测调好,再把激光雷达检测调好,最后再考虑怎么融合。否则出了问题你都不知道是哪个环节的锅。
- 重视标定精度:外参标定差1度,50米外的目标就偏了将近1米。我见过有人花了两周调融合算法,最后发现是标定板没放平。
- 做好数据记录:每次路测都记录传感器原始数据、标定参数、算法版本。这样出了问题才能复现、排查。
- 关注延迟:传感器融合的延迟会直接影响控制模块。我一般要求融合输出延迟不超过50ms,否则车辆反应会「慢半拍」。
嗯,感知模块的内容就先聊到这儿。下一章我们会深入聊聊目标检测网络的具体实现和调优技巧。有什么问题,欢迎随时交流。