多目标跟踪框架boxmot介绍

news2024/11/15 21:53:26

引言

boxmot由mikel brostrom开发,用于目标检测,分割和姿态估计模型的SOTA(state of art)跟踪模块,现已加入python第三方库 PYPI,可用pip包管理器进行安装。
boxmot所支持的跟踪器采用外观特征识别方法,如重型ReID(CLIRdID)和轻型ReID(LightMBN, OSNet等),来识别不同图像帧中同一个目标。这些ReID权文件在运行boxmot时自动下载,无需事先下载checkpoint文件。
boxmot目前支持的对象检测模型有:yolov8, yolo-NAS和YOLOX。支持的跟踪器:BoTSORT, DeepOCSORT, OCSORT, HybridSORT, ByteTrack, StrongSORT。之前常用的DeepSort由增强型的StrongSORT取代。
boxmot可以看作一个软件封装器,将多种对象检测模型与不同的目标跟踪器组合,实现多目标跟踪。

boxmot安装

安装以linux系统为例,假定该系统已经安装有python >=3.8,且建立好虚拟环境。

将boxmot安装到yolo_tracking目录:

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

以上命令操作过程,即基本完成所需运行的python语言,pytorch模块运行环境。需要说明,这里还需要安装ultralytics相关模块。不过,在yolo_tracking/examples/track.py中,程序自动检查是否安装ultralytics。若没有,则自动安装mikel-brosrom github目录中保存的ultralytics v8.0.146到虚拟环境。需要注意:boxmot v10.0.43仅与ultralytics v8.0.146兼容,若安装ultralytics最新版本将出现莫名错误。
利用examples/track.py安装ultralytics与boxmot现有版本兼容。这里有个问题,track程序将ultralytics安装到虚拟环境,而不在工作目录yolo_tracking下,这样调试程序时,不能跟踪到ultralytics相关的程序模块。当然可以对python调试器做一些相应的配置,就更沟跟踪到虚拟环境的模块,但是操作很麻烦。
把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到工作目录yolo_tracking,这样在python程序调试时,可以跟踪到ultralytics模块。为了防止混淆,将examples/track.py中安装ultralytics语句注释掉:

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

运行示例

运行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 

运行 yolo_nas + strongsort 示例:

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 

track.py程序运行解析

examples/track.py中,经繁琐的模型初始化后,每帧图像的检测-跟踪处理开始于循环:

for frame_idx, r in enumerate(results)

即,每帧产生一个results,对每帧results写入MOT跟踪文件,而实际的处理看跟踪results的跳转。这里跳转至
ultralytics.engine.predictor.py 中的 stream_inference()函数,略过某些初始化,看函数中的循环:

for batch in self.dataset

其中重要的处理在:

# Preprocess              
with profilers[0]:
    im = self.preprocess(im0s)       #1 图像格式处理,提取帧内容到数组。
# Inference
with profilers[1]
    preds = self.inference(im, *args, **kwargs)   #2 对象检测器,提取帧内目标。

# Postprocess
            with profilers[2]:                                 # 3  对所提取目标的后处理,即对跟踪器的目标输入,进行某种处理。
                if isinstance(self.model, AutoBackend):                           
                    self.results = self.postprocess(preds, im, im0s)           # ultralytics内定义的检测器处理方法,  如 yolov8
                else:
                    self.results = self.model.postprocess(path, preds, im, im0s)   # ultralytics之外的检测器处理, 如 yolo_nas, yolox
            with profilers[3]:
                self.run_callbacks('on_predict_postprocess_end')         # 4  构造跟踪器 tracker, 对检测目标的跟踪
  1. preprocess, 输入图像处理。
  2. inference, 推理,目标检测器提取图像帧中的目标。
  3. postprocess, 目标检测器输出preds的处理, yolov8用 non_max_suppression(); 非ultralytics的目标检测器(yolo_nas, yolox)则貌似没有处理。
  4. postprocess_end,跟踪器处理,输出跟踪结果results。
    yolov8以及之前的版本,yolov3, yolov5等采用non_max_suppression(preds, …)来去除不可信的多余目标,且可根据classes来筛选需要保留的目标类别,从而减少目标数量,为后续的跟踪器创造较好的工作环境,减少跟踪器运行时间。因为跟踪器按照目标数量逐一迭代产生跟踪轨迹tracks,迭代为串行运算,目标越多跟踪时间越长。Postprocess执行non_max_supperssion。
    对于yolo-nas,由Deci AI公司开发,目前尚未公开,boxmot无法筛选目标类别,所以,postprocess对preds基本没有处理,直接送到跟踪器tracker。
    最后,on_predict_postprocess_end执行跟踪器操作,输入preds,输出results。

图1
图1 yolov8 postprocess,经non_max_suppression(),筛选出小车对象(classes=2)。

在这里插入图片描述
图2 yolo_nas postprocess, boxmot目前不能通过筛选classes目标,跟踪输出多个类型目标。

ultralytics.trackers.track.py执行函数 on_predict_postprocess_end, boxmot所支持的跟踪器定义在 boxmot.trackers目录中。
完成 Preprocess, Inference, Postprocess后,得到跟踪输出results,进入可视化过程,在输入视频上绘制跟踪框;标注目标id、类型、置信度等参数等。
由此,完成一帧图像的检测-跟踪-可视化。predictor.py函数stream_inference对一帧图像处理,track.py中的循环体(for frame_idx, r in enumerate(results))对输入视频逐帧处理。

examples目录下还有两个可执行文件val.py, evolve.py
val.py 根据选定的benchmark(MOT16, MOT17, MOT20),对检测器+跟踪器组合做性能评估,跟踪类型为persons。
以下benchmark = MOT17, yolov8s + strongsort的评估结果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
看来MOT-17指标与mikel brostrom提供的评估指标还有相当差距,原因不明。此外,本人运行得到的MOT-16各项指标与MOT-17倒是相差很小。

evolve.py 对跟踪器进行配置参数优化,就是在val.py过程提供评估指标,采用NSGA-II多目标遗传算法调整跟踪器配置参数,迭代运行,实现配置参数优化。显然,这是耗时较多的计算过程,尚未尝试。

跟踪框可视化

此处记录跟踪框可视化过程,便于对跟踪框所标注的目标信息进行修改显示。对此部分内容不感兴趣的读者可忽略。
从一帧图像的处理着手,见predictor.py 中函数stream_inference(), 其中看注释Visualize, save, write results下面的循环:

for i in range(n):
    if self.args.verbose or self.args.save or self.args.save_txt or self.args.show:   ###############
                    s += self.write_results(i, self.results, (p, im, im0))   # 此处进入跟踪框可视化

函数write_results部分:

def write_results(self, idx, results, batch):

    if self.args.save or self.args.show:  # Add bbox to image
            plot_args = {
                'line_width': self.args.line_width,
                'boxes': self.args.boxes,
                'conf': self.args.show_conf,
                'labels': self.args.show_labels}
            if not self.args.retina_masks:
                plot_args['im_gpu'] = im[idx]
            self.plotted_img = result.plot(**plot_args)     ####进入plot

result.plot在 ultralytics.engine.results.py定义,模块引用

from ultralytics.utils.plotting import Annotator

下面是result.plot函数使用类Anootator

annotator = Annotator(                                       #定义实例annotator
            deepcopy(self.orig_img if img is None else img),
            line_width,
            font_size,
            font,
            pil or (pred_probs is not None and show_probs),  # Classify tasks default to pil=True
            example=names)
            ...
# Plot Detect results
if pred_boxes and show_boxes:
            for d in reversed(pred_boxes):
                c, conf, id = int(d.cls), float(d.conf) if conf else None, None if d.id is None else int(d.id.item())
                name = ('' if id is None else f' {id} ')    
                label = (f'{name} {conf:.2f}' if conf else name) if labels else None
                annotator.box_label(d.xyxy.squeeze(), label, color=colors(c, True))     # 进入annotator.box_label , 绘制bbox框。

实际的跟踪框bbox绘制在函数 annotator.box_label(), 这个可视化与mikel brostrom之前的版本(v3, v4, v5, v6)一致,都用ultralytics.utils.plotting.py。找到这个annotator.box_label,可以更改跟踪框显示方式,因为默认的label参数太多(id, class_name, conf),当图像帧中目标很多时,显示label一团糟,根本看不清。找到修改地方就主动。见图1,图2的简洁label显示。

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

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

相关文章

一文了解VR全景在城市园区和电子楼书的应用

引言: 虚拟现实(VR)技术在日常生活中越发普及,已经成为众多行业的宣传工具,房地产行业近些年来热度较低,VR全景为房地产展示带来了新方式,为购房者提供更真实、更直观的体验。 一.…

练[MRCTF2020]Ez_bypass

[MRCTF2020]Ez_bypass 文章目录 [MRCTF2020]Ez_bypass掌握知识解题思路关键paylaod 掌握知识 ​ 代码审计,md5函数绕过,is_numeric函数绕过,弱等于的字符串和数字类型绕过 解题思路 打开题目链接,发现是代码审计题目&#xff0…

基于猫群优化的BP神经网络(分类应用) - 附代码

基于猫群优化的BP神经网络(分类应用) - 附代码 文章目录 基于猫群优化的BP神经网络(分类应用) - 附代码1.鸢尾花iris数据介绍2.数据集整理3.猫群优化BP神经网络3.1 BP神经网络参数设置3.2 猫群算法应用 4.测试结果:5.M…

buuctf-[BSidesCF 2020]Had a bad day 文件包含

打开环境 就两个按钮,随便按按 url变了 还有 像文件包含,使用php伪协议读取一下,但是发现报错,而且有两个.php,可能是自己会加上php后缀 所以把后缀去掉 /index.php?categoryphp://filter/convert.base64-encode/resourcei…

从0开始深入理解并发、线程与等待通知机制(中)

一,深入学习 Java 的线程 线程的状态/生命周期 Java 中线程的状态分为 6 种: 1. 初始(NEW):新创建了一个线程对象,但还没有调用 start()方法。 2. 运行(RUNNABLE):Java 线程中将就绪(ready)和…

Endnote修改参考文献(References)的期刊全称为缩写

一、准备(下载)所需要的期刊缩写列表 (Term Lists) 我已经下载并上传了一份Trem Lists 链接: 在不列颠哥伦比亚大学图书馆网站导出所有期刊名和缩写,大概1W的期刊名字,期刊名字和缩写截至2021.12.03 哥伦…

【抢先体验】开通使用 ChatGPT 语音版功能保姆级教程

大家好,我是苍何,一个土木转码的非典型程序员,也是一名技术管理者,同时也是 AI 应用的探索者。今天在视频号上看到和 ChatGPT 语音对话的视频,其声音的真实感太让人震撼了,于是也想去抢先体验一下 ChatGPT …

学习记忆——宫殿篇——记忆宫殿——记忆桩——卧室——莫兰勋爵在地铁走失的案子

《神探夏洛克》第三季第一集中提到“思维殿堂”,其实指的就是记忆宫殿。讲述了一个名叫莫兰勋爵在地铁走失的案子,这里简单给大家罗列以下破案信息: 订阅报纸的男人、伦敦养狗的女人、穿着黑色运动的非裔女人、松木、云杉、雪松、新樟脑球、碳…

js——深拷贝和浅拷贝

深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的。对于基本数据类型,例如字符串、数字、布尔值等,由于它们是按值传递的,所以不存在深拷贝和浅拷贝的问题。 深拷贝 将对象从内存中完整拷贝出来,从堆内存中开辟一个新的…

mac电脑任务管理器 Things3 for Mac中文

Things 3是一款效率软件,可以帮助用户规划一天行程、管理项目,并使使用者按部就班地朝目标迈进。以下是Things 3的主要特点和功能: 待办事项:以“待办事项”为基本组成部分,每一则待办事项都是迈向大成就的一小步。用…

【每日一题】买卖股票的最佳时机含冷冻期

文章目录 Tag题目来源题目解读解题思路方法一:动态规划空间优化 写在最后 Tag 【动态规划】【数组】【2023-10-05】 题目来源 309. 买卖股票的最佳时机含冷冻期 题目解读 这是股票系列问题的第五篇了,要求求出买卖股票的最佳时期以获得最大的利润&…

基于spirngboot人事考勤管理信息系统

一:功能介绍 本系统前端采用vue框架以及Elemnt-UI,后端采用springboot、mysql、redis、mybatis等技术栈。 主要功能有登录、员工考勤、数据统计、薪资管理、权限管理、打卡管理、考勤审核、请假审批、薪资发放、报表统计、文件上传、文件下载、考勤设置、请假设置。…

Spring Boot注册Web组件

文章目录 什么是Web组件?注册Servlet注册Filter注册Listener总结 🎉欢迎来到架构设计专栏~Spring Boot注册Web组件 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒🍹✨博客主页:IT陈寒的博客🎈该系列文章专栏:架构设计&a…

安装matplotlib__pygame,以pycharm调入模块

安装pip 安装matplotlib 安装完毕,终端输入pip list检查 导入模块出现bug,发现不是matplotlib包的问题,pycharm版本貌似不兼容,用python编辑器可正常绘图,pygame也可正常导入。 ​​​​​​​ pycharm版本问题解决 终…

k8s集群-7 service

工作负载的应用是如何暴露出去的 解决访问问题 Service可以看作是一组提供相同服务的Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。 service默认只支持4层负载均衡能力,没有7层功能。(可以通过Ingress实现) service的类型: C…

【每日一题】买卖股票的最佳时机含手续费

文章目录 Tag题目来源题目解读解题思路方法一:动态规划空间优化 写在最后 Tag 【动态规划】【数组】【2023-10-06】 题目来源 714. 买卖股票的最佳时机含手续费 题目解读 本题与 122. 买卖股票的最佳时机 II 如出一辙,仅仅是增加了交易的手续费用。 解…

人工智能:定义未来,揭开历史神秘面纱,展望无限可能!

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是尘缘,一个在CSDN分享笔记的博主。📚📚 👉点击这里,就可以查看我的主页啦!👇&#x…

python读取vivo手机截图,将满屏图片文件移动别的路径

问题之初 python读取vivo手机截图, 将满屏图片文件移动别的路径好多这样的图片,占用手机大量的内存,食之无味弃之可惜!那么会复制粘贴👀代码的我们我们今天就把这些图片筛选清理掉。 这段代码 原有逻辑的基础上&…

MySQL中的 增 删 查 改(CRUD)

目录 新增 insert into 表名 value(数据,数据),.......; insert into 表名(列1,列2.....) value(数据,数据),.......; datatime 类型的数据如何插入? 查询 select * from 表名…