检测告诉你一帧里有什么,跟踪尝试把相邻帧的同一目标关联起来。YOLO 配合 ByteTrack 可以导出临时轨迹 ID,适合检查一段视频中的目标轨迹。ID 不是永久身份,也不是跨视频的人物识别结果。
准备一个容易人工回看的短片
使用自有的 clip.mp4,建议先选十几秒、镜头相对稳定、目标数量不多的片段。在 Python 3.11 独立环境安装 ultralytics。模型首次运行会下载 yolo11n.pt;本文未运行该视频跟踪模型,以下是官方接口的复现示例。

python -m pip install ultralytics
逐帧保存 ID 和框坐标
保存代码为 track_video.py,运行 python track_video.py。stream=True 让结果按帧迭代,避免把长视频的全部结果一次保存在内存中。
import csv
from ultralytics import YOLO
model = YOLO("yolo11n.pt")
with open("tracks.csv", "w", newline="", encoding="utf-8-sig") as f:
writer = csv.writer(f)
writer.writerow(["frame_index", "track_id", "class", "score", "x1", "y1", "x2", "y2"])
results = model.track(source="clip.mp4", tracker="bytetrack.yaml",
stream=True, device="cpu", verbose=False)
for frame_index, result in enumerate(results):
boxes = result.boxes
if boxes is None or boxes.id is None:
continue
for track_id, cls, score, xyxy in zip(boxes.id.cpu().tolist(),
boxes.cls.cpu().tolist(), boxes.conf.cpu().tolist(),
boxes.xyxy.cpu().tolist()):
writer.writerow([frame_index, int(track_id), result.names[int(cls)],
float(score), *xyxy])
print("saved tracks.csv")
CSV 的 frame_index 从零开始,表示这次解码迭代的帧序号,不是精确的毫秒时间戳。需要时间对齐时另用实际视频时间信息,不能把可变帧率视频直接按固定 FPS 硬算。
核对 ID 是否保持、何时会断
回看连续可见的同一目标,对照相邻帧的 track_id 和框位置;再检查遮挡前后是否换 ID,两个目标交叉时是否交换 ID。把这些位置记录下来,作为跟踪失败清单。
某帧没有轨迹 ID 时,脚本不会写入该帧的目标行;空行段不代表场景无人。遮挡、出画面再回来、快速运动和镜头切换都可能破坏关联。
为什么不直接拿 ID 算累计人数
同一个人重新获得 ID 会让去重计数偏大,不同人错误共享 ID 会让结果偏小。要做过线计数,还需明确线的位置、方向、重复经过规则并逐段人工核验。本文只验收轨迹导出,不宣称完成客流统计。
ByteTrack 是本例显式指定的跟踪器,避免把版本默认跟踪器当成固定事实。视频人工标注的 Track 与这里自动关联的模型输出也不同。部署前核对 Ultralytics 授权。
资料与适用范围
本文依据 2026 年 10 月 1 日读取的项目资料编写。安装后请记录实际依赖版本;版本升级时先用小样本核对接口和输出。
Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/30653.html