基于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项目、学习资料、技术互助 文中获取源码 项目介绍 系统的角色:管理员、宿管、学生 管理员管理宿管员,管理学生,修改密码,维护个人信息。 宿管员…...
ArcGis Pro Python工具箱教程 03 工具箱中工具自定义
ArcGis Pro Python工具箱教程 03 工具箱中工具自定义 用于定义工作工具类的方法 工具方法必选或可选描述__ init __必需项right-aligned 初始化工具类。getParameterInfo可选定义工具的参数。isLicensed可选返回工具是否获得执行许可。updateParameters可选在用户每次在工具对…...
【C++初阶】之类和对象(中)
【C初阶】之类和对象(中) ✍ 类的六个默认成员函数✍ 构造函数🏄 为什么需要构造函数🏄 默认构造函数🏄 为什么编译器能自动调用默认构造函数🏄 自己写的构造函数🏄 构造函数的特性 ✍ 拷贝构造…...
Vue2(十一):脚手架配置代理、github案例、插槽
一、脚手架配置代理 1.回顾常用的ajax发送方式: (1)xhr 比较麻烦,不常用 (2)jQuery 核心是封装dom操作,所以也不常用 (3)axios 优势:体积小、是promis…...
在宝塔面板中,为自己的云服务器安装SSL证书,为所搭建的网站启用https(主要部分攻略)
前提条件 My HTTP website is running Nginx on Debian 10(或者11) 时间:2024-3-28 16:25:52 你的网站部署在Debain 10(或者11)的 Nginx上 安装单域名证书(默认)(非泛域名…...
学习JavaEE的日子 Day32 线程池
Day32 线程池 1.引入 一个线程完成一项任务所需时间为: 创建线程时间 - Time1线程中执行任务的时间 - Time2销毁线程时间 - Time3 2.为什么需要线程池(重要) 线程池技术正是关注如何缩短或调整Time1和Time3的时间,从而提高程序的性能。项目中可以把Time…...
@Transactional 注解使用的注意事项
事务管理 事务管理在系统开发中是不可缺少的一部分,Spring提供了很好的事务管理机制,主要分为编程式事务和声明式事务两种。 编程式事务: 是指在代码中手动的管理事务的提交、回滚等操作,代码侵入比较强。 声明式事务ÿ…...
电商系列之库存
> 插:AI时代,程序员或多或少要了解些人工智能,前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 坚持不懈,越努力越幸运,大家…...
Apache HBase(二)
目录 一、Apache HBase 1、HBase Shell操作 1.1、DDL创建修改表格 1、创建命名空间和表格 2、查看表格 3、修改表 4、删除表 1.2、DML写入读取数据 1、写入数据 2、读取数据 3、删除数据 2、大数据软件启动 一、Apache HBase 1、HBase Shell操作 先启动HBase。再…...
【设计模式】原型模式详解
概述 用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象 结构 抽象原型类:规定了具体原型对象必须实现的clone()方法具体原型类:实现抽象原型类的clone()方法,它是可以被复制的对象。访问类&…...
企微侧边栏开发(内部应用内嵌H5)
一、背景 公司的业务需要用企业微信和客户进行沟通,而客户的个人信息基本都存储在内部CRM系统中,对于销售来说需要一边看企微,一边去内部CRM系统查询,比较麻烦,希望能在企微增加一个侧边栏展示客户的详细信息…...
主做熟人推荐的招聘网站/线下营销方式主要有哪些
岗位管理_实现显示、删除、添加、修改 |-分析通用增删改查功能及命名规范 |-岗位管理----显示、删除 |-第一步:岗位管理空架action的搭建 |-第一段:action准备 和 struts.xml中配置 和 空jsp页面 |-第二段:service 准备 |-第二步:…...
网站代理建设/长尾关键词排名工具
// 判断是否为手机号 isPoneAvailable: function (pone) { var myreg /^[1][3,4,5,7,8][0-9]{9}$/; if (!myreg.test(pone)) { return false; } else { return true; } }, // 判断是否为电话号码 isTelAvailable: function (tel) { var myreg /^(([0\]\d{2,3}-)?(0\d{2,3})-…...
襄阳棋牌网站建设/腾讯广告推广怎么做
复习必备第一章(什么是操作系统:所谓操作系统就是能有效地管理计算机系统中的各种硬件\软件资源、合理的组织计算机的工作流程,从而为程序员\操作员和各类用户创造良好的工作环境的系统软件。操作系统基本特性:并发性(最主要特征),共享性&…...
做网站的域名怎样买/网站排名优化方法
1 把硬盘接上 2 重启系统,如果系统不能识别还要设置一下bios 3 用fdisk查看 fdisk -l,可以看到多了一块硬盘,并且告诉我们没有分区信息 4 用fdisk 进行分区,如 fdisk /dev/sdb 5 格式化新分区 如mkfs.ext3fs ***࿰…...
商城网站建设net2006/网络推广电话销售技巧和话术
git是什么? Git是一个开源的分布式版本控制系统,可以有效、高速的处理从很小到非常大的项目版本管理。Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 git的用途 个人理解: git是一个非常好的多…...
厦门外贸网站建设哪家公司大/app推广一手单
主要内容1.编码问题2.File类的使用3.RandomAccessFile的使用4.I/O 输入输出流编码问题:1 importjava.io.UnsupportedEncodingException;23 public class编码问题 {4 public static voidmain(String[] args) {5 //我们项目的默认编码是GBK6 String s "测试 ABC…...