DeepSORT 改进点
改进一:IOU 匹配容忍丢失帧数(–iou-match-tolerance)
1. 源码位置
文件:deep_sort/sort/tracker.py, 函数:_match
# Associate remaining tracks together with unconfirmed tracks using IOU.iou_track_candidates=unconfirmed_tracks+[kforkinunmatched_tracks_aifself.tracks[k].time_since_update==1]unmatched_tracks_a=[kforkinunmatched_tracks_aifself.tracks[k].time_since_update!=1]matches_b,unmatched_tracks_b,unmatched_detections=\ linear_assignment.min_cost_matching(iou_matching.iou_cost,self.max_iou_distance,self.tracks,detections,iou_track_candidates,unmatched_detections)原版只允许刚丢失 1 帧(time_since_update == 1)的轨迹进入 IoU 营救轮。
2. 改进代码
文件:deep_sort/sort/tracker.py, 函数:_match
iou_track_candidates=unconfirmed_tracks+[kforkinunmatched_tracks_aifself.tracks[k].time_since_update<=self.iou_match_tolerance]unmatched_tracks_a=[kforkinunmatched_tracks_aifself.tracks[k].time_since_update>self.iou_match_tolerance]matches_b,unmatched_tracks_b,unmatched_detections=\ linear_assignment.min_cost_matching(iou_matching.iou_cost,self.max_iou_distance,self.tracks,detections,iou_track_candidates,unmatched_detections,iou_match_tolerance=self.iou_match_tolerance)文件:deep_sort/sort/iou_matching.py, 函数:iou_cost(配套添加)
forrow,track_idxinenumerate(track_indices):iftracks[track_idx].time_since_update>iou_match_tolerance:cost_matrix[row,:]=linear_assignment.INFTY_COSTcontinue== 1改为<= iou_match_tolerance(默认 3),并在 iou_cost 内把超过容忍值的轨迹代价置 INFTY(防止 tentative 轨绕过候选过滤)。
3. 测试视频与结果对比
测试视频:video/dense.mp4(1280×720,29.97fps,394 帧,帧间隔 5,共 78 个处理帧)。
改进组: python .\test\test_deepsort.py --frame-interval=5 --iou-match-tolerance=3 基线组: python .\test\test_deepsort.py --frame-interval=5 --iou-match-tolerance=1两组除该参数外完全一致(其余均用默认值),基线组即原版行为。
| 指标 | 改进(3) | 原版(1) |
|---|---|---|
| 轨迹总 ID | 76 | 92 |
| 从未确认轨迹(❤️ 次命中) | 15 | 28 |
| 平均轨迹长度(次) | 16.9 | 14.0 |
| 长轨迹(≥10 次) | 44 | 43 |
| 2~3 处理帧空窗保住同 ID | 28 处 | 11 处 |
4. 对比分析意义
丢失 2~3 帧的轨迹在外观级联失败后,原版只能断裂成两个 ID(检测重新出现时新建轨迹),改进后可凭纯几何 IoU 续接。本视频上少产生 16 个碎片 ID、13 条废轨迹,17 处短空窗保住 ID。是正向改进,三个参数中效果最大。
改进二:确认阶段容忍丢失帧数(–tentative-tolerance)
1. 源码位置
文件:deep_sort/sort/track.py, 函数:mark_missed
defmark_missed(self):ifself.state==TrackState.Tentative:self.state=TrackState.Deletedelifself.time_since_update>self._max_age:self.state=TrackState.Deleted原版 tentative(未确认)轨迹一次丢失直接删除,没有任何容忍判断。
2. 改进代码
文件:deep_sort/sort/track.py, 函数:mark_missed
defmark_missed(self):ifself.state==TrackState.Tentative:ifself.time_since_update>self._tentative_tolerance:self.state=TrackState.Deletedelifself.time_since_update>self._max_age:self.state=TrackState.Deleted添加time_since_update > tentative_tolerance判断(默认 3),未确认轨迹可容忍短暂漏检不死。
3. 测试视频与结果对比
测试视频:video/dense.mp4(同上)。
改进组: python .\test\test_deepsort.py --frame-interval=5 --tentative-tolerance=3 基线组: python .\test\test_deepsort.py --frame-interval=5 --tentative-tolerance=0两组除该参数外完全一致(其余均用默认值),基线组即原版行为。
| 指标 | 改进(3) | 原版(0) |
|---|---|---|
| 轨迹总 ID | 76 | 85 |
| 从未确认轨迹 | 15 | 24 |
| 平均轨迹长度(次) | 16.9 | 15.2 |
| 长轨迹(≥10 次) | 44 | 43 |
4. 对比分析意义
tentative 轨迹需要连续 3 次命中才能确认;原版丢一帧即删,导致“2 命中 + 短暂漏检”的目标被拆成两个 ID 且碎片永远无法上屏。改进后这类目标保住 ID、更早确认上屏,轨迹总 ID 从 85 降到 76。是正向改进,效果次于改进一。
改进三:轨迹输出允许的最大丢失帧数(–max-output-age)
1. 源码位置
文件:deep_sort/deep_sort.py, 函数:update
fortrackinself.tracker.tracks:ifnottrack.is_confirmed()ortrack.time_since_update>1:continue原版输出门控固定time_since_update > 1跳过,即只允许丢失后1 帧惯性输出。
2. 改进代码
文件:deep_sort/deep_sort.py, 函数:update
fortrackinself.tracker.tracks:ifnottrack.is_confirmed()ortrack.time_since_update>self.max_output_age:continue固定值 1 替换为max_output_age(默认 3),丢失后最多 3 帧继续输出卡尔曼预测框。
3. 测试视频与结果对比
测试视频:video/dense.mp4(同上)。
改进组: python .\test\test_deepsort.py --frame-interval=5 --max-output-age=3 基线组: python .\test\test_deepsort.py --frame-interval=5 --max-output-age=1| 指标 | 改进(3) | 原版(1) |
|---|---|---|
| 匹配/轨迹结果(txt 正文) | 完全一致 | 完全一致 |
| 确认轨迹匹配输出框 | 1147 | 1147 |
| 惯性输出框(卡尔曼预测) | 182 | 75 |
4. 对比分析意义
该参数只作用于输出组装,不参与预测/匹配/轨迹生命周期,是纯输出层参数——两份 txt 正文逐字节一致即为证明。改进后多 107 个惯性预测框,短暂遮挡时画面框不闪断;代价是目标真正离开后“幽灵框”最多多显示 2 个处理帧。达到设计目的,正向改进。
3个参数改进的总结
| 改进参数 | 原版行为 | 改进默认值 | 核心收益 | 判定 |
|---|---|---|---|---|
--iou-match-tolerance | 仅丢失 1 帧的轨迹进 IoU 轮 | 3 | 少 16 碎片 ID、17 处空窗续接 | 正向,效果最大 |
--tentative-tolerance | tentative 丢 1 帧即删 | 3 | 少 9 碎片 ID、更早确认上屏 | 正向 |
--max-output-age | 只允许 1 帧惯性输出 | 3 | 多 107 惯性框填平显示空窗 | 正向,纯输出层 |
三个改进全部有效且方向正确。注意改进一与改进二的效果部分重叠:tentative 阶段的检测空窗需要“活着(tentative 容忍)+ 匹配上(IoU 容忍)”两道闸门同时打开才能救回,收益不能简单相加。局限:验证基于单一场景(dense.mp4 车流),参数值 3 的最优性未做扫描。
| 描述 | 链接 |
|---|---|
| 项目 | 基于 Ultralytics + DeepSORT 多目标跟踪与改进 |
| 往期回顾 | 链接 |
| 数据集 | 数据集汇总 |
| 软件开发 | 深度学习软件开发汇总 |