博客算法工具链征程6上的多目标跟踪(MOT):DeepSORT+JDE部署与BPU调度

征程6上的多目标跟踪(MOT):DeepSORT+JDE部署与BPU调度

默认265282026-08-30
45
0

检测做得再好,没有跟踪也做不成自动驾驶。多目标跟踪(MOT)负责把每帧的检测框关联成连续的轨迹,输出"这辆车从哪来、到哪去"。我在一个城市NOA项目里把DeepSORT+JDE部署到征程6M上,BPU跑检测,CPU跑跟踪,两者协同调度有不少门道。这篇把完整部署经验记下来。

一、DeepSORT+JDE架构

我们的跟踪方案:

1. 检测器:YOLOv5m(BPU运行),每帧输出检测框

2. 外观特征提取:JDE(Joint Detection and Embedding)的reid分支(BPU运行),输出每个目标的128维外观特征

3. 跟踪器:DeepSORT的级联匹配(CPU运行),做运动匹配+外观匹配

4. 轨迹管理:卡尔曼滤波预测、轨迹初始化/确认/删除逻辑

二、BPU+CPU协同调度

征程6M有2个BPU core和4个ARM core。调度策略:

```

Frame N:

BPU Core 0: 跑检测(YOLOv5m)

BPU Core 1: 跑ReID(JDE分支)

ARM Core 0-3: 跑DeepSORT跟踪逻辑

Frame N+1:

BPU Core 0: 跑检测(下一帧)

BPU Core 1: 跑ReID(下一帧)

ARM Core 0-3: 跑DeepSORT(当前帧的跟踪)

```

检测和ReID并行跑,跟踪在CPU上异步跑,最大化硬件利用率。

踩坑记录1:BPU core争抢

一开始检测和ReID都用同一个BPU core,因为两个模型的输入不一样(检测用整帧图像,ReID用裁剪的目标区域),工具链的model_group无法把它们绑定到不同core。

解决方案:

分别编译两个hbm,板端代码里手动指定每个模型用的core:

```cpp

// 检测模型用core 0

hbDNNInfer(&task_det, model_det, &input_det, 1);

hbDNNSetTaskAttr(task_det, HB_DNN_TASK_ATTR_BPU_CORE, 0);

// ReID模型用core 1

hbDNNInfer(&task_reid, model_reid, &input_reid, 1);

hbDNNSetTaskAttr(task_reid, HB_DNN_TASK_ATTR_BPU_CORE, 1);

```

三、JDE外观特征提取的优化

JDE的reid分支是一个小网络(输入128×64,输出128维特征)。优化要点:

1. 输入尺寸对齐:128×64的通道数要保证是8的倍数。如果backbone输出特征通道是256,没问题;如果是255,需要padding到256。

2. 批量推理:一帧通常有10-30个目标,逐个跑ReID延迟高。可以用batch推理,把多个目标的裁剪图拼成一个batch:

```cpp

// 批量ReID推理

hbDNNTensor_t reid_inputs[batch_size];

for (int i = 0; i < batch_size; i++) {

reid_inputs[i] = crop_tensors[i];

}

hbDNNInfer(&task_reid, model_reid, reid_inputs, batch_size);

```

batch_size建议≤16,超过16内存占用增加明显。

四、DeepSORT跟踪逻辑优化

DeepSORT的级联匹配分为两步:

1. 运动匹配:用卡尔曼滤波预测目标位置,和检测框做IOU匹配

2. 外观匹配:对运动匹配失败的目标,用外观特征做余弦距离匹配

优化策略:

· 卡尔曼滤波降频:如果目标运动缓慢,卡尔曼滤波的预测步可以每2帧做一次,而不是每帧都做。节省CPU时间约30%。

· 级联匹配剪枝:外观匹配时,只和最近5帧的历史特征做匹配,而不是全部历史。节省内存和计算量。

· 轨迹状态机优化:

· Tentative(临时):连续3帧匹配成功 → Confirmed(确认)

· Confirmed:连续30帧未匹配 → Deleted(删除)

· 根据场景调整阈值,拥堵场景可以把删除阈值从30降到15

五、性能表现

在J6M上,城市道路的跟踪性能:

· 检测延迟:约8ms(YOLOv5m,640×640)

· ReID延迟:约2ms(batch=10,128×64)

· 跟踪延迟:约3-5ms(CPU,目标数

· 总延迟:约15ms/帧,帧率65fps

作为对比,纯CPU跑检测+跟踪的方案,帧率只有15-20fps。BPU+CPU协同方案帧率提升3倍以上。

六、踩坑记录

· 坑1:ReID模型的batch_size设太大(如32),BPU推理时内存分配失败。解决:batch_size≤16,或降低ReID输入分辨率到96×48。

· 坑2:DeepSORT的外观匹配在夜间场景效果差(车灯造成外观特征剧烈变化)。解决:夜间模式关闭外观匹配,只用运动匹配;或增加光照不变性的特征提取网络。

· 坑3:跟踪ID跳变(同一目标被分配不同ID)。通常是检测框抖动导致IOU匹配失败。解决:增加检测框的平滑滤波(EMA),或降低IOU匹配阈值。

· 坑4:密集场景(如十字路口)目标数>50,CPU跟踪延迟暴涨到20ms+。解决:用匈牙利算法的近似版本(如贪婪匹配),或做ROI区域划分(只跟踪本车道附近的目标)。

七、顺便提一嘴

· JDE的reid分支可以用更轻量的网络替代(如OSNet),精度持平但参数量只有1/4,BPU延迟更低。

· 如果项目对实时性要求极高,可以用ByteTrack替代DeepSORT。ByteTrack不用外观特征,只用检测框做匹配,跟踪延迟降到1ms以内,但ID切换率比DeepSORT高。

· 征程6P的4个BPU core可以同时跑检测+ReID+其他感知任务,跟踪单独在CPU上做,整个感知pipeline可以跑到100fps+。

数据来源:本文MOT部署方案参考地平线开发者社区官方文档及多任务调度相关技术博客。

算法工具链
社区征文征程6
评论0
0/600