同一辆车为什么被算几百次?我给 YOLO 加了 ByteTrack 目标跟踪
项目地址yolo-object-detection-lab:基于 FastAPI 与 Ultralytics YOLO 的图像目标检测实验项目 - AtomGit上一篇我已经把 YOLO 从图片检测扩展到了视频检测。当时视频检测已经可以完成Video Upload → YOLO Detection → Video Progress → Detection Video → Video Summary → JSON Export但做完以后有一个很明显的问题。比如一辆车连续出现在几十甚至几百帧中普通 YOLO 会在每一帧都检测到它。于是统计结果可能变成Car ×100但实际上它可能从头到尾都是同一辆车。所以这一次我继续使用码道 Agent在原来的 YOLO 视频检测项目上加入了YOLO11n ByteTrack让模型不只是知道这一帧有什么还能够进一步判断这一帧里的这辆车和上一帧的是不是同一个目标一、Detection 和 Tracking 到底差在哪普通目标检测的逻辑是Frame 1 → Car Frame 2 → Car Frame 3 → Car Frame 4 → CarYOLO 并不知道这四个 Car 是不是同一辆。因此统计时可能得到Detection Events 4而目标跟踪加入以后会给目标一个持续存在的 ID。例如Frame 1 → Car #7 Frame 2 → Car #7 Frame 3 → Car #7 Frame 4 → Car #7虽然产生了 4 次 Detection Event但真正的唯一目标只有Unique Objects 1这就是这一次加入 ByteTrack 最核心的原因。二、加入第四种模式Tracking现在项目顶部已经有四种模式Single Image Batch Images Video TrackingTracking 模式继续复用之前的视频上传和 metadata 读取能力。我这次测试的视频参数为Resolution: 1920 × 1080 FPS: 29.97 Total Frames: 962 Duration: 32.10 sTracking Settings 中增加了Confidence ThresholdFrame IntervalShow Track TrailsTrail Length这次实际设置为Confidence 0.50 Frame Interval Every Frame Show Track Trails ON Trail Length 30三、ByteTrack 是怎么接进来的这次没有再引入 DeepSORT 或其他新的 Tracking 框架。直接使用 Ultralytics 已经集成的ByteTrack核心思路类似model.track( frame, persistTrue, trackerbytetrack.yaml, confconfidence, devicedevice)其中比较关键的是persistTrue它让 tracker 在连续视频帧之间保留跟踪状态。这样同一个目标在下一帧再次出现时就有机会继续使用原来的track_id例如Car #4 Person #6 Bicycle #15而不是每一帧都当成新的目标。四、Track ID 才是 Unique Count 的基础这次后端会从 ByteTrack 返回结果中读取boxes.id再把它转换成真实的track_id然后维护一个集合unique_track_ids set()每出现一个新的有效 IDunique_track_ids.add(track_id)最终Unique Objects len(unique_track_ids)所以如果Car #7连续出现 200 帧Detection Events 200 Unique Objects 1这就和之前的视频检测统计产生了本质区别。五、真实结果3989 次检测最终只有 37 个唯一目标这次完整处理了962 / 962 Frames Progress: 100%页面最终统计Detection Events: 3989 Unique Objects: 37也就是说YOLO 在视频帧中一共产生了3989 次检测事件但 ByteTrack 根据 Track ID 去重以后真正跟踪到的唯一目标数量是37这就是 Detection 和 Tracking 最直观的区别。六、37 个 Unique Objects 分别是什么Tracking Summary 会按照类别继续统计唯一目标。这次真实结果为ClassUnique ObjectsCar18Person16Bicycle3刚好18 16 3 37这比上一篇单纯看到大量 Detection Event 更容易解释实际场景。以前只能说Car 被检测了很多次。现在可以进一步说ByteTrack 最终关联出了 18 个不同的 Car Track。七、为什么还要保留 Detection Events既然已经有了 Unique Objects是不是 Detection Events 就没用了其实不是。两者代表不同的信息。Detection Events表示所有检测帧中一共出现了多少次目标框它更能反映目标在视频中的持续时间和检测频率。Unique Objects表示基于 ByteTrack Track ID 去重后的目标数量例如Car #7出现 150 帧。那么Detection Events 150 Unique Objects 1所以这次页面同时保留Detection Event Summary Unique Object Summary两种统计而不是用一个数字替代另一个。八、给每个目标画上运动轨迹这次另外加入了一个比较直观的功能Track Trails对于每个 Track ID会根据 Bounding Box 中心点计算cx (x1 x2) / 2 cy (y1 y2) / 2然后保存最近若干个位置。这次设置Trail Length 30也就是每个目标最多保留最近 30 个中心点。最后通过 OpenCV 把这些点连接起来。因此在结果视频中除了Bounding Box Class Track ID Confidence还可以看到黄色的运动轨迹。这比普通 YOLO 的矩形框更容易观察目标到底从哪里移动到哪里。九、Active Tracks 和 Unique Seen 不是一个概念Tracking Progress 中还有两个容易混淆的值Active Tracks Unique Seen比如这次任务结束后页面显示Active Tracks: 0 Unique Seen: 37这并不代表跟踪失败。因为Active Tracks代表的是当前帧仍然活跃的目标数量。任务结束以后最后一帧如果没有活跃目标它自然可能变成 0。而Unique Seen代表整个视频处理过程中累计见过多少个不同 Track ID。所以这次真正要看的累计结果是Unique Seen 37十、Track List 能看到每个目标的生命周期Tracking 模式还增加了一个Track List每个唯一目标都会保存自己的生命周期信息Track ID Class First Frame Last Frame Frames Seen Avg Confidence Max Confidence例如#1 Car Frames: 0 → 79 Seen: 78 Avg Confidence: ... Max Confidence: ...这样就不只是知道“有 18 辆车”还可以进一步查看某一辆车是什么时候第一次出现的持续了多少帧整个跟踪过程中置信度怎么样这已经开始有一点真正视频分析系统的感觉了。十一、新任务必须重置 Tracker做 Tracking 时还有一个需要特别注意的问题Tracker 本身是有状态的。因为 ByteTrack 要记住上一帧有哪些 Track ID所以如果Video A处理完以后直接开始Video B但没有清空 tracker那么第二个任务可能继承第一个视频中的状态。因此这次专门增加了reset_tracker()每一个新的 Tracking Job 开始以前都先把旧 tracker 状态清掉。这样Tracking Job 1和Tracking Job 2就是完全独立的。同时也不会影响原来的普通 Video Detection。十二、导出 Tracking JSON 和 CSV跟踪完成以后现在可以导出两类结果。Export Tracking JSONJSON 会保存Detection Events Unique Objects Unique Class Summary Detection Class Summary Tracks每个 Track 里面还有track_id class_name first_frame last_frame frames_seen avg_confidence max_confidence结构类似{ detection_events: 3989, unique_objects: 37, unique_class_summary: { car: 18, person: 16, bicycle: 3 } }Export Tracks CSVCSV 则是一条 Track 一行。例如track_id,class_name,first_frame,last_frame,frames_seen,... 1,car,0,79,78,... 2,person,0,72,57,...相比把视频每一帧全部导出来这种形式更适合分析一个独立目标的完整生命周期。十三、测试也增加到了 126 个在加入 Tracking 之前整个项目已经有77 passed这次又增加了大量 ByteTrack 相关测试。最终126 passed前端逻辑测试72 assertions passed新增测试主要覆盖tracker resetTrack ID 解析boxes.id is NoneUnique Track 去重同一 ID 多帧只统计一次Detection EventsUnique Class SummaryTrail LengthFirst / Last FrameFrames SeenAvg ConfidenceMax ConfidenceActive TracksTracking JSONTracks CSV新 Job 不继承旧 tracker原 Video / Batch / Single Image 不回归总结这一篇之后项目已经不只是YOLO Detection而是进一步进入了YOLO Detection ↓ ByteTrack ↓ Track ID ↓ Cross-frame Association ↓ Unique Object Count ↓ Trajectory Trail ↓ Track Lifecycle这次真实测试中962 Frames 3989 Detection Events 37 Unique Objects其中Car ×18 Person ×16 Bicycle ×3也就是说之前那些成百上千次重复检测现在终于可以通过 Track ID 关联成真正的独立目标。从这一帧有一辆车变成这是之前那辆 Car #7它现在移动到了这里。这就是从Object Detection到Multi-Object Tracking最直观的一步。项目地址yolo-object-detection-lab:基于 FastAPI 与 Ultralytics YOLO 的图像目标检测实验项目 - AtomGit下一篇就可以继续解决一个更实际的问题既然已经知道每辆车是谁那能不能统计到底有多少辆车真正经过某一条线下一步YOLO ByteTrack Line Crossing做真正的行人 / 车流过线计数。

相关新闻

《计算机是如何工作的:人人都能懂的计算机软硬件工作原理》第 8 章 机器码与汇编语言 阅读笔记 8

《计算机是如何工作的:人人都能懂的计算机软硬件工作原理》第 8 章 机器码与汇编语言 阅读笔记 8

《计算机是如何工作的:人人都能懂的计算机软硬件工作原理》第 8 章 机器码与汇编语言 阅读笔记 8 我们已经介绍了计算机的物理部分:内存、CPU和 I/O 设备。 理解计算机的硬件部分很重要,但是硬件只起一半作用。 计算机的魔力在于软件。 软件把…

2026/10/11 4:32:15 阅读更多 →
游戏化编程学习:CodeCombat如何用即时反馈重塑编程入门体验

游戏化编程学习:CodeCombat如何用即时反馈重塑编程入门体验

编程这个事儿,一开始最吓人的不是语法,而是那种“写完代码却不知道自己到底在干嘛”的虚无感。刷题平台把知识点切成碎片,刷完几十道题,感觉自己是熟练工,但真要写一个活着的东西,立刻抓瞎。后来我接触了 C…

2026/10/11 4:31:15 阅读更多 →
黏菌算法优化PNN光滑因子:分类预测精度提升实战

黏菌算法优化PNN光滑因子:分类预测精度提升实战

做分类预测的同行应该都有过这种体验:模型结构和数据清洗都做得差不多了,但精度就是卡在某个阈值上不去。排查到最后,问题往往出在一个不起眼的超参数上。对于概率神经网络(PNN)来说,这个参数十有八九就是光…

2026/10/11 4:31:15 阅读更多 →

最新新闻

从synchronized到CAS:高并发下的锁优化与实战选型

从synchronized到CAS:高并发下的锁优化与实战选型

前阵子帮一个电商中台团队排查生产问题,现象很典型:每逢整点秒杀流量进来,服务端TPS从2000直接掉到不到500,CPU占用没跑满但接口RT明显上涨,调用链上的热点全部落在一个用synchronized包裹的库存扣减方法上。把线程dum…

2026/10/11 6:06:01 阅读更多 →
微信聊天记录导出教程:用 WeChatMsg 把记录存成 Word、HTML、CSV 三种文档

微信聊天记录导出教程:用 WeChatMsg 把记录存成 Word、HTML、CSV 三种文档

微信聊天记录导出教程:用 WeChatMsg 把记录存成 Word、HTML、CSV 三种文档 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHu…

2026/10/11 6:06:01 阅读更多 →
C语言一维数组详解:从内存原理到冒泡排序与字符串处理

C语言一维数组详解:从内存原理到冒泡排序与字符串处理

1. 一维数组到底在解决什么问题先聊个很实际的场景。你写了一个班级成绩统计程序,要存50个学生的C语言期末成绩。最原始的做法是声明50个变量:score1、score2、score3……光是声明变量就能写到手抽筋,后面的遍历、求和、排序更是噩梦。一维数…

2026/10/11 6:06:01 阅读更多 →
鸿蒙化Flutter工程中clean_coverage覆盖率报告净化实践

鸿蒙化Flutter工程中clean_coverage覆盖率报告净化实践

自从开始把 Flutter 工程往鸿蒙生态迁移,我遇到的一个很现实的坑就是:代码覆盖率报告越来越“好看”,但越来越没人敢信。原因不复杂,flutter test --coverage生成的 lcov.info 默认会把.g.dart、.dart_tool、build 缓存、插件注册…

2026/10/11 6:06:01 阅读更多 →
不是宇宙崩了,是人类知识崩了——从空圈容错视角看物理极限

不是宇宙崩了,是人类知识崩了——从空圈容错视角看物理极限

作者:Liaiyang66 元宝(合著) 交叉互验:豆包、DeepSeek、千问 系列:空圈容错理论跨界推演随笔引子:从时间落差说起 以中国历史为参照,中国文明存在了五千年。但真正让中国走入现代科学文明的&am…

2026/10/11 6:06:01 阅读更多 →
太原网站建设哪家支持二次开发?

太原网站建设哪家支持二次开发?

不少太原企业搭建网站后,都会面临功能升级、系统对接、业务迭代的需求,因此选择支持二次开发的建站服务商至关重要。在太原本地建站机构中,科辉荣盛凭借成熟的技术体系和透明的服务模式,成为企业二次开发建站的优选品牌。深耕太原…

2026/10/11 6:05:00 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →