RF-DETR + ByteTrack 多目标跟踪实战教程:从命令行到 Python 视频轨迹可视化
RF-DETR + ByteTrack 多目标跟踪实战教程:从命令行到 Python 视频轨迹可视化
这篇教程是根据近期学习目标检测、多目标跟踪和视频分析项目的复现过程整理出来的,重点演示如何把 RF-DETR 检测器和 ByteTrack 跟踪器组合起来,对视频中的目标进行连续跟踪,并绘制检测框、轨迹和跟踪 ID。
ByteTrack 和 SORT 一样,都建立在卡尔曼滤波与匈牙利匹配算法的基本框架上,但它的核心改进是数据关联策略:ByteTrack 会尽可能利用几乎所有检测框,而不是简单丢弃低置信度框。它通常先用高置信度检测框匹配已有轨迹,再用低置信度检测框通过 IoU 匹配仍未关联的轨迹。这样可以减少遮挡、弱检测带来的漏跟踪和轨迹断裂,同时保持较高的运行速度。
本文会分别演示两种使用方式:
- 使用
trackers命令行工具快速跑通视频跟踪 - 使用 Python 代码组合 RF-DETR、ByteTrack 和 supervision 标注器
- 在移动镜头场景中加入相机运动补偿,让轨迹显示更稳定

如果你正在系统学习目标检测、多目标跟踪和视频理解任务,可以先收藏本文;配套 notebook、示例视频和后续同系列更新,我会整理成资料包,后面统一放到更方便获取的位置。
📚 文章目录
⚙️ 环境准备
这一部分主要完成 GPU 检查、依赖安装和示例视频下载。视频跟踪任务通常会逐帧运行检测模型,因此建议优先使用 GPU 环境。
🧪 检查 GPU 是否可用
先确认当前环境是否可以访问 GPU。可以使用 nvidia-smi 命令进行检查。如果在 Colab 中遇到 GPU 不可用的问题,可以进入 Runtime -> Change runtime type -> Hardware accelerator,将硬件加速器设置为 GPU,然后点击 Save。
!nvidia-smi
🔧 安装依赖
这里安装 inference-gpu 和 trackers==2.3.0。在 Google Colab 中可能会看到依赖冲突警告,这通常来自 Colab 预装环境,不影响本教程功能。
!pip install -q inference-gpu trackers==2.3.0
🎬 下载示例视频
下面会下载 3 段示例视频,分别用于普通视频跟踪和移动镜头下的轨迹补偿实验。你也可以把路径替换成自己的视频。
!wget -q https://storage.googleapis.com/com-roboflow-marketing/supervision/video-examples/bikes-1280x720-1.mp4
!wget -q https://storage.googleapis.com/com-roboflow-marketing/supervision/video-examples/bikes-1280x720-2.mp4
!wget -q https://storage.googleapis.com/com-roboflow-marketing/supervision/video-examples/skiers-1280x720-5.mp4
💻 方式一:使用 CLI 进行目标跟踪
trackers 库提供了命令行接口(CLI),可以直接对视频运行目标跟踪,不需要先写 Python 代码。对于快速验证模型、调参数或批量处理视频,这种方式很方便。
更多 CLI 参数和配置可以参考 Track from CLI documentation。
SOURCE_VIDEO_PATH = "/content/bikes-1280x720-1.mp4"
TARGET_VIDEO_PATH = "/content/bikes-1280x720-1-result.mp4"
!trackers track \
--source {SOURCE_VIDEO_PATH} \
--output {TARGET_VIDEO_PATH} \
--model rfdetr-medium \
--tracker bytetrack \
--show-trajectories
TARGET_VIDEO_COMPRESSED_PATH = "/content/bikes-1280x720-1-result-compressed.mp4"
!ffmpeg -y -loglevel error -i {TARGET_VIDEO_PATH} -vcodec libx264 -crf 28 {TARGET_VIDEO_COMPRESSED_PATH}
from IPython.display import Video
Video(TARGET_VIDEO_COMPRESSED_PATH, embed=True, width=1080)
🐍 方式二:使用 Python 组合检测器和跟踪器
如果你希望更细粒度地控制检测阈值、NMS、标注样式、轨迹长度或类别过滤,就更适合使用 Python 代码。
🚀 初始化检测器和跟踪器
这里使用 get_model("rfdetr-medium") 加载 RF-DETR Medium 检测模型,并初始化 ByteTrackTracker。
from inference import get_model
from trackers import ByteTrackTracker
model = get_model("rfdetr-medium")
tracker = ByteTrackTracker()
🎨 配置标注器
这里使用 supervision 配置三类标注器:
BoxAnnotator:绘制检测框LabelAnnotator:绘制跟踪 ID 或标签TraceAnnotator:绘制目标运动轨迹
import supervision as sv
color = sv.ColorPalette.from_hex([
"#ffff00", "#ff9b00", "#ff8080", "#ff66b2", "#ff66ff", "#b266ff",
"#9999ff", "#3399ff", "#66ffff", "#33ff99", "#66ff66", "#99ff00"
])
box_annotator = sv.BoxAnnotator(
color=color,
color_lookup=sv.ColorLookup.TRACK)
label_annotator = sv.LabelAnnotator(
color=color,
color_lookup=sv.ColorLookup.TRACK,
text_color=sv.Color.BLACK,
text_scale=0.8)
trace_annotator = sv.TraceAnnotator(
color=color,
color_lookup=sv.ColorLookup.TRACK,
thickness=2,
trace_length=100)
🧩 运行检测和跟踪
这一段是 Python 版本的核心流程:
- 每一帧先用 RF-DETR 做目标检测
- 使用 NMS 去除重叠框
- 将检测结果交给 ByteTrack 更新轨迹
- 在当前帧上绘制检测框、轨迹和跟踪 ID
- 最后用
sv.process_video逐帧处理并生成新视频
CONFIDENCE_THRESHOLD = 0.2
NMS_THRESHOLD = 0.3
SOURCE_VIDEO_PATH = "/content/bikes-1280x720-2.mp4"
TARGET_VIDEO_PATH = "/content/bikes-1280x720-2-result.mp4"
def callback(frame, i):
result = model.infer(frame, confidence=CONFIDENCE_THRESHOLD)[0]
detections = sv.Detections.from_inference(result).with_nms(threshold=NMS_THRESHOLD)
detections = tracker.update(detections)
annotated_image = frame.copy()
annotated_image = box_annotator.annotate(annotated_image, detections)
annotated_image = trace_annotator.annotate(annotated_image, detections)
annotated_image = label_annotator.annotate(annotated_image, detections, detections.tracker_id)
return annotated_image
tracker.reset()
sv.process_video(
source_path=SOURCE_VIDEO_PATH,
target_path=TARGET_VIDEO_PATH,
callback=callback,
show_progress=True,
)
📺 显示 Python 跟踪结果
TARGET_VIDEO_COMPRESSED_PATH = "/content/bikes-1280x720-2-result-compressed.mp4"
!ffmpeg -y -loglevel error -i {TARGET_VIDEO_PATH} -vcodec libx264 -crf 28 {TARGET_VIDEO_COMPRESSED_PATH}
from IPython.display import Video
Video(TARGET_VIDEO_COMPRESSED_PATH, embed=True, width=1080)
🛰️ 相机运动补偿
当视频由移动相机拍摄时,比如无人机、手持设备、滑雪跟拍或车辆行驶画面,目标轨迹可能会因为相机本身的平移或旋转而显得不稳定。相机运动补偿会通过光流估计相机运动,并在绘制轨迹时进行稳定化处理。
这种能力对移动镜头视频尤其重要,因为我们真正关心的是目标自身的运动,而不是相机移动造成的画面偏移。
from inference import get_model
from trackers import ByteTrackTracker, MotionEstimator, MotionAwareTraceAnnotator
PERSON_CLASS_ID = 0
model = get_model("rfdetr-large")
tracker = ByteTrackTracker(minimum_consecutive_frames=3)
motion_estimator = MotionEstimator(
max_points=500,
min_distance=10,
quality_level=0.001,
ransac_reproj_threshold=1.0,
)
color = sv.ColorPalette.from_hex([
"#ffff00", "#ff9b00", "#ff8080", "#ff66b2", "#ff66ff", "#b266ff",
"#9999ff", "#3399ff", "#66ffff", "#33ff99", "#66ff66", "#99ff00"
])
box_annotator = sv.BoxAnnotator(
color=color,
color_lookup=sv.ColorLookup.TRACK)
label_annotator = sv.LabelAnnotator(
color=color,
color_lookup=sv.ColorLookup.TRACK,
text_color=sv.Color.BLACK,
text_scale=0.8)
motion_aware_trace_annotator = MotionAwareTraceAnnotator(
color=color,
color_lookup=sv.ColorLookup.TRACK,
thickness=2,
trace_length=100)
CONFIDENCE_THRESHOLD = 0.2
NMS_THRESHOLD = 0.3
SOURCE_VIDEO_PATH = "/content/skiers-1280x720-5.mp4"
TARGET_VIDEO_PATH = "/content/skiers-1280x720-5-result.mp4"
def callback(frame, i):
coord_transform = motion_estimator.update(frame)
result = model.infer(frame, confidence=CONFIDENCE_THRESHOLD)[0]
detections = sv.Detections.from_inference(result).with_nms(threshold=NMS_THRESHOLD)
detections = detections[detections.class_id == PERSON_CLASS_ID]
detections = tracker.update(detections)
annotated_image = frame.copy()
annotated_image = box_annotator.annotate(annotated_image, detections)
annotated_image = motion_aware_trace_annotator.annotate(
annotated_image, detections, coord_transform=coord_transform)
annotated_image = label_annotator.annotate(annotated_image, detections, detections.tracker_id)
return annotated_image
tracker.reset()
motion_estimator.reset()
motion_aware_trace_annotator.reset()
sv.process_video(
source_path=SOURCE_VIDEO_PATH,
target_path=TARGET_VIDEO_PATH,
callback=callback,
show_progress=True,
)
TARGET_VIDEO_COMPRESSED_PATH = "/content/skiers-1280x720-5-result-compressed.mp4"
!ffmpeg -y -loglevel error -i {TARGET_VIDEO_PATH} -vcodec libx264 -crf 28 {TARGET_VIDEO_COMPRESSED_PATH}
from IPython.display import Video
Video(TARGET_VIDEO_COMPRESSED_PATH, embed=True, width=1080)
📌 小结
这篇教程把 RF-DETR 检测器和 ByteTrack 跟踪器组合起来,分别演示了命令行和 Python 两种用法。对于入门多目标跟踪来说,可以重点理解下面几件事:
- 检测器负责逐帧找出目标框
- 跟踪器负责把不同帧中的同一目标关联起来
- ByteTrack 会利用低置信度检测框来减少轨迹断裂
supervision标注器可以快速绘制检测框、轨迹和跟踪 ID- 移动镜头场景下,相机运动补偿能让轨迹显示更稳定
后续我会继续把类似的目标检测、多目标跟踪、OCR 和图像分割项目整理成系列教程。配套 notebook、示例视频和运行环境说明也会按主题逐步整理出来,适合刚入门计算机视觉和视频分析的同学跟着实践。
📚 同系列教程汇总
- Google Gemini 3.5 Flash 零样本目标检测教程:从提示词到可视化结果
- GLM-OCR 文档识别实战教程:从验证码、公式到车牌 OCR
- RF-DETR + ByteTrack 多目标跟踪实战教程:从命令行到 Python 视频轨迹可视化
- YOLO26 自定义目标检测训练中文教程:待整理
- SAM 3 图像/视频分割中文教程:待整理
更多推荐


所有评论(0)