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

yolov8 strongSORT多目标跟踪工具箱BOXMOT

1 引言

多目标跟踪MOT项目在Github中比较完整有:BOXMOT , 由mikel brostrom提供。在以前的版本中,有yolov5+deepsort(版本v3-v5), yolov8+strongsort(版本v6-v9),直至演变到v10,名称BOXMOT。
BOXMOT提供三种对象检测器:yolov8, yolo_nas, yolox; 支持多个跟踪器:BoTSORT, DeepOCSORT, OCSORT, Hybridsort, ByteTrack, StrongSORT 。以前常见的DeepSort在此由增强型StrongSORT替代。

2 安装BOXMOT

boxmot安装
安装环境:Ubuntu18.04,python 3.8,已建有虚拟环境。

将boxmot从github克隆到本地,建立yolo_tracking目录:

git clone https://github.com/mikel-brostrom/yolo_tracking.git
cd yolo_tracking
pip install -v -e .

第三个命令pip install -v -e. 相当于 python setup.py develop,即根据setup.py执行安装,其中“develop”参数将软件包以开发模式安装到Python环境中,以便在开发过程中能够即时反映源代码的修改。
完成BOXMOT安装后,看看yolo_tracking下面有什么:
在这里插入图片描述
图1 yolo_tracking目录
见图1, BOXMOT支持的三个对象检测器定义文件yolonas.py, yolov8.py, yolox.py在examples/detectors目录。跟踪器tracker在boxmot/trackers目录下。 boxmot/appearance目录是tracker所需使用的外观识别REID模块。boxmot/configs为tracker的参数构造文件。boxmot/motion目录是运动预测用Kalman滤波器。
下一步根据需要,安装三个对象检测器。

2.1 安装ultralytics

对象检测器yolov8需要安装ultralytics python库,需注意,BOXMOT适用ultralytics v8.0.146,而最新的版本不适用。
安装ultralytics到yolo_tracking目录,操作如下:
先删除虚拟环境下和系统中可能安装的ultralytics模块:

pip uninstall ultralytics

克隆ultralytics v8.0.146

git clone https://github.com/mikel-brostrom/ultralytics.git

此操作在home目录下产生ultralytics目录。我们需要将ultralytics二级目录:~/ultralytics/ultralytics移动到yolo_tracking目录下,完成安装ultralytics。这样在python程序调试时,可以跟踪到ultralytics模块。为了防止混淆,将examples/track.py和val.py中安装ultralytics语句注释掉:

#__tr = TestRequirements()
#__tr.check_packages(('ultralytics @ git+https://github.com/mikel-brostrom/ultralytics.git', ))  # install  ultralytics

现在,已实现基础对象检测器yolov8的运行环境,可执行跟踪track.py和评估val.py程序。
运行yolov8s+strongsort对输入视频进行车辆跟踪示例:

python examples/track.py  \--yolo-model yolov8s    \--reid-mode  osnet_x0_25_market1501.pt   \--source     ~/yolo_tracking/MOT16-13-h264.mp4  \ --save         \--show         \--classes 2     \--tracking-method strongsort 

若已下载yolov8s权重文件yolov8s.pt,可在–yolo-model 变量中指定文件路径,若没下载,则track.py根据"yolov8s"自动从网上下载。

2.2 安装yoloNAS

yoloNAS需安装super-gradients:

pip install super-gradients

运行yoloNAS,实现的示例:

python examples/track.py  \--yolo-model yolo_nas_s    \--reid-mode  osnet_x0_25_market1501.pt   \--source     ~/yolo_tracking/MOT16-13-h264.mp4  \ --save         \--show         \--classes 2     \--tracking-method strongsort  

BOXMOT使用yoloNAS不能对跟踪对象类进行筛选,而把图像中所有符合COCO数据集类型的对象都提取,大数量目标对跟踪器造成很大负担,运行速度慢。
在yolonas.py的postprocess函数中增加类型过滤:

def postprocess(self, path, preds, im, im0s):results = []for i, pred in enumerate(preds):if pred is None:pred = torch.empty((0, 6))r = Results(path=path,boxes=pred,orig_img=im0s[i],names=self.names)results.append(r)else:pred[:, :4] = ops.scale_boxes(im.shape[2:], pred[:, :4], im0s[i].shape)# filter boxes by classes   ############################################pred = pred[torch.isin(pred[:, 5].cpu(), torch.as_tensor(self.args.classes))]   # added by someoner = Results(path=path,boxes=pred,orig_img=im0s[i],names=self.names)results.append(r)return results

2.3 安装YOLOX

YOLOX官网克隆到本地,产生YOLOX目录。

git clone https://github.com/Megvii-BaseDetection/YOLOX.git

将YOLOX目录下三个子目录:yolox, tools, exps 复制到yolo_tracking,完成YOLOX环境。
实现YOLOX对象检测器的跟踪示例

python examples/track.py  \--yolo-model yolox_s    \--reid-mode  osnet_x0_25_market1501.pt   \--source     ~/yolo_tracking/MOT16-13-h264.mp4  \ --save         \--show         \--tracking-method strongsort  

此BOXMOT版本v10.043在使用YOLOX上有限制,从track.py程序下载的权重文件yolox_s仅支持一个类型“person”的对象检测,不支持其他对象检测。从YOLOX Github下载权重文件yolox_s.pth支持COCO数据集的80个类型,这里需要修改:
1 YOLOX官网下载的权重文件yolox_s.pth,80个类型; BOXMOT,track.py下载的yolox_s.pt,1个person类型。在examples/detectors/yolox.py中如下修改:

def __init__(self, model, device, args):self.args = argsself.pt = Falseself.stride = 32  # max stride in YOLOX# model_type one of: 'yolox_n', 'yolox_s', 'yolox_m', 'yolox_l', 'yolox_x'model_type = self.get_model_from_weigths(YOLOX_ZOO.keys(), model)if model_type == 'yolox_n':exp = get_exp(None, 'yolox_nano')else:exp = get_exp(None, model_type)LOGGER.info(f'Loading {model_type} with {str(model)}')# download crowdhuman bytetrack modelsif not model.exists() and model.stem == model_type:LOGGER.info('Downloading pretrained weights...')gdown.download(url=YOLOX_ZOO[model_type + '.pt'],output=str(model),quiet=False)# "yolox_s.pt" 表示num_classes =1,  "yolox_s.pth"表示num_classes = 80。#    boxmot下载的ckpt只处理“person”类型,#     github.com/Megvii-BaseDetection/YOLOX提供的ckpt用于num_classes,可处理多种类型。# needed for bytetrack yolox people models# update with your custom model needsexp.num_classes = 1             self.num_classes = 1elif model.stem == model_type:exp.num_classes = 1self.num_classes = 1_, file_extension = os.path.splitext(str(model))            if file_extension == ".pth":exp.num_classes = 80           self.num_classes = 80if exp.num_classes ==1:    self.img_normal = True  #num_classes = 1,    BOXMOT format: 0.0-1.0else:self.img_normal = False   #num_classes = 80, YOLOX website ckpt format:  0-255 ckpt = torch.load(str(model),map_location=torch.device('cpu'))self.model = exp.get_model()self.model.eval()self.model.load_state_dict(ckpt["model"])self.model = fuse_model(self.model)self.model.to(device)self.model.eval()

这里,对 YoloXStrategy(YoloInterface)类增加类变量:self.num_classes,适应来自不同网站的yolox权重文件。

2 YOLOX官网yolox detector所处理的图像为0-255数据,而BOXMOT yolox detector所处理图像数据为0.0 - 1.0,需要针对不同权重文件对图像输入进行变换。对 YoloXStrategy(YoloInterface)类增加类变量:self.img_normal。

更改yolox.py postprocess

def postprocess(self, path, preds, im, im0s):results = []for i, pred in enumerate(preds):pred = postprocess(pred.unsqueeze(0),  # YOLOX postprocessor expects 3D araryself.num_classes,                                             #  1   num_classes  conf_thre=0.5,              #0.1nms_thre=0.7,            # 0.45class_agnostic=True,   )[0]

更改ultralytics/engine/predictor.py preprocess函数

def preprocess(self, im):"""Prepares input image before inference.Args:im (torch.Tensor | List(np.ndarray)): BCHW for tensor, [(HWC) x B] for list."""not_tensor = not isinstance(im, torch.Tensor)if not_tensor:im = np.stack(self.pre_transform(im))im = im[..., ::-1].transpose((0, 3, 1, 2))  # BGR to RGB, BHWC to BCHW, (n, 3, h, w)im = np.ascontiguousarray(im)  # contiguousim = torch.from_numpy(im)img = im.to(self.device)img = img.half() if self.model.fp16 else img.float()  # uint8 to fp16/32if not_tensor:                                 # -------------------------------------------------------------------------if not self.model.img_normal:return img                          # yolox  num_classes = 80  , img 取值 0-255                                    img /= 255                              # 0 - 255 to 0.0 - 1.0   # yolov8, yolo_nas and yolox  num_classes = 1的ckpt,img 取值 0.0 - 1.0 。return img

注:如果更改BOXMOT中默认的yolox单一类型处理模式,由于对ultralytics/engine/predictor.py preprocess方法做了修改,会涉及到yolov8和yoloNAS,所以:
yolov8: ultralytics/nn/autobackend.py, 类 AutoBackend, 增加类变量 self.img_normal = True
yoloNAS:examples/detectors/yolonas.py, 类 YoloNASStrategy, 增加类变量 self.img_normal = True

当然,如果不改变BOXMOT默认的yolox,则无需改变yolov8和yoloNAS。

对比BOXMOT 默认yolox_s.pt和YOLOX官网yolo_s.pth,两者分别运行val.py

python examples/val.py   \
--yolo-model    examples/weights/yolox_s.pt  \   --tracking-method  deepocsort   \--benchmark  MOT17python examples/val.py   \
--yolo-model    examples/weights/yolox_s.pth  \   --tracking-method  deepocsort   \--benchmark  MOT17

得到如下结果(取MOT17 - FRCNN每个序列的前10帧):

                                  HOTA           MOTA          MOTP          IDF1
yolox_s.pt             68.294         67.268         81.267       81.403   
yolox_s.pth           60.038         52.223         78.765       70.531

这因为yolox_s.pt是针对拥挤行人情况的权重,而yolox_s.pth则适用于COCO各种类型,所以评价指标有提高。

相关文章:

yolov8 strongSORT多目标跟踪工具箱BOXMOT

1 引言 多目标跟踪MOT项目在Github中比较完整有:BOXMOT , 由mikel brostrom提供。在以前的版本中,有yolov5deepsort(版本v3-v5), yolov8strongsort(版本v6-v9),直至演变…...

如何开发一款跑酷游戏?

跑酷游戏(Parkour Game)是一种流行的视频游戏类型,玩家需要在游戏中控制角色进行极限动作、跳跃、爬墙和各种动作,以完成各种挑战和任务。如果你有兴趣开发一款跑酷游戏,以下是一些关键步骤和考虑事项: 游…...

使用宝塔面板在Linux上搭建网站,并通过内网穿透实现公网访问

文章目录 前言1. 环境安装2. 安装cpolar内网穿透3. 内网穿透4. 固定http地址5. 配置二级子域名6. 创建一个测试页面 前言 宝塔面板作为简单好用的服务器运维管理面板,它支持Linux/Windows系统,我们可用它来一键配置LAMP/LNMP环境、网站、数据库、FTP等&…...

Unity可视化Shader工具ASE介绍——6、通过例子说明ASE节点的连接方式

大家好,我是阿赵。继续介绍Unity可视化Shader编辑插件ASE的用法。上一篇已经介绍了很多ASE常用的节点。这一篇通过几个小例子,来看看这些节点是怎样连接使用的。   这篇的内容可能会比较长,最终是做了一个遮挡X光的效果,不过把这…...

VUE3基础知识梳理

VUE3基础知识梳理 一、vue了解和环境搭建1.vue是什么:cn.vuejs.org/vuejs.org2.渐进式框架3.vue的版本4.vueAPI的风格5.准备环境5.1.创建vue项目5.2.vue的目录结构 二、vue3语法1.干净的vue项目2.模板语法2.1 文本插值2.2属性绑定2.3条件渲染2.4列表渲染2.5通过key管…...

Java架构师缓存通用设计方案

目录 1 采用多级缓存2 缓存数据尽量前移3 静态化4 数据平衡策略5 jvm缓存的问题6 redis存放数据解决7 redis垂直拆分8 总结1 采用多级缓存 在实际应用中需要考虑的实际问题。首先,前端页面可以做缓存,虽然图上没有显示,但在现实应用中这是提高性能的一个重要方面。前端页面缓…...

2023年【危险化学品生产单位安全生产管理人员】及危险化学品生产单位安全生产管理人员模拟考试题

题库来源:安全生产模拟考试一点通公众号小程序 危险化学品生产单位安全生产管理人员考前必练!安全生产模拟考试一点通每个月更新危险化学品生产单位安全生产管理人员模拟考试题题目及答案!多做几遍,其实通过危险化学品生产单位安…...

微信小程序 在bindscroll事件中监听scroll-view滚动到底

scroll-view其实提供了一个 bindscrolltolower 事件 这个事件的作用是直接监听scroll-view滚动到底部 但是 总有不太一样的情况 公司的项目 scroll-view 内部 最下面有一个 类名叫 bottombj 的元素 我希望 滚动到这个 bottombj 上面的时候就开始加载滚动分页 简单说 bottombj这…...

收银系统商品定价设计思考

一、背景 因为门店系统里商品总共也就几万款,一直以来都是根据条码由总部统一定价销售,现在有加盟店,各门店也有进行各自促销活动的需求,这就需要放开门店自主定价权,所以近段时间系统在商品定价上做了扩展。 二、商…...

Kotlin函数作为参数指向不同逻辑

Kotlin函数作为参数指向不同逻辑 fun sum(): (Int, Int) -> Int {return { a, b -> (a b) } }fun multiplication(): (Int, Int) -> Int {return { a, b -> (a * b) } }fun main(args: Array<String>) {var math: (Int, Int) -> Intmath sum()println(m…...

读书笔记—《如何阅读一本书》

读书笔记—《如何阅读一本书》 一、阅读的层次1、主动阅读的基础一个阅读者要提出的四个基本问题 2、基础阅读&#xff08;第一层&#xff09;3、检视阅读&#xff08;第二层&#xff09;4、分析阅读&#xff08;第三层&#xff09; 二、阅读不同读物的方法三、阅读的最终目标1…...

Kafka数据同步原理详解

Kafka数据同步原理详解 Kafka是一种分布式的消息队列系统&#xff0c;它具有高吞吐量、可扩展性和分布式特性等优势。在Kafka中&#xff0c;数据按照主题进行分区&#xff0c;每个主题都有一组分区。每个分区都有自己的生产者和消费者&#xff0c;生产者负责向分区中写入消息&…...

C++课程总复习

一、c的第一条程序 1.cout cout >输出类对象&#xff0c;用来输出的&#xff0c;可以自动识别类型&#xff0c;所以不需要加格式符号 << 插入符&#xff08;输出符号&#xff09; endl 换行>\n #include <iostream> //#预处理 //include 包含 相应的头…...

数据结构—顺序表

目录 1.线性表 2.顺序表概念 3.实现顺序表 (1)声明结构体 (2)初始化 (3)打印数据 (4) 销毁 (5)尾插&头插 尾插 判断是否扩容 头插 (6)尾删&头删 尾删 头删 (7)指定位置插入元素 (8)删除指定位置元素 (9)查找指定元素位置 (10)修改指定位置元素 完整版…...

企业服务器租用对性能有什么要求呢?

企业租用服务器租用首要的是稳定&#xff0c;其次是安全&#xff0c;稳定是为了让企业的工作能够顺利进行&#xff0c;只有性能稳定的服务器才能保证网站之类的正常工作&#xff0c;就让小编带大家看一看有什么要求吧&#xff01; 服务器简单介绍。服务器是在网络上为其它客户机…...

2731.移动机器人

2731. 移动机器人 - 力扣&#xff08;LeetCode&#xff09; 有一些机器人分布在一条无限长的数轴上&#xff0c;他们初始坐标用一个下标从 0 开始的整数数组 nums 表示。当你给机器人下达命令时&#xff0c;它们以每秒钟一单位的速度开始移动。 给你一个字符串 s &#xff0c…...

相交链表Java

给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 nu11。 以下有两种解决方法: 一种是用Map,利用其key值唯一的方法去判断(也可以使用set,set在add时,已存在的元素会返回false,不存在的返回…...

第二章:OSI参考模型与TCP/IP模型

OSI参考模型与TCP/IP模型 一、OSI参考模型二、TCP/IP模型2.1 四层分法&#xff08;书上&#xff09;2.2 五层分法&#xff08;实际厂商&#xff09;2.3 数据封装和解封装2.3.1 封装2.3.2 解封装2.3.3 TCP/IP分层封装2.3.4 数据封装和解封装过程 一、OSI参考模型 1.物理层 定义电…...

知识图谱04——openGL与ubuntu22.04

跑图神经网络的时候遇到了如下问题 libGL error: failed to load driver: iris libGL error: MESA-LOADER: failed to open iris: /usr/lib/dri/iris_dri.so: 无法打开共享对象文件: 没有那个文件或目录 (search paths /usr/lib/x86_64-linux-gnu/dri:\$${ORIGIN}/dri:/usr/li…...

如何看待为了省小钱而花费时间

相信每个人都会遇到这种情况&#xff1a;购买东西时想着货比三家或者想办法领优惠券、凑单等就可以省下一些钱&#xff0c;但是需要花费不少时间和精力。这时就开始犹豫了&#xff1a;省钱是必要的&#xff0c;需要居安思危&#xff0c;等到缺钱的时候不会后悔&#xff1b;又想…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...