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

基于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 等。

  1. SORT(Simple Online and Realtime Tracking):这是一种简单而高效的在线多目标跟踪算法,它结合了卡尔曼滤波和匈牙利算法来实现目标跟踪。SORT适用于实时应用,并且在计算资源有限的情况下表现良好。

  2. DeepSort:这是在SORT基础上发展而来的算法,它引入了深度学习技术,特别是卷积神经网络(CNN),用于提取目标的特征表示。DeepSort在目标跟踪的准确性和鲁棒性方面相对于传统方法有所提升。

  3. StrongSort:这是另一种基于深度学习的多目标跟踪算法,它通过设计更强大的特征提取网络和更精细的跟踪策略来提高目标跟踪的性能。

目标跟踪可分为下面几种:

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

模板匹配:顾名思义,这种方法使用预定义的模板在每个视频序列中进行匹配。

基于相关性的跟踪:这种方法用于计算目标对象与后续帧中候选区域之间的相似性。

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

ByteSort

其他MOT算法中移除低置信度检测框的问题主要源于对检测框置信度的阈值设置以及对检测框的筛选策略。因为低置信度的检测框被认为可能是误检测或者不可靠的检测结果,因此会被丢弃以提高跟踪的准确性。然而,这种策略可能会带来一些问题:

  1. 遮挡目标: 低置信度的检测框有时确实可以指示目标的存在,尤其是在目标被部分遮挡或者遮挡物很大时。丢弃这些低置信度的检测框可能会导致漏检目标,因为算法无法正确地识别被遮挡的目标。

  2. 轨迹断裂: 移除低置信度的检测框可能导致轨迹的不连续性,因为目标在一帧中被识别出来,在另一帧中却被移除了。这可能会导致跟踪算法无法正确地维持目标的标识符,从而产生碎片化的轨迹,使跟踪结果不连贯。

ByteTrack考虑低置信度的检测框的原因在于:

  1. 避免漏检: ByteTrack意识到低置信度的检测框可能是有价值的目标信息,尤其是在目标被遮挡的情况下。因此,保留这些检测框有助于避免目标漏检的情况,提高跟踪的完整性。

  2. 减少轨迹断裂: 通过保留低置信度的检测框,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 客户端&#xff0c;而不是 docker 容器的标准输出。只需要在启动时把app 标准输出重定向到 docker标准输出。 测试如下&#xff1a; 1.启动 docker docker run -it -p 60022:22 --name test test:v4 bash -c "service ssh restart;…...

WPF---1.入门学习

&#x1f388;个人主页&#xff1a;靓仔很忙i &#x1f4bb;B 站主页&#xff1a;&#x1f449;B站&#x1f448; &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;WPF &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xf…...

Vue3 + Vite + TS + Element-Plus + Pinia项目(5)对axios进行封装

1、在src文件夹下新建config文件夹后&#xff0c;新建baseURL.ts文件&#xff0c;用来配置http主链接 2、在src文件夹下新建http文件夹后&#xff0c;新建request.ts文件&#xff0c;内容如下 import axios from "axios" import { ElMessage } from element-plus im…...

【Rust】——编写自动化测试(一)

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…...

第十二章 微服务核心(一)

一、Spring Boot 1.1 SpringBoot 构建方式 1.1.1 通过官网自动生成 进入官网&#xff1a;https://spring.io/&#xff0c;点击 Projects --> Spring Framework&#xff1b; 拖动滚动条到中间位置&#xff0c;点击 Spring Initializr 或者直接通过 https://start.spring…...

MySQL索引18连问,谁能顶住

前言 过完这个节&#xff0c;就要进入金银季&#xff0c;准备了 18 道 MySQL 索引题&#xff0c;一定用得上。 作者&#xff1a;感谢每一个支持&#xff1a; github 1. 索引是什么 索引是一种数据结构&#xff0c;用来帮助提升查询和检索数据速度。可以理解为一本书的目录&…...

[flink 实时流基础系列]揭开flink的什么面纱基础一

Apache Flink 是一个框架和分布式处理引擎&#xff0c;用于在无边界和有边界数据流上进行有状态的计算。Flink 能在所有常见集群环境中运行&#xff0c;并能以内存速度和任意规模进行计算。 文章目录 0. 处理无界和有界数据无界流有界流 1. Flink程序和数据流图2. 为什么一定要…...

开放平台 - 互动玩法演进之路

本期作者 1. 背景 随着直播业务和用户规模日益壮大&#xff0c;如何丰富直播间内容、增强直播间内用户互动效果&#xff0c;提升营收数据变得更加关键。为此&#xff0c;直播互动玩法应运而生。通过弹幕、礼物、点赞、大航海等方式&#xff0c;用户可以参与主播的直播内容。B站…...

Linux之进程控制进程终止进程等待进程的程序替换替换函数实现简易shell

文章目录 一、进程创建1.1 fork的使用 二、进程终止2.1 终止是在做什么&#xff1f;2.2 终止的3种情况&&退出码的理解2.3 进程常见退出方法 三、进程等待3.1 为什么要进行进程等待&#xff1f;3.2 取子进程退出信息status3.3 宏WIFEXITED和WEXITSTATUS&#xff08;获取…...

RegSeg 学习笔记(待完善)

论文阅读 解决的问题 引用别的论文的内容 可以用 controlf 寻找想要的内容 PPM 空间金字塔池化改进 SPP / SPPF / SimSPPF / ASPP / RFB / SPPCSPC / SPPFCSPC / SPPELAN &#xfffc; ASPP STDC&#xff1a;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 问:四种信道划分介质访问控制?

目录 正文什么是信道划分介质访问控制&#xff1f;什么是多路复用技术&#xff1f;四种信道划分介质访问控制1. 频分多路复用 FDM2. 时分多路复用 TDM3. 波分多路复用 WDM4. 码分多路复用 CDM 正文 什么是信道划分介质访问控制&#xff1f; 信道划分介质访问控制&#xff08;…...

Rust编程(五)终章:查漏补缺

闭包 & 迭代器 闭包&#xff08;Closure&#xff09;通常是指词法闭包&#xff0c;是一个持有外部环境变量的函数。外部环境是指闭包定义时所在的词法作用域。外部环境变量&#xff0c;在函数式编程范式中也被称为自由变量&#xff0c;是指并不是在闭包内定义的变量。将自…...

LLM漫谈(五)| 从q star视角解密OpenAI 2027年实现AGI计划

最近&#xff0c;网上疯传OpenAI2027年关于AGI的计划。在本文&#xff0c;我们将针对部分细节以第一人称进行分享。​ 摘要&#xff1a;OpenAI于2022年8月开始训练一个125万亿参数的多模态模型。第一个阶段是Arrakis&#xff0c;也叫Q*&#xff0c;该模型于2023年12月完成训练&…...

【echart】数据可视化+vue+vite遇到问题

1、vue3使用echars图表报错&#xff1a;"Initialize failed:invalid dom" 原因是因为&#xff1a;Dom没有完成加载时&#xff0c;echarts.init() 就已经开始执行了&#xff0c;获取不到Dom&#xff0c;无法进行操作 解决&#xff1a;加个延时 onMounted(async () …...

mac m1安装和使用nvm的问题

mac m1安装和使用nvm的问题 使用nvm管理多版本node 每个项目可能用的node版本不同&#xff0c;所以需要多个版本node来回切换 但是最近遇到安装v14.19.0时一直安装失败的问题。 首先说明一下&#xff0c;用的电脑是mac M1芯片 Downloading and installing node v14.19.0... …...

git泄露

git泄露 CTFHub技能树-Web-信息泄露-备份文件下载 当前大量开发人员使用git进行版本控制&#xff0c;对站点自动部署。如果配置不当,可能会将.git文件夹直接部署到线上环境。这就引起了git泄露漏洞。 工具GitHack使用&#xff1a;python2 GitHack.py URL地址/.git/ git命令…...

Java项目:78 springboot学生宿舍管理系统的设计与开发

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 系统的角色&#xff1a;管理员、宿管、学生 管理员管理宿管员&#xff0c;管理学生&#xff0c;修改密码&#xff0c;维护个人信息。 宿管员…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...