基于YOLOv8与ByteTrack实现多目标跟踪——算法原理与代码实践
概述
在目标检测中,有许多经算法如Faster RCNN、SSD和YOLO的各种版本,这些算法利用深度学习技术,特别是卷积神经网络(CNN),能够高效地在图像中定位和识别不同类别的目标。Faster RCNN是一种基于区域提议的目标检测算法,通过引入区域建议网络(RPN)来生成候选框,然后使用分类器和回归器来识别和精确定位目标。SSD(Single Shot MultiBox Detector)是一种单阶段的目标检测算法,它在单个卷积网络中同时进行目标分类和定位,具有较快的速度和较高的准确性。而YOLO(You Only Look Once)则是一种端到端的目标检测算法,通过将图像分割为网格并预测每个网格中的目标类别和边界框来实现目标检测,具有实时性的优势。
但这里有一个问题是,在目标检测上,所检测到的目标是一帧帧的,同一个目标在帧与帧之间并没有关联起来,这个时候,如果要确定上一帧的A_1目标是不是下一帧的A_2目标,这里就要用到多目标跟踪。多目标追踪传输的是一个视频流,对于每一帧,需要检测目标并分配一个“对象 ID”,在下一帧中,如果检测到相同的对象,则需要分配相同的对象 ID。有许多算法用于 MOT,如 SORT(简单在线实时跟踪)、DeepSort、StrongSort 等。
-
SORT(Simple Online and Realtime Tracking):这是一种简单而高效的在线多目标跟踪算法,它结合了卡尔曼滤波和匈牙利算法来实现目标跟踪。SORT适用于实时应用,并且在计算资源有限的情况下表现良好。
-
DeepSort:这是在SORT基础上发展而来的算法,它引入了深度学习技术,特别是卷积神经网络(CNN),用于提取目标的特征表示。DeepSort在目标跟踪的准确性和鲁棒性方面相对于传统方法有所提升。
-
StrongSort:这是另一种基于深度学习的多目标跟踪算法,它通过设计更强大的特征提取网络和更精细的跟踪策略来提高目标跟踪的性能。
目标跟踪可分为下面几种:
基于特征的跟踪:这涉及基于其特征(如颜色、形状、纹理等)进行跟踪。
模板匹配:顾名思义,这种方法使用预定义的模板在每个视频序列中进行匹配。
基于相关性的跟踪:这种方法用于计算目标对象与后续帧中候选区域之间的相似性。
基于深度学习的跟踪:这种方法使用在大型数据集上训练的神经网络实时检测和跟踪对象。
ByteSort
其他MOT算法中移除低置信度检测框的问题主要源于对检测框置信度的阈值设置以及对检测框的筛选策略。因为低置信度的检测框被认为可能是误检测或者不可靠的检测结果,因此会被丢弃以提高跟踪的准确性。然而,这种策略可能会带来一些问题:
-
遮挡目标: 低置信度的检测框有时确实可以指示目标的存在,尤其是在目标被部分遮挡或者遮挡物很大时。丢弃这些低置信度的检测框可能会导致漏检目标,因为算法无法正确地识别被遮挡的目标。
-
轨迹断裂: 移除低置信度的检测框可能导致轨迹的不连续性,因为目标在一帧中被识别出来,在另一帧中却被移除了。这可能会导致跟踪算法无法正确地维持目标的标识符,从而产生碎片化的轨迹,使跟踪结果不连贯。
ByteTrack考虑低置信度的检测框的原因在于:
-
避免漏检: ByteTrack意识到低置信度的检测框可能是有价值的目标信息,尤其是在目标被遮挡的情况下。因此,保留这些检测框有助于避免目标漏检的情况,提高跟踪的完整性。
-
减少轨迹断裂: 通过保留低置信度的检测框,ByteTrack可以减少轨迹的不连续性,从而提高了多目标跟踪的连贯性和准确性。这有助于跟踪算法更好地维持目标的标识符,减少碎片化轨迹的出现。
可以从下面的例子说明这个问题,如下图1:

在帧 t1 中,初始化了三个不同的轨迹,因为它们的置信度都高于 0.5。但在帧 t2 和 t3 中,置信度从 0.8 下降到 0.4,然后从 0.4 下降到 0.1。
图2:

这些检测框将被阈值机制消除,相应的红色轨迹也会相应消失,如上图所示。但如果考虑所有的检测框,更多的误报率将会被引入,例如图1中右most的框。这带来了第二个问题。
图3:

例如,如图3所示,两个低分检测框通过运动预测框(虚线)与轨迹匹配,因此对象被正确恢复。背景框被移除,因为它没有匹配的轨迹。
因此,使用高分到低分检测框在匹配过程中。这种简单而有效的关联方法称为 BYTE,因为每个检测框都是轨迹的基本单位。首先,它根据运动或外观相似性将高分检测框匹配到轨迹。然后,它采用卡尔曼滤波器来预测下一帧中轨迹的位置。然后可以使用 IoU 或 Re-ID 特征距离计算预测框和检测框之间的相似性。在第二次匹配步骤中,低分检测和未匹配的轨迹,即红色框中的轨迹,使用相同的运动相似性进行匹配。
数据关联
数据关联是多目标跟踪的核心之一,它涉及计算轨迹和检测框之间的相似性,并根据相似性应用不同的策略进行匹配。
在相似性度量方面,位置、运动和外观是三个重要的线索。SORT算法通常简单地利用位置和运动线索。它使用卡尔曼滤波器来预测下一帧中的轨迹,并计算检测框和预测框之间的IoU作为相似性度量。然而,位置和运动线索更适用于短距离匹配。对于长距离匹配,外观相似性则变得更加重要。例如,长时间被遮挡的对象可能会通过外观相似性进行识别。外观相似性通常通过计算Re-ID特征的余弦相似性来衡量。与此类似,DeepSort采用了独立的深度学习模型来处理外观相似性。
在匹配策略方面,不同的算法使用不同的方法为对象分配ID。SORT通常通过一次匹配将检测框与轨迹匹配,而DeepSort则采用级联匹配策略。这种策略首先将检测框与最近的跟踪器匹配,然后与丢失的跟踪器进行匹配。
BYTE 算法
BYTE算法的输入是视频序列和检测器,以及一个检测阈值值。该算法的输出是视频的每一帧中的轨迹T,其中包含对象的边界框和ID。
对于视频中的每一帧,首先使用检测器(Det)预测检测框和相应的预测分数。然后,根据设定的检测分数阈值,将检测框分为高分(Det(high))和低分(Det(low))两部分。
分离检测框后,BYTE算法将卡尔曼滤波器应用于预测当前帧中每个轨迹T的新位置。首先对高分检测框进行关联,然后再处理剩余的低分检测框。
BYTE算法的主要亮点在于其非常灵活,能够与不同的关联方法兼容。这意味着它可以根据特定的应用场景选择最合适的关联方法,从而提高多目标跟踪的性能和效果。
性能测试
在同一个数据集上的表现,ByteTrack算法的性能优于SORT和DeepSORT算法,这表明它在多目标跟踪任务上具有较好的表现。,ByteTrack的MOTA达到了76.6,而SORT和DeepSORT的性能分别为74.6和75.4。
ByteTrack在算法架构上相对简单,但其性能却十分可观。这种性能提升可能源于它在关联过程中的灵活性以及对外观相似性的更好处理。
ByteTrack 与 YOLOv8 示例
多目标追踪场景中,大部分遮挡物体的检测结果都是低分框,ByteTrack 非常简洁地从低分检测框中寻找遮挡的物体,对遮挡非常鲁棒。ByteTrack 同时也为如何最大程度利用检测结果来帮助 MOT 提供了启发,下面提供了 ByteTrack 的部署代码和模型:
import supervision as sv
from ultralytics import YOLO
from tqdm import tqdm
import argparse
import numpy as nptracker = 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 vehicleLINE_END = sv.Point(1280, 500) # Line end point for count in/out vehicletracker = 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 videovideo_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 modelresults = 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 boxesannotated_frame = box_annotator.annotate(scene = frame.copy(), detections= detections) #Prepare labelslabels = []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 triggerline_counter.trigger(detections=detections)# Annotating labelsannotated_label_frame = label_annotator.annotate(scene=annotated_frame, detections=detections, labels=labels)# Annotating line labelsline_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)

完整代码带GUI界面代码和代码部署可参考《YOLOv8项目实践——目标检测、实例分割、姿态估计、目标追踪算法原理及模型部署(Python实现带界面)》
源码下载地址:https://download.csdn.net/download/matt45m/89036361?spm=1001.2014.3001.5503
模型下载地址链接:https://pan.baidu.com/s/1-t5TwKzdRuHF3dL7POk1dA
提取码:3r1v
相关文章:
基于YOLOv8与ByteTrack实现多目标跟踪——算法原理与代码实践
概述 在目标检测中,有许多经算法如Faster RCNN、SSD和YOLO的各种版本,这些算法利用深度学习技术,特别是卷积神经网络(CNN),能够高效地在图像中定位和识别不同类别的目标。Faster RCNN是一种基于区域提议的…...
C语言——函数练习程序
1.从终端接收一个数,封装一个函数判断该数是否为素数 #include <stdio.h>int pri(int num) {int i 0;for (i 2; i < num; i){if (num % i 0){return 0;break;}}if (i num-1){return 1;} }int main(void) {int num 0;int ret 0;scanf("%d", &num);…...
ssh 启动 docker 中 app, docker logs 无日志
ssh 启动 app, 标准输出被重定向 ssh 客户端,而不是 docker 容器的标准输出。只需要在启动时把app 标准输出重定向到 docker标准输出。 测试如下: 1.启动 docker docker run -it -p 60022:22 --name test test:v4 bash -c "service ssh restart;…...
WPF---1.入门学习
🎈个人主页:靓仔很忙i 💻B 站主页:👉B站👈 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:WPF 🤝希望本文对您有所裨益,如有不足之处…...
Vue3 + Vite + TS + Element-Plus + Pinia项目(5)对axios进行封装
1、在src文件夹下新建config文件夹后,新建baseURL.ts文件,用来配置http主链接 2、在src文件夹下新建http文件夹后,新建request.ts文件,内容如下 import axios from "axios" import { ElMessage } from element-plus im…...
【Rust】——编写自动化测试(一)
🎃个人专栏: 🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客 🐳Java基础:Java基础_IT闫的博客-CSDN博客 🐋c语言:c语言_IT闫的博客-CSDN博客 🐟MySQL:…...
第十二章 微服务核心(一)
一、Spring Boot 1.1 SpringBoot 构建方式 1.1.1 通过官网自动生成 进入官网:https://spring.io/,点击 Projects --> Spring Framework; 拖动滚动条到中间位置,点击 Spring Initializr 或者直接通过 https://start.spring…...
MySQL索引18连问,谁能顶住
前言 过完这个节,就要进入金银季,准备了 18 道 MySQL 索引题,一定用得上。 作者:感谢每一个支持: github 1. 索引是什么 索引是一种数据结构,用来帮助提升查询和检索数据速度。可以理解为一本书的目录&…...
[flink 实时流基础系列]揭开flink的什么面纱基础一
Apache Flink 是一个框架和分布式处理引擎,用于在无边界和有边界数据流上进行有状态的计算。Flink 能在所有常见集群环境中运行,并能以内存速度和任意规模进行计算。 文章目录 0. 处理无界和有界数据无界流有界流 1. Flink程序和数据流图2. 为什么一定要…...
开放平台 - 互动玩法演进之路
本期作者 1. 背景 随着直播业务和用户规模日益壮大,如何丰富直播间内容、增强直播间内用户互动效果,提升营收数据变得更加关键。为此,直播互动玩法应运而生。通过弹幕、礼物、点赞、大航海等方式,用户可以参与主播的直播内容。B站…...
Linux之进程控制进程终止进程等待进程的程序替换替换函数实现简易shell
文章目录 一、进程创建1.1 fork的使用 二、进程终止2.1 终止是在做什么?2.2 终止的3种情况&&退出码的理解2.3 进程常见退出方法 三、进程等待3.1 为什么要进行进程等待?3.2 取子进程退出信息status3.3 宏WIFEXITED和WEXITSTATUS(获取…...
RegSeg 学习笔记(待完善)
论文阅读 解决的问题 引用别的论文的内容 可以用 controlf 寻找想要的内容 PPM 空间金字塔池化改进 SPP / SPPF / SimSPPF / ASPP / RFB / SPPCSPC / SPPFCSPC / SPPELAN  ASPP STDC:short-term dense concatenate module 和 DDRNet SE-ResNeXt …...
Qt中常用宏定义
Qt中常用宏定义 一、Q_DECLARE_PRIVATE(Class)二、Q_DECLARE_PRIVATE_D(Dptr, Class)三、Q_DECLARE_PUBLIC(Class)四、Q_D(Class) 和 Q_Q(Class) 一、Q_DECLARE_PRIVATE(Class) #define Q_DECLARE_PRIVATE(Class) inline Class##Private* d_func() { # 此处的 d_ptr 是属于QOb…...
【计算机网络】第 9 问:四种信道划分介质访问控制?
目录 正文什么是信道划分介质访问控制?什么是多路复用技术?四种信道划分介质访问控制1. 频分多路复用 FDM2. 时分多路复用 TDM3. 波分多路复用 WDM4. 码分多路复用 CDM 正文 什么是信道划分介质访问控制? 信道划分介质访问控制(…...
Rust编程(五)终章:查漏补缺
闭包 & 迭代器 闭包(Closure)通常是指词法闭包,是一个持有外部环境变量的函数。外部环境是指闭包定义时所在的词法作用域。外部环境变量,在函数式编程范式中也被称为自由变量,是指并不是在闭包内定义的变量。将自…...
LLM漫谈(五)| 从q star视角解密OpenAI 2027年实现AGI计划
最近,网上疯传OpenAI2027年关于AGI的计划。在本文,我们将针对部分细节以第一人称进行分享。 摘要:OpenAI于2022年8月开始训练一个125万亿参数的多模态模型。第一个阶段是Arrakis,也叫Q*,该模型于2023年12月完成训练&…...
【echart】数据可视化+vue+vite遇到问题
1、vue3使用echars图表报错:"Initialize failed:invalid dom" 原因是因为:Dom没有完成加载时,echarts.init() 就已经开始执行了,获取不到Dom,无法进行操作 解决:加个延时 onMounted(async () …...
mac m1安装和使用nvm的问题
mac m1安装和使用nvm的问题 使用nvm管理多版本node 每个项目可能用的node版本不同,所以需要多个版本node来回切换 但是最近遇到安装v14.19.0时一直安装失败的问题。 首先说明一下,用的电脑是mac M1芯片 Downloading and installing node v14.19.0... …...
git泄露
git泄露 CTFHub技能树-Web-信息泄露-备份文件下载 当前大量开发人员使用git进行版本控制,对站点自动部署。如果配置不当,可能会将.git文件夹直接部署到线上环境。这就引起了git泄露漏洞。 工具GitHack使用:python2 GitHack.py URL地址/.git/ git命令…...
Java项目:78 springboot学生宿舍管理系统的设计与开发
作者主页:源码空间codegym 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 系统的角色:管理员、宿管、学生 管理员管理宿管员,管理学生,修改密码,维护个人信息。 宿管员…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
