深入解析 YOLOv10 中的 BYTETracker 与 STrack:多目标跟踪的源码级实现指南

发布时间:2026/9/15 17:18:53
深入解析 YOLOv10 中的 BYTETracker 与 STrack:多目标跟踪的源码级实现指南 深入解析 YOLOv10 中的 BYTETracker 与 STrack多目标跟踪的源码级实现指南【免费下载链接】yolov10YOLOv10: Real-Time End-to-End Object Detection [NeurIPS 2024]项目地址: https://gitcode.com/GitHub_Trending/yo/yolov10导读本文以仓库中的 API 参考文档 docs/en/reference/trackers/byte_tracker.md 为骨架系统剖析 YOLOv10Ultralytics YOLO 生态中多目标跟踪核心模块ultralytics/trackers/byte_tracker.py的实现细节包括基于卡尔曼滤波的单目标跟踪表示类STrack、端到端多目标跟踪器BYTETracker以及与之配套的配置参数、状态机与关联策略。读完本文你将掌握 ByteTrack 两阶段关联算法的完整工作流、每个阈值参数如track_high_thresh、track_low_thresh、match_thresh在源码中的具体作用并能熟练地在检测/分割/姿态任务上启用 ByteTrack 完成视频流跟踪。一、模块定位ByteTrack 在 YOLOv10 跟踪体系中的角色ByteTrack 是 YOLOv10 仓库内置的两种跟踪器之一另一种是 BoT-SORT其注册与调用链如下跟踪器入口定义于 ultralytics/trackers/init.py通过TRACKER_MAP {bytetrack: BYTETracker, botsort: BOTSORT}将配置中的tracker_type映射到对应类ultralytics/trackers/track.py 中的register_tracker通过on_predict_start/on_predict_postprocess_end两个回调把跟踪器挂载到预测流程中调用入口位于 ultralytics/engine/model.py#L475当调用model.track(...)时触发register_tracker(self, persist)。由此ByteTrack 与检测器解耦检测模型Detect / Segment / Pose只负责输出每帧的检测框BYTETracker负责跨帧将这些框关联成带稳定 ID 的轨迹。该设计思路与官方 ByteTrack 算法一致本仓库的实现集中在byte_tracker.py中STrack与BYTETracker两个类。二、STrack单目标跟踪轨迹类STrack继承自 ultralytics/trackers/basetrack.py 中的BaseTrack其职责是存储单个轨迹的全部信息并基于卡尔曼滤波进行状态更新与预测见 byte_tracker.py#L12-L44 的类注释。2.1 核心属性从源码中的类文档与__init__实现byte_tracker.py#L46-L60可归纳出以下关键属性属性类型含义shared_kalmanKalmanFilterXYAH类级共享卡尔曼滤波器所有STrack实例共用用于向量化的多轨迹预测_tlwhnp.ndarray私有存储左上角坐标 宽高top-left, width, heightkalman_filterKalmanFilterXYAH该轨迹实例使用的卡尔曼滤波器由activate时注入mean/covariancenp.ndarray卡尔曼状态的均值向量与协方差矩阵is_activatedbool轨迹是否已被激活scorefloat轨迹的置信度分数tracklet_lenint轨迹长度被更新的帧数cls/idxany/int类别标签与目标索引frame_id/start_frameint当前帧号 / 首次检测到该目标的帧号stateTrackState轨迹状态见下文状态机__init__中还体现了对输入格式的约束assert len(xywh) in [5, 6]即接受xywhidx或xywhaidx带旋转角用于 OBB 任务。self.angle xywh[4] if len(xywh) 6 else None表明角度信息仅在 OBB 场景下存在。2.2 状态机New / Tracked / Lost / RemovedTrackState定义于 ultralytics/trackers/basetrack.py#L9-L23New 0新检测到尚未激活Tracked 1在后续帧中持续成功关联Lost 2暂时丢失未与任何检测匹配Removed 3被移除出跟踪池。对应的状态迁移方法mark_lost()与mark_removed()也定义在BaseTrack中basetrack.py#L94-L100。此外BaseTrack提供了全局自增的track_id分配机制next_id()与reset_id()保证整个跟踪过程中轨迹 ID 全局唯一。2.3 生命周期方法activate / re_activate / updateSTrack的三个关键生命周期方法byte_tracker.py#L103-L153activate(kalman_filter, frame_id)启动一条新轨迹。分配新track_id用kalman_filter.initiate()以当前检测框初始化均值与协方差并将状态置为Tracked。注意frame_id 1时直接置is_activated True其余情况由首次成功关联触发激活。re_activate(new_track, frame_id, new_idFalse)用新检测救活一条此前丢失的轨迹。执行一次卡尔曼更新重置tracklet_len恢复Tracked状态若new_idTrue则分配全新 ID用于 ID 切换场景。update(new_track, frame_id)更新已匹配轨迹。tracklet_len 1用新检测的坐标做一次卡尔曼校正更新同步刷新score、cls、angle、idx。2.4 坐标格式转换体系STrack维护了一整套坐标格式的属性与工具方法byte_tracker.py#L155-L205tlwh左上角 宽高若mean已存在则由卡尔曼均值推导ret[2] * ret[3]恢复宽ret[:2] - ret[2:] / 2还原左上角xyxy由tlwh转换为左上 右下xywh中心点 宽高xywha中心点 宽高 角度OBB 用若angle为None则告警并退回xywhtlwh_to_xyah转换为 ByteTrack 卡尔曼状态所用的(center_x, center_y, aspect_ratio, height)格式result输出最终的跟踪结果行[坐标..., track_id, score, cls, idx]。其中xyah正是KalmanFilterXYAH采用的观测空间表示用宽高比aspect ratio替代宽度是 ByteTrack 官方实现的经典做法目的是让状态量对目标尺度变化更稳健。2.5 共享卡尔曼滤波器与向量化预测STrack提供两个静态方法用于批量操作multi_predict(stracks)byte_tracker.py#L69-L82将多条轨迹的mean、covariance堆叠为矩阵一次调用shared_kalman.multi_predict()完成所有轨迹的运动预测向量化版本性能远优于逐条预测。multi_gmc(stracks, H)byte_tracker.py#L84-L101使用单应性矩阵H默认单位阵对状态做全局运动补偿。实现上通过np.kron构造 8×8 块对角旋转矩阵R8x8对均值与协方差做变换用于相机运动GMC场景。三、BYTETracker两阶段关联的多目标跟踪器BYTETrackerbyte_tracker.py#L212-L365是 ByteTrack 算法的核心实现负责维护tracked_stracks、lost_stracks、removed_stracks三个轨迹池并在每帧执行预测 → 两阶段关联 → 状态更新的流程。3.1 构造与关键属性构造函数byte_tracker.py#L241-L251def __init__(self, args, frame_rate30): self.tracked_stracks [] # 已激活的轨迹 self.lost_stracks [] # 丢失的轨迹 self.removed_stracks [] # 已移除的轨迹 self.frame_id 0 self.args args self.max_time_lost int(frame_rate / 30.0 * args.track_buffer) self.kalman_filter self.get_kalmanfilter() self.reset_id()关键点三个轨迹池分别对应Tracked/Lost/Removed状态max_time_lost由track_buffer与帧率换算得到决定一条轨迹丢失多少帧后判定死亡get_kalmanfilter()返回KalmanFilterXYAHbyte_tracker.py#L367-L369reset()方法byte_tracker.py#L392-L399可重置全部轨迹池、帧号、卡尔曼滤波器与 ID 计数器用于切换视频源时清零状态。3.2 update每帧的主流程五步update(results, imgNone)byte_tracker.py#L253-L365是核心入口输入为单帧检测结果conf、xywh/xywhr、cls输出为激活轨迹的result数组。流程可分解为检测框按分数分流remain_inds scores track_high_thresh得到高分检测集inds_second (scores track_low_thresh) (scores track_high_thresh)得到中分检测集byte_tracker.py#L267-L277。低分检测被直接丢弃。第一轮关联高分检测将tracked_stracks与lost_stracks合并为strack_pool用卡尔曼滤波预测当前位置可选 GMC 补偿计算 IoU 距离并执行linear_assignment阈值为match_thresh默认 0.8。匹配上的轨迹执行update或re_activatebyte_tracker.py#L288-L308。第二轮关联中分检测将第一轮未匹配的高分轨迹与中分检测做 IoU 关联阈值固定 0.5救回被低置信度检测短暂遮挡的目标byte_tracker.py#L309-L323。这一步是 ByteTrack 相对传统 MOT 算法的关键改进不丢弃低分检测而是利用它们恢复遮挡轨迹。处理未确认轨迹与新轨迹第一轮未匹配的检测与unconfirmed未激活轨迹做阈值 0.7 的关联仍未匹配的检测若score new_track_thresh则activate为新轨迹否则丢弃byte_tracker.py#L325-L347。状态收尾超时frame_id - end_frame max_time_lost的 lost 轨迹标记为 removed合并三池、去重remove_duplicate_stracksIoU 距离阈值 0.15保留存活时间更长的轨迹并将removed_stracks裁剪到最近 999 条以控制内存byte_tracker.py#L348-L365。3.3 距离度量与关联工具关联过程依赖 ultralytics/trackers/utils/matching.pylinear_assignment默认使用lap.lapjv求解线性分配use_lapTruecost_limitthresh之外的匹配视为不匹配若未安装lap自动检查并安装lapx0.5.2也可回退到scipy.optimize.linear_sum_assignmentiou_distance基于 IoU 构建代价矩阵1 - iou支持普通框bbox_ioa与 OBB 旋转框batch_probiou对应 5 维xywhafuse_score将检测置信度与 IoU 相似度融合最终代价为1 - (1 - dist) * score即高置信度检测在关联中权重更大。3.4 卡尔曼滤波状态空间的数学基础BYTETracker使用的KalmanFilterXYAH定义于 ultralytics/trackers/utils/kalman_filter.py#L7-L2168 维状态(x, y, a, h, vx, vy, va, vh)中心点 (x, y)、宽高比 a、高度 h 及其各自速度恒定速度模型_motion_mat中mat[i, ndimi] dtdt1位置与速度通过时间步耦合线性观测模型_update_mat直接取状态的前 4 维作为观测不确定度权重_std_weight_position 1/20、_std_weight_velocity 1/160控制运动模型与观测模型的置信度且与目标高度mean[3]成比例大目标允许更大的不确定性initiate/predict/update分别实现轨迹初始化、运动预测与观测校正校正阶段使用 Cholesky 分解求解卡尔曼增益multi_predict为向量化预测版本配合STrack.multi_predict批量推进所有轨迹。同文件中还定义了KalmanFilterXYWHkalman_filter.py#L219-L360其状态为(x, y, w, h, vx, vy, vw, vh)专供 BoT-SORTBOTSORT使用——这也解释了byte_tracker.py为什么采用XYAH表示。四、配置参数bytetrack.yaml 全量解读默认配置位于 ultralytics/cfg/trackers/bytetrack.yamltracker_type: bytetrack # 跟踪器类型可选 [botsort, bytetrack] track_high_thresh: 0.5 # 第一轮关联高分检测的分数阈值 track_low_thresh: 0.1 # 第二轮关联中分检测的分数阈值 new_track_thresh: 0.6 # 未匹配检测创建新轨迹的最低分数 track_buffer: 30 # 轨迹超时移除的缓冲帧数按帧率换算 match_thresh: 0.8 # 轨迹-检测关联IoU 距离阈值各参数在源码中的精确作用参数默认值源码位置作用说明track_high_thresh0.5byte_tracker.py#L267高于该分数的检测进入第一轮高分关联track_low_thresh0.1byte_tracker.py#L268高于该分数且低于track_high_thresh的检测进入第二轮中分关联低于此值直接丢弃new_track_thresh0.6byte_tracker.py#L344第一轮未匹配检测只有分数超过它才激活为新轨迹抑制低质量误报产生碎片轨迹track_buffer30byte_tracker.py#L249与帧率换算成max_time_lost决定 lost 轨迹的复活窗口byte_tracker.py#L350match_thresh0.8byte_tracker.py#L298第一轮linear_assignment的代价上限IoU 距离越大越容易接受低 IoU 匹配自定义时只需复制该 YAML 为custom_tracker.yaml并修改参数tracker_type除外用法见 docs/en/modes/track.md 与 ultralytics/trackers/README.md。注意track_buffer的效果受帧率换算影响max_time_lost int(frame_rate / 30.0 * track_buffer)即默认按 30fps 标定。五、实战在 YOLOv10 中启用 ByteTrack5.1 Python APIfrom ultralytics import YOLO model YOLO(yolov10n.pt) # 或 yolov8n-seg.pt / 自定义模型 # 使用默认跟踪器BoT-SORT results model.track(sourcevideo.mp4, showTrue) # 显式指定 ByteTrack results model.track( sourcevideo.mp4, showTrue, trackerbytetrack.yaml, # 亦可用自定义配置 custom_tracker.yaml ) # 逐帧循环跟踪persistTrue 告知跟踪器这是连续帧序列 import cv2 cap cv2.VideoCapture(video.mp4) while cap.isOpened(): success, frame cap.read() if success: results model.track(frame, persistTrue, trackerbytetrack.yaml) annotated_frame results[0].plot() cv2.imshow(YOLOv10 ByteTrack, annotated_frame) if cv2.waitKey(1) 0xFF ord(q): break else: break cap.release() cv2.destroyAllWindows()5.2 CLI 用法yolo track modelyolov10n.pt sourcevideo.mp4 trackerbytetrack.yaml yolo track modelyolov8n-seg.pt sourcevideo.mp4 trackerbytetrack.yaml yolo track modelpath/to/best.pt sourcevideo.mp4 conf0.3 iou0.5 trackerbytetrack.yaml5.3 结果的读法model.track()返回的结果与检测一致但额外带有boxes.id字段每帧分配的稳定轨迹 ID。跟踪器的最终输出由STrack.resultbyte_tracker.py#L201-L205构造每行为[坐标(4 或 5 维), track_id, score, cls, idx]经 track.py#L66-L77 的on_predict_postprocess_end写回结果对象。若在逐帧循环中不使用persistTrue则切换视频源时跟踪器会被自动reset()track.py#L62-L64ID 计数从头开始。六、扩展阅读BOTSORT 与跟踪生态BYTETracker还是 BoT-SORT 的基类ultralytics/trackers/bot_sort.py#L125 中class BOTSORT(BYTETracker)直接继承并扩展追加了 ReID 嵌入距离embedding_distance见 matching.py#L96-L117与 GMC 相机运动补偿。因此理解byte_tracker.py是理解整个 ultralytics/trackers 目录的基础状态机在 basetrack.py关联工具在 utils/matching.py卡尔曼实现在 utils/kalman_filter.py配置在 ultralytics/cfg/trackers 下的两个 YAML 文件中。七、总结STrack与BYTETracker构成了 YOLOv10 多目标跟踪的完整闭环STrack是单条轨迹的数据结构用KalmanFilterXYAH承载运动模型管理Tracked / Lost / Removed状态与 IDBYTETracker是跨帧关联的调度器通过高分检测一轮关联 中分检测二轮补关联 新轨迹激活 超时清理的五步流程把检测流转换成带稳定 ID 的轨迹流所有行为都由 bytetrack.yaml 中的五个参数精确调控理解它们在不同场景密集人群、遮挡、高速运动下的调优方向是落地 ByteTrack 的关键。从源码结构看该实现严格对齐 ByteTrack 官方算法两阶段关联思想并针对 YOLO 推理管线做了向量化multi_predict、批处理多 tracker 实例与 OBBxywha等工程化增强。无论是二次开发自定义跟踪器还是排查跟踪 ID 频繁跳变、轨迹丢失等问题byte_tracker.py都是首选入口。【免费下载链接】yolov10YOLOv10: Real-Time End-to-End Object Detection [NeurIPS 2024]项目地址: https://gitcode.com/GitHub_Trending/yo/yolov10创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询