ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

同一辆车为什么被算几百次?我给 YOLO 加了 ByteTrack 目标跟踪

同一辆车为什么被算几百次?我给 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做真正的行人 / 车流过线计数。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表