目标追踪:使用ByteTrack进行目标检测和跟踪

news2025/3/16 10:05:45

BYTE算法是一种简单而有效的关联方法,通过关联几乎每个检测框而不仅仅是高分的检测框来跟踪对象。这篇博客的目标是介绍ByteTrack以及多目标跟踪(MOT)的技术。我们还将介绍在样本视频上使用ByteTrack跟踪运行YOLOv8目标检测。

dac2d9c22a2cc4612b02778939800a24.gif

多目标跟踪(MOT)

你可能听说过目标检测,有许多算法如Faster RCNN、SSD和YOLO的各个版本,它们可以以很高的准确性检测物体。但有一个更新的问题是多目标跟踪。基本上,你将传递一个视频流,对于每一帧,你需要检测对象并分配一个“对象ID”,在下一帧中,如果检测到相同的对象,需要分配相同的对象ID。有许多用于MOT的算法,如SORT(简单在线和实时跟踪)、DeepSort、StrongSort等。

有各种用于目标跟踪的方法,包括:

1. 基于特征的跟踪:这涉及基于其特征(如颜色、形状、纹理等)进行跟踪。

2. 模板匹配:正如其名称所示,该方法使用预定义的模板在每个视频序列中进行匹配。

3. 相关性跟踪:该方法用于计算目标对象与后续帧中候选区域的相似性。

4. 基于深度学习的跟踪:该方法使用在大型数据集上训练的神经网络,以实时检测和跟踪对象。

在你可能对MOT有了一些基本的了解。让我们尝试进入ByteTrack并尝试理解为什么它是比DeepSort等更好的目标跟踪。

ByteSort

首先,我们将了解先前MOT算法的问题,然后理解ByteSort的逻辑。

其他MOT算法的问题:

  • 低置信度检测框:其他MOT算法的第一个问题是删除低置信度的检测框。而ByteTrack考虑了低置信度的检测框。为什么呢?

因为低置信度的检测框有时表示物体的存在,例如被遮挡的物体。过滤这些对象会在MOT中引入不可逆的错误,导致不可忽视的漏检和碎片化的轨迹。让我们通过例子来理解:

370844990a22283744acf7622089fec3.jpeg

Detection boxes

 如图 t1 中所示,我们初始化三个不同的tracklet,因为它们的分数高于0.5。但在 t2 和 t3 中,分数从 0.8 下降到 0.4,然后再下降到 0.1。

aefa0758cc9f6ca406db40cca953f01e.jpeg

Tracklets by associating high scores detection boxes

 这些检测框将通过阈值机制被消除,红色轨迹随之消失,如图 b 所示。但如果我们考虑所有的检测框,将引入更多的假阳性,例如图 a 中最右侧的框。这带来了第二个问题:

  • 假阳性边框的考虑:在这里识别到与tracklets相似性提供了在低分检测框中区分对象和背景的强关联。

3910c8f2494f85dd74384bb943109748.jpeg

Tracklets by associating every detection boxes

例如,如图 c 所示,通过运动预测的框(虚线)将两个低分检测框与tracklets匹配,从而正确恢复了对象。由于背景框没有匹配的tracklet,因此将其移除。因此,为了在匹配过程中使用高分到低分的检测框,这种简单而有效的关联方法被称为BYTE,因为每个检测框是tracklet的基本单元。

首先,它根据运动或外观相似性将高分检测框与tracklets匹配。然后,它采用卡尔曼滤波器来预测tracklets在下一帧的位置。然后,可以使用IoU或Re-ID特征距离计算预测框与检测框之间的相似性。在第二个匹配步骤中,使用相同的运动相似性匹配低分检测和未匹配的tracklets,即红框中的tracklets。让我们尝试理解数据关联,这是MOT算法的核心。

数据关联

这是多目标跟踪的核心,首先计算tracklets和检测框之间的相似性,并根据相似性应用不同的策略进行匹配。

  • 相似性度量:对于关联,位置、运动和外观是三个重要的线索。SORT以非常简单的方式使用位置和运动线索。它采用卡尔曼滤波器来预测下一帧中的tracklets,然后计算检测框和预测框之间的IoU作为相似性。但是位置和运动线索适用于短程匹配。但对于长程匹配,外观相似性是有帮助的。例如,长时间被遮挡的对象将使用外观相似性进行识别。外观相似性通过Re-ID特征的余弦相似度来计算。DeepSort使用一个独立的深度学习模型进行外观相似性。

  • 匹配策略:在相似性计算后,匹配策略用于为对象分配ID。这可以通过匈牙利算法或贪婪分配来完成。SORT通过一次匹配将检测框与tracklets匹配。而DeepSort使用级联匹配策略,首先将检测框与最近的trackers匹配,然后匹配失去的tracklets。

BYTE算法

e0452d14f78d16071e1d8673a93c3b75.jpeg

(d)BYTETrack的伪代码。(绿色是该方法的关键)

BYTE算法的输入是视频序列和检测器。还有一个检测阈值。该算法输出视频的轨迹T,每一帧包含对象的边界框和ID。对于视频中的每一帧,首先使用检测器Det预测检测框和预测分数。然后根据检测分数阈值将检测框分为Det(high)和Det(low)两类。

在分离了检测框之后,对每个轨迹T应用卡尔曼滤波器来预测当前帧的新位置。首先,在高检测框上应用关联,然后在剩余的低检测框上应用关联。BYTE的主要亮点是,它非常灵活,可以与不同的关联方法兼容。

性能

ByteTrack优于SORT和DeepSORT算法。ByteTrack的MOTA(多目标跟踪准确性)为76.6,而SORT和DeepSort分别为74.6和75.4。现在,你可能已经理解了ByteTrack的主要概念。我想这很简单。让我们尝试在实际项目中应用它。

使用YOLOv8检测器的ByteTrack

在这里,我们将看到如何使用YOLOv8检测器跟踪道路上的车辆,并计算进出的车辆数。

7a001f7dd69af655bb7c8dc2d364403d.png

如你所见,每辆新车都被分配了一个ID、一个类名和检测概率。使用in和out,你可以看到进出交通的计数。让我们看看这个实现的代码:

import supervision as sv
from ultralytics import YOLO 
from tqdm import tqdm
import argparse
import numpy as np


tracker = sv.ByteTrack() 
def process_video(
        source_weights_path: str, 
        source_video_path: str,
        target_video_path: str, 
        confidence_threshold: float = 0.3,
        iou_threshold: float = 0.7
) -> None:
    model = YOLO(source_weights_path)       # Load YOLO model 
    classes = list(model.names.values())    # Class names 
    LINE_STARTS = sv.Point(0,500)           # Line start point for count in/out vehicle
    LINE_END = sv.Point(1280, 500)          # Line end point for count in/out vehicle
    tracker = sv.ByteTrack()                # Bytetracker instance 
    box_annotator = sv.BoundingBoxAnnotator()     # BondingBox annotator instance 
    label_annotator = sv.LabelAnnotator()         # Label annotator instance 
    frame_generator = sv.get_video_frames_generator(source_path=source_video_path) # for generating frames from video
    video_info = sv.VideoInfo.from_video_path(video_path=source_video_path)
    line_counter = sv.LineZone(start=LINE_STARTS, end = LINE_END)
    line_annotator = sv.LineZoneAnnotator(thickness=2, text_thickness=2, text_scale= 0.5)


    with sv.VideoSink(target_path=target_video_path, video_info=video_info) as sink:
        for frame in tqdm(frame_generator, total= video_info.total_frames):
            # Getting result from model
            results = model(frame, verbose=False, conf= confidence_threshold, iou = iou_threshold)[0] 
            detections = sv.Detections.from_ultralytics(results)    # Getting detections
            #Filtering classes for car and truck only instead of all COCO classes.
            detections = detections[np.where((detections.class_id==2)|(detections.class_id==7))]
            detections = tracker.update_with_detections(detections)  # Updating detection to Bytetracker
            # Annotating detection boxes
            annotated_frame = box_annotator.annotate(scene = frame.copy(), detections= detections) 


            #Prepare labels
            labels = []
            for index in range(len(detections.class_id)):
                # creating labels as per required.
                labels.append("#" + str(detections.tracker_id[index]) + " " + classes[detections.class_id[index]] + " "+ str(round(detections.confidence[index],2)) )
            
            # Line counter in/out trigger
            line_counter.trigger(detections=detections)
            # Annotating labels
            annotated_label_frame = label_annotator.annotate(scene=annotated_frame, detections=detections, labels=labels)
            # Annotating line labels
            line_annotate_frame = line_annotator.annotate(frame=annotated_label_frame, line_counter=line_counter)
            sink.write_frame(frame = line_annotate_frame)


if __name__ == "__main__":
    parser = argparse.ArgumentParser("video processing with YOLO and ByteTrack") 
    parser.add_argument(
        "--source_weights_path",
        required=True,
        help="Path to the source weights file",
        type=str
    )
    parser.add_argument(
        "--source_video_path",
        required=True, 
        help="Path to the source video file",
        type = str
    )
    parser.add_argument(
        "--target_video_path",
        required=True,
        help="Path to the target video file",
        type= str
    )
    parser.add_argument(
        "--confidence_threshold",
        default = 0.3,
        help= "Confidence threshold for the model",
        type=float
    )
    parser.add_argument(
        "--iou_threshold",
        default=0.7,
        help="Iou threshold for the model",
        type= float
    )
    args = parser.parse_args() 
    process_video(
        source_weights_path=args.source_weights_path, 
        source_video_path= args.source_video_path,
        target_video_path=args.target_video_path, 
        confidence_threshold=args.confidence_threshold,
        iou_threshold=args.iou_threshold
    )

在这里,我使用了YOLOv8 Ultralytics库来加载在COCO数据集上训练的YOLO模型。Supervision库用于加载ByteTrack和其他视觉任务,如标注、车辆计数等。

你只需通过传递视频作为输入运行此命令:

python sv_bytetracker_yolo.py --source_weights_path yolov8m.pt --source_video_path test_video.mp4 --target_video_path test_pred.mp4 --confidence_threshold 0.1

如果你想跟踪其他类别,可以从代码中删除类别过滤器。

应用场景

因此,我们已经完全了解了ByteTrack。它可以在各种应用和行业中使用,例如:

1. 汽车行业:用于跟踪道路上的车辆进行交通分析,例如任何车辆是否朝错误的方向行驶,四路口的交通情况等。

2. 生产行业:可以在生产线上用于计数和跟踪生产物品。

3. 购物中的客户互动:跟踪客户的移动,了解客户对哪种产品或哪个类别更感兴趣。他们持有产品的时间有多长,最终是购买还是放回货架。

4. 增强客户体验:在客户看起来困惑或寻找产品时间过长时进行识别。

总结

1. 有各种MOT模型,如SORT、DeepSort、ByteTrack等。

2. 有各种用于对象跟踪的方法/技术,包括基于特征的跟踪、模板匹配、相关性跟踪和基于深度学习的跟踪。

3. ByteTrack算法考虑了低分检测框(与高分检测框一起)进行对象跟踪。

4. 数据关联应用于每个检测。

5. 在数据关联中,生成了tracklet和检测框之间的相似性。然后根据相似性应用不同的策略进行匹配。

6. 相似性可以通过IoU或由卡尔曼滤波器的tracklet预测的Re-ID计算。

7. 对于长距离,外观相似性是有用的。

8. 在匹配策略中使用了匈牙利算法。

9.Byte首先对高分检测框应用关联,然后对低分检测框应用关联。

·  END  ·

HAPPY LIFE

f5d9b7fcf99a419f8cae3f0c808e3549.png

本文仅供学习交流使用,如有侵权请联系作者删除

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1336683.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JoySSL证书

很多人喜欢JoySSL证书,主要是因为 JoySSL 提供了许多有吸引力的特性和优势。首先,JoySSL 提供的 SSL 证书价格相对较为实惠,使得小型企业和个人网站也能够轻松承担起加密保护的成本。其次,JoySSL 提供的证书具有很高的安全性&…

华为云Stack 8.X流量模型分析(三)

三、VPC内部二层流量模型分析 1.不同宿主机下虚拟机互访 VM1发送arp请求,arp报文根据流表到达br-tun,br-tun给予VM1到达VM2的MAC信息。此时arp报文不出宿主机(Host1); **注意:**br-tun内的信息是由管理平…

Android Termux安装SSH结合内网穿透实现远程SFTP文件传输

文章目录 1. 安装openSSH2. 安装cpolar3. 远程SFTP连接配置4. 远程SFTP访问4. 配置固定远程连接地址 SFTP(SSH File Transfer Protocol)是一种基于SSH(Secure Shell)安全协议的文件传输协议。与FTP协议相比,SFTP使用了…

Windows操作系统:共享文件夹,防火墙的设置

1.共享文件夹 1.1 共享文件夹的优点 1.2 共享文件夹的优缺点 1.3 实例操作 ​编辑 2.防火墙设置 2.1 8080端口设置 3.思维导图 1.共享文件夹 1.1 共享文件夹的优点 优点 协作和团队合作:共享文件夹使多个用户能够在同一文件夹中协作和编辑文件。这促进了团…

【开源】基于JAVA语言的企业项目合同信息系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 合同审批模块2.3 合同签订模块2.4 合同预警模块2.5 数据可视化模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 合同审批表3.2.2 合同签订表3.2.3 合同预警表 四、系统展示五、核心代码5.1 查询合同…

Rancher小白学习之路

官网:http://docs.rancher.cn/docs/rancher1/rancher-service/load-balancer/_indexhttp://docs.rancher.cn/docs/rancher1/rancher-service/load-balancer/_indexRancher2.5集群搭建&K3S生产环境搭建手册 - 知乎 【rancher教程】十年运维大佬两小时带你搞定ran…

centos7.9中离线安装nginx开启ssl,arm架构

一、首先需要去国内相关镜像库下载相关依赖rpm: http://mirrors.bfsu.edu.cn/centos-altarch/7.9.2009/os/aarch64/ http://mirror.nju.edu.cn/centos-altarch/7.9.2009/os/aarch64/ http://mirrors.tuna.tsinghua.edu.cn/centos-altarch/7.9.2009/os/aarch64/ htt…

Flink 输出至 Redis

【1】引入第三方Bahir提供的Flink-redis相关依赖包 <!-- https://mvnrepository.com/artifact/org.apache.bahir/flink-connector-redis --> <dependency><groupId>org.apache.bahir</groupId><artifactId>flink-connector-redis_2.11</arti…

【数学建模美赛M奖速成系列】Matplotlib绘图技巧(一)

Matplotlib图像基础 写在前面1 基本绘图实例&#xff1a;sin、cos函数图2 plot()函数详解**kwargs参数&#xff1a; 3 matplotlib中绘图的默认配置4 设置图的横纵坐标的上下界5 设置横纵坐标上的记号6 调整图像的脊柱7 添加图例8 给一些特殊点加注释9 子图最后 写在前面 前面我…

轻松设置CentOS IP地址的最终指南:详细的分步说明

轻松设置CentOS IP地址的最终指南 一、引言二、准备工作三、手动设置IP地址四、自动分配IP地址(DHCP)五、使用网络管理工具设置IP地址5.1、使用nmtui工具进行图形化设置5.2、使用nmcli命令行工具进行设置 六、常见问题和解决方案七、总结 一、引言 CentOS操作系统是一种基于Li…

uni-app tabbar组件

锋哥原创的uni-app视频教程&#xff1a; 2023版uniapp从入门到上天视频教程(Java后端无废话版)&#xff0c;火爆更新中..._哔哩哔哩_bilibili2023版uniapp从入门到上天视频教程(Java后端无废话版)&#xff0c;火爆更新中...共计23条视频&#xff0c;包括&#xff1a;第1讲 uni…

AI+城市运行“一网统管”建设白皮书,核心建设目标和内容

“一网统管”是指依托智能城市运行管理中心的实体化运作&#xff0c;以物联网、大数据、人工智能、区块链等现代信息技术为手段&#xff0c;对城市运行进行全域的即时分析、指挥、调动、管理&#xff0c;实现对城市运行中各类事项“一网打尽”、城市治理“一屏通览”。 以下是A…

Jmeter 性能测试 —— 评估一个系统TPS与并发数!

问题&#xff1a;性能压测&#xff0c;如何评估一个系统的TPS和并发数&#xff1f; 1、对于新系统 由业务部门或开发人员预估交易量和TPS指标 可以参考公式&#xff1a;并发用户 在线用户数 * 10%。 当一个系统还没有上线时&#xff0c;我们可以预判的是这个系统准备要给多…

12.25

led.c #include "led.h" void all_led_init() {RCC_GPIO | (0X3<<4);//时钟使能GPIOE_MODER &(~(0X3<<20));//设置PE10输出GPIOE_MODER | (0X1<<20);//设置PE10为推挽输出GPIOE_OTYPER &(~(0x1<<10));//PE10为低速输出GPIOE_OSPEED…

关于“Python”的核心知识点整理大全43

目录 ​编辑 15.2.3 使2散点图并设置其样式 scatter_squares.py 15.2.4 使用 scatter()绘制一系列点 scatter_squares.py 15.2.5 自动计算数据 scatter_squares.py 15.2.6 删除数据点的轮廓 15.2.7 自定义颜色 15.2.8 使用颜色映射 scatter_squares.py 注意 15.2.9…

C# Winform教程(二):基础窗口程序

1、介绍 winform应用程序是一种智能客户端技术&#xff0c;我们可以使用winform应用程序帮助我们获得信息或者传输信息等。 2、常用属性 Name&#xff1a;在后台要获得前台的控件对象&#xff0c;需要使用Name属性。 Visible&#xff1a;指示一个控件是否可见、 Enable&…

超声系统前端理论与模拟仿真-续

作者&#xff1a;蒋志强 本人同意他人对我的文章引用&#xff0c;但请在引用时注明出处&#xff0c;谢谢&#xff0e;作者&#xff1a;蒋志强 前言 近期整理了一下彩超前端及波束合成相关的内容&#xff0c;很早以前已经有过一次&#xff0c;这次把其它的内容总结一下&#xf…

前端canvas项目实战——简历制作网站(一)——左侧工具栏

目录 前言一、效果展示二、实现步骤1. 拆分旧代码&#xff0c;优化项目结构2. 左侧工具栏3. 组合代码 三、Show u the code后记 前言 在fabric基础系列博文中&#xff0c;我们通过代码向画布canvas中添加矩形、圆形等对象。对于用户&#xff0c;我们不能指望他们可以理解代码&…

改变命运第一法

不与事争&#xff0c;你争不过因果&#xff1b;不与人争&#xff0c;会伤了感情&#xff1b;不与己争&#xff0c;会让人心累。平静淡泊、守望平和&#xff0c;不指责&#xff0c;不抱怨&#xff0c;不计较&#xff0c;永远做个善良清澈的自己&#xff0c;以善为本&#xff0c;…

Linux OpenEuler(欧拉系统)无公网ip实现SSH远程连接

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;…