当前位置: 首页 > article >正文

25/2/18 <算法笔记> ByteTrack

ByteTrack(发表在 2021 年)是一种高效且精确的 **多目标跟踪(Multi-Object Tracking, MOT)**算法。它属于目标跟踪领域中基于检测的类别(tracking by detection),核心思想是利用目标检测器的高置信度和低置信度检测结果,通过简单的后处理策略实现高效和准确的目标跟踪。

多目标跟踪 (MOT) 的主要目的是对视频或帧序列中的多个对象进行检测和跟踪。在 MOT 方法中通常有两种主要阶段:

  • 检测阶段:识别目标(人、车、动物等)。
  • 跟踪阶段:将连续帧中的目标进行关联,生成轨迹。

核心难点

传统 MOT 的核心挑战包括:

  1. 检测不够可靠: 检测器可能漏检或置信度过低,导致目标轨迹中断。
  2. 遮挡问题: 多个目标之间可能发生遮挡,导致轨迹消失或错误关联。
  3. 实时性: 跟踪需要在高精度和高效率之间取得平衡。

为了应对以上问题,ByteTrack 引入了一种简单、高效的方法,通过同时利用高置信和低置信检测结果提高了跟踪性能。

核心难点

传统 MOT 的核心挑战包括:

  1. 检测不够可靠: 检测器可能漏检或置信度过低,导致目标轨迹中断。
  2. 遮挡问题: 多个目标之间可能发生遮挡,导致轨迹消失或错误关联。
  3. 实时性: 跟踪需要在高精度和高效率之间取得平衡。

为了应对以上问题,ByteTrack 引入了一种简单、高效的方法,通过同时利用高置信和低置信检测结果提高了跟踪性能。

  1. 设置 τ 作为置信度阈值:

    • HighConfDets={di∣Conf(di)>τ}
    • LowConfDets={dj∣Conf(dj)≤τ}
  2. 轨迹初始化:
    已经生成的轨迹存储为一个集合 Tracks={t1,t2,...,tn},其中包含跟踪对象的历史状态与信息(如位置、形状、速度等)。

  3. 数据关联 (Data Association):

    • 第一阶段匹配(高置信匹配):
      • 通过匈牙利算法或 IOU 匹配,将高置信检测结果与现有轨迹进行关联。
      • 使用两个常见度量:
        • 外观特征: 比如目标的 ReID 特征。
        • 运动相似性: 预测轨迹框位置与当前检测框的 IOU。
      • 完成后将更新轨迹集合,任何未匹配的轨迹标记为未匹配轨迹
    • 第二阶段匹配(低置信检测参与匹配):
      • 针对未匹配的轨迹,尝试将低置信检测结果进行二次匹配。
      • 通过同样的匹配策略(如 IOU)进行匹配,扩大追踪范围。

轨迹状态更新:

  • 已匹配的轨迹更新历史状态(例如位置、大小等)。
  • 未匹配的轨迹(包括从低置信检测中也未匹配上的)经过多个连续帧未激活后,将被删除。
  • 新的检测(高或低置信)初始化为新轨迹

ByteTrack 的知识点解析

数据关联 (Data Association)

这是 MOT 的核心技术,用于在帧间将目标匹配起来,主要方法包括:

  1. 匈牙利算法 (Hungarian Algorithm)

    • 一种用于解决二分图匹配问题的经典方法,用于寻找最优匹配关系。
    • ByteTrack 使用匈牙利算法完成轨迹和检测框的匹配。
  2. IOU 匹配:

    • IOU(交并比)是目标检测中的重要度量,表示预测框和真实框的重叠程度。
    • IOU 越高,匹配关系越强。
  3. 成本矩阵:

    • 在数据关联时,会基于 IOU(或结合其他特征)生成成本矩阵,用于衡量轨迹和检测框之间的匹配代价

匈牙利算法流程

匈牙利算法的核心思想是通过动态调整权重,寻找代价矩阵中的最优匹配,具体分为以下步骤:

输入:
  • 代价矩阵 CC(即轨迹和检测框之间的权重关系)。
  • 初始化一个矩形矩阵(轨迹行 ×× 检测列),未匹配的元素填充一个大的无穷值。
步骤:
  1. 对矩阵的每一行减去该行的最小值。
    • 保证矩阵中每一行都有至少一个零。
  2. 对矩阵的每一列减去该列的最小值。
    • 保证矩阵中每一列也至少有一个零。
  3. 在矩阵中找到覆盖所有零元素的最小直线条数:
    • 如果直线条的数量等于矩阵的维度,表明已经找到了最优匹配,停止。
    • 否则,调整矩阵中的值,重复之前过程:
      • 找出未被覆盖的最小值。
      • 将其减去未覆盖元素,增加到两条覆盖线条的交点处。
  4. 重复步骤 3,直到覆盖线条数等于矩阵维度。

高置信与低置信检测的分裂

传统 MOT 主要依赖高置信度的检测框,而忽略低置信检测可能导致轨迹中断。ByteTrack 基于检测的置信度做了以下改进:

  • 高置信检测:直接更新轨迹。
  • 低置信检测:尝试与未匹配轨迹进一步关联。

轨迹管理

轨迹管理包含对目标状态的跟踪和更新,主要包括:

  • 初始化: 新检测目标生成新的轨迹。
  • 更新: 匹配成功后更新轨迹位置与状态。
  • 删除: 连续未被匹配的轨迹删除。
# 核心逻辑:ByteTrack 简化版实现
def byte_track(detections, tracks, track_id_count, conf_threshold=0.5, iou_threshold=0.3, max_age=30):
    """
    ByteTrack 核心逻辑
    detections: 检测框及置信度 [(bbox, conf), ...],bbox 是 [x1, y1, x2, y2]
    tracks: 当前已有轨迹 Track 对象列表
    track_id_count: 唯一的轨迹 ID 计数器
    conf_threshold: high_conf 的置信度分割阈值
    """
    # Step 1: 根据置信度划分高置信检测和低置信检测
    high_conf_dets = [det for det in detections if det[1] >= conf_threshold]
    low_conf_dets = [det for det in detections if det[1] < conf_threshold]

    # Step 2: 高置信检测进行第一阶段匹配
    matches, unmatched_tracks, unmatched_detections = associate_detections_to_tracks(
        [det[0] for det in high_conf_dets], tracks, iou_threshold
    )

    # 更新轨迹(匹配成功的部分)
    for track_idx, det_idx in matches:
        tracks[track_idx].update(high_conf_dets[det_idx][0])  # 更新轨迹位置

    # 标记未匹配轨迹
    for track_idx in unmatched_tracks:
        tracks[track_idx].mark_missed()

    # 未匹配的高置信检测框则初始化为新轨迹
    for det_idx in unmatched_detections:
        new_track = Track(high_conf_dets[det_idx][0], track_id_count, high_conf_dets[det_idx][1])
        tracks.append(new_track)
        track_id_count += 1

    # Step 3: 第二阶段:低置信检测参与匹配(补充漏检)
    if len(unmatched_tracks) > 0:
        unmatched_tracks = [tracks[i] for i in unmatched_tracks]
        low_conf_bbox = [det[0] for det in low_conf_dets]
        _, unmatched_tracks, unmatched_detections = associate_detections_to_tracks(
            low_conf_bbox, unmatched_tracks, iou_threshold
        )

        # 更新未匹配轨迹
        for track_idx, det_idx in matches:
            unmatched_tracks[track_idx].update(low_conf_dets[det_idx][0])

    # 删除长期未被匹配的轨迹
    tracks = [t for t in tracks if t.time_since_update <= max_age]

    return tracks, track_id_count


http://www.kler.cn/a/552739.html

相关文章:

  • 阿里云前端自动化部署流程指南
  • 《DeepSeek赋能工业互联网:解锁数据深度分析新姿势》
  • 【Elasticsearch】分页查询
  • Pycharm打开的jupyter notebook无法在pycharm中关闭怎么解决
  • el-table树状表格,默认展开第一个节点的每一层
  • 2024亚马逊数据分析!
  • lambda表达式thenComparing使用示例
  • Ubuntu 下创建具有 root 权限用户
  • Elasticsearch AI Assistant 集成 DeepSeek,1分钟搭建智能运维助手
  • 在nodejs中使用RabbitMQ(七)实现生产者确认
  • 私域流量运营中用户价值提升策略研究——以开源AI智能名片2+1链动模式与S2B2C商城小程序为例
  • 1-13 tortoiseGit忽略文件与文件夹
  • 深度学习模型常用激活函数集合
  • 智能硬件定位技术发展趋势
  • HarmonyOS:使用List实现分组列表(包含粘性标题)
  • 中电金信:数字基础设施未来展望·行业定制与开源融合
  • JSON类型理解(前后端交互/内存对数据操作)
  • 微服务监控与Go服务性能分析
  • 级联选择器多选动态加载
  • 基于SpringBoot+Vue高校就业领航管理系统