yolov5 onnx的部署文件(主要是onnx文件的使用)

第一步。导出onnx文件,然后检查一下
pip install torch onnx onnxruntime   #导入onnxruntime
pip install onnx --upgrade -i https://pypi.tuna.tsinghua.edu.cn/simple  #镜像安装
pip install onnx-simplifier        ##导入onnx的优化器

运行export,py文件,进行onnx模型的导出

python export.py --weights runs/train/exp3/weights/best.pt --img 640 --batch 1 --include onnx   ##

对模型进行优化,检查模型

python -m onnxsim runs/train/exp3/weights/best.onnx output_onnx_model   #对模型进行优化,优化后会在根目录下输出一个output_onnx_model文件
model = onnx.load(output_onnx_model)   #通过路径加载模型
onnx.checker.check_model(model) #检查模型的正确性,正确则不反回任何消息

第二部写一个class来实现模型的加载,通过一个model实现传入图片,模型检测,检测结果的数据及它的检测图片的输出,方便后期脱离yolo架构,将onnx模型对外进行部署

声明这个代码参考了 qq_22487889 博主写的《详细介绍 Yolov5 转 ONNX模型 + 使用ONNX Runtime 的 Python 部署(包含官方文档的介绍)》,链接是https://blog.csdn.net/qq_22487889/article/details/128011883

我只是作了一定的改动,放到这里是方便自己后期落地使用。

代码分三部分 ——在一个py文件里,通过两个方法,一个类来实现

1,onnx模型的加载,及输入变量名的获取

2,输入图片,对图片进行计算,并能输出它的预测框参数

3,绘图+显示。

import onnx
import onnxruntime as ort
import cv2
import numpy as np
from onnxruntime.transformers.models.gpt2.parity_check_helper import inference
from torch import nnCLASSES = ['cat', 'dog']
model_path = '../output_onnx_model'def draw(image, box_data, CLASSES):# -------------------------------------------------------#	取整,方便画框# -------------------------------------------------------boxes = box_data[..., :4].astype(np.int32)  # x1 x2 y1 y2scores = box_data[..., 4]classes = box_data[..., 5].astype(np.int32)for box, score, cl in zip(boxes, scores, classes):top, left, right, bottom = boxprint('class: {}, score: {}'.format(CLASSES[cl], score))print('box coordinate left,top,right,down: [{}, {}, {}, {}]'.format(top, left, right, bottom))cv2.rectangle(image, (top, left), (right, bottom), (255, 0, 0), 2)cv2.putText(image, '{0} {1:.2f}'.format(CLASSES[cl], score),(top, left),cv2.FONT_HERSHEY_SIMPLEX,0.6, (0, 0, 255), 2)return imagedef load_onnx(model_path):#在这里还是先加载模型,然后check一下看看正确否onnx_model = onnx.load(model_path)try:onnx.checker.check_model(onnx_model)except Exception:print("Model incorrect")else:print("Model correct")## 模型进入运行阶段,准备测试onnx_session = ort.InferenceSession(model_path)input_name = onnx_session.get_inputs()[0].name  #明确是一个输入张量,就这样写吧,简简单单return onnx_session, input_nameclass Yolov5ONNX(nn.Module):def __init__(self, onnx_session, input_name):super(Yolov5ONNX,self).__init__()self.model = onnx_sessionself.input_name = input_namedef inference(self, img):""" 1.cv2读取图像并resize2.图像转BGR2RGB和HWC2CHW(因为yolov5的onnx模型输入为 RGB:1 × 3 × 640 × 640)3.图像归一化4.图像增加维度5.onnx_session 推理 """resize_img = cv2.resize(img, (640, 640))   # resize后的原图 (640, 640, 3)image = cv2.cvtColor(resize_img, cv2.COLOR_BGR2RGB)   #cv2读进来是BGR的,一定转成Rgb的,上次研究了一下午就是这里出了问题img = image.transpose(2, 0, 1)  # whc转cwhimg = img.astype(dtype=np.float32)  # onnx模型的类型是type: float32[ , , , ]img /= 255.0img = np.expand_dims(img, axis=0)  # [3, 640, 640]扩展为[1, 3, 640, 640]# img尺寸(1, 3, 640, 640)return img,resize_imgdef nms(self,boxs, thresh):# dets:x1 y1 x2 y2 score class# x[:,n]就是取所有集合的第n个数据x1 = boxs[:, 0]y1 = boxs[:, 1]x2 = boxs[:, 2]y2 = boxs[:, 3]# -------------------------------------------------------#   计算框的面积#	置信度从大到小排序# -------------------------------------------------------areas = (y2 - y1 + 1) * (x2 - x1 + 1)scores = boxs[:, 4]# print(scores)keep = []index = scores.argsort()[::-1]  # np.argsort()对某维度从小到大排序# [::-1] 从最后一个元素到第一个元素复制一遍。倒序从而从大到小排序while index.size > 0:i = index[0]keep.append(i)# -------------------------------------------------------#   计算相交面积#	1.相交#	2.不相交# -------------------------------------------------------x11 = np.maximum(x1[i], x1[index[1:]])y11 = np.maximum(y1[i], y1[index[1:]])x22 = np.minimum(x2[i], x2[index[1:]])y22 = np.minimum(y2[i], y2[index[1:]])w = np.maximum(0, x22 - x11 + 1)h = np.maximum(0, y22 - y11 + 1)overlaps = w * h# -------------------------------------------------------#   计算该框与其它框的IOU,去除掉重复的框,即IOU值大的框#	IOU小于thresh的框保留下来# -------------------------------------------------------ious = overlaps / (areas[i] + areas[index[1:]] - overlaps)idx = np.where(ious <= thresh)[0]index = index[idx + 1]return keepdef xywh2xyxy(self,x):# [x, y, w, h] to [x1, y1, x2, y2]y = np.copy(x)y[:, 0] = x[:, 0] - x[:, 2] / 2y[:, 1] = x[:, 1] - x[:, 3] / 2y[:, 2] = x[:, 0] + x[:, 2] / 2y[:, 3] = x[:, 1] + x[:, 3] / 2return ydef filter_box(self,pred, conf_thres, iou_thres):  # 过滤掉无用的框# 先筛选置信度# […,4]:代表了取最里边一层的所有第4号元素,…代表了对:,:,:,等所有的的省略。此处生成:25200个第四号元素组成的数组conf = pred[..., 4] > conf_thres  # 0 1 2 3 4 4是置信度,只要置信度 > conf_thres 的box = pred[conf == True]  # 根据objectness score生成(n, 9),只留下符合要求的框print('box:符合要求的框')print(box.shape)#   通过argmax获取置信度最大的类别cls_cinf = box[..., 5:]  # 左闭右开(5 6),就只剩下了每个grid cell中各类别的概率cls = cls_cinf.argmax(axis=-1)all_cls = list(set(cls))  # 去重,找出图中都有哪些类别# set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。output = []for i in np.arange(len(all_cls)):curr_cls = all_cls[i]curr_cls_box = []curr_out_box = []for j in range(len(cls)):if cls[j] == curr_cls:box[j][5] = curr_clscurr_cls_box.append(box[j][:6])  # 左闭右开,0 1 2 3 4 5curr_cls_box = np.array(curr_cls_box)  # 0 1 2 3 4 5 分别是 x y w h score class# curr_cls_box_old = np.copy(curr_cls_box)curr_cls_box = self.xywh2xyxy(curr_cls_box)  # 0 1 2 3 4 5 分别是 x1 y1 x2 y2 score classcurr_out_box = self.nms(curr_cls_box, iou_thres)  # 获得nms后,剩下的类别在curr_cls_box中的下标for k in curr_out_box:output.append(curr_cls_box[k])output = np.array(output)return outputdef forward(self, image,conf_thres, iou_thres):image_np,resize_img = self.inference(image)print(image_np.shape) #这里应该是[1,3,640,640]pred =self.model.run(None, {self.input_name: image_np})print(pred.shape)    #[1,1,25200,7]pred =pred[0][0]   #[25200,7]#开始进行置信度cfg_thr,iou_thr,非极大值抑制out_put =self.filter_box(pred, conf_thres, iou_thres)return out_put,resize_imgif __name__ == '__main__':CLASSES = ['cat', 'dog']model_path = '../output_onnx_model'image = cv2.imread('../data/cat.jpg')onnx_session,input_name = load_onnx(model_path)yolov5_model=Yolov5ONNX(onnx_session,input_name)boxs,resize_image = yolov5_model(image, conf_thres=0.5, iou_thres=0.5)image =draw(resize_image,boxs,CLASSES)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM之Arthas的dashboard命令以及CPU飙高场景

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

JSAR 基础 1.2.1 基础概念_空间小程序

JSAR 基础 1.2.1 基础概念_空间小程序 空间空间自由度可嵌入空间空间小程序 最新的技术进展表明&#xff0c;官网之前的文档准备废除了&#xff0c;基于xsml的开发将退出历史舞台&#xff0c;three.js和普通web结合的技术将成为主导。所以后续学习请移步three.js学习路径&#…

蓝桥杯嵌入式组第七届省赛题目解析+STM32G431RBT6实现源码

文章目录 1.题目解析1.1 分而治之&#xff0c;藕断丝连1.2 模块化思维导图1.3 模块解析1.3.1 KEY模块1.3.2 ADC模块1.3.3 IIC模块1.3.4 UART模块1.3.5 LCD模块1.3.6 LED模块1.3.7 TIM模块 2.源码3.第七届题目 前言&#xff1a;STM32G431RBT6实现嵌入式组第七届题目解析源码&…

Java之IO流

什么是IO流 存储和读取数据的解决方案 I&#xff1a;input:输入 O&#xff1a;output&#xff1a;输出 流&#xff1a;像水流一样传输数据 IO流的作用 用于读取数据&#xff08;本地文件&#xff0c;网络&#xff09; IO流的分类 流的方向&#xff1a; 输入流&#xff…

Python入门———条件、循环

目录 语句 顺序语句 条件语句 缩进和代码块 判断年份是否是闰年 空语句 pass 循环 while 循环 求5的阶乘&#xff1a; 求1&#xff01;2&#xff01;3&#xff01;4&#xff01;5&#xff01; for循环 打印1-10 打印2&#xff0c;4&#xff0c;6&#xff0c;8&#x…

JWT的学习

1、HTTP无状态及解决方案 HTTP一种是无状态的协议&#xff0c;每次请求都是一次独立的请求&#xff0c;一次交互之后就是陌生人。 以CSDN为例&#xff0c;先登录一次&#xff0c;然后浏览器退出&#xff0c;这个时候在进入CSDN&#xff0c;按理说服务器是不知道你已经登陆了&…

【接口负载】✈️整合 Resilience4j 指定接口负载,避免过载

目录 &#x1f44b;前言 &#x1f378;一、应用场景 &#x1f37b;二、 代码实现 &#x1f379;三、扩展 &#x1f378;四、章末 &#x1f44b;前言 小伙伴们大家好&#xff0c;上次本地实操了下针对百万级数据量如何快速排序、指定条件获取等&#xff0c;文章内容包括&am…

CSS—网格布局Grid

网格布局grid 提供了带有行和列的基于网格的布局系统&#xff0c;无需使用浮动和定位。 当 HTML 元素的 display 属性设置为 grid 或 inline-grid 时&#xff0c;它就会成为网格容器。 更多布局模式可以参考之前的博客&#xff1a; ​​​​​​CSS—flex布局、过渡transit…

表格columns拼接两个后端返回的字段(以umi框架为例)

在用组件对前端项目进行开发时&#xff0c;我们会遇到以下情况&#xff1a;项目原型中有取值范围这个表字段&#xff0c;需要存放最小取值到最大取值。 而后端返回给我们的数据是返回了一个最小值和一个最大值&#xff0c; 在columns中我们需要对这两个字段进行拼接&#xff0…

Git系列之git tag和ReleaseMilestone

以下是关于 Git Tag、Release 和 Milestone 的深度融合内容&#xff0c;并补充了关于 Git Tag 的所有命令、详细解释和指令实例&#xff0c;条理清晰&#xff0c;结合实际使用场景和案例。 1. Git Tag 1.1 定义 • Tag 是 Git 中用于标记特定提交&#xff08;commit&#xf…

SQLiteStudio:一款免费跨平台的SQLite管理工具

SQLiteStudio 是一款专门用于管理和操作 SQLite 数据库的免费工具。它提供直观的图形化界面&#xff0c;简化了数据库的创建、编辑、查询和维护&#xff0c;适合数据库开发者和数据分析师使用。 功能特性 SQLiteStudio 提供的主要功能包括&#xff1a; 免费开源&#xff0c;可…

VMware workstation 17安装过程详细指南

VMware 17安装过程详细指南 一、准备工作 在开始安装 VMware 之前&#xff0c;你需要确保你的计算机满足以下条件&#xff1a; 操作系统&#xff1a;VMware Workstation 支持多种 Windows 和 Linux 操作系统。确保你的操作系统版本在 VMware 支持的范围内。 硬件要求&#…

【从零开始学习计算机科学】计算机组成原理(六)异常事件处理

【从零开始学习计算机科学】计算机组成原理&#xff08;六&#xff09;异常事件处理 异常事件处理异常处理的数据通路异常事件入口地址 异常事件处理 异常和中断事件改变处理机正常指令的执行顺序。异常指令执行过程中&#xff0c;由于操作非法和指令非法引起的事件。陷阱指陷…

基于DeepSeek的智慧医药系统(源码+部署教程)

运行环境 智慧医药系统运行环境如下&#xff1a; 前端&#xff1a; HTMLCSS后端&#xff1a;Java AIGCDeepseekIDE工具&#xff1a;IDEA技术栈&#xff1a;Springboot HTMLCSS MySQL 主要角色 智慧医药系统主要分为两个角色。 游客 尚未进行注册和登录。具备登录注册、…

WinUI 3 支持的三种窗口 及 受限的窗口透明

我的目标 希望能够熟悉 WinUI 3 窗口的基本使用方式&#xff0c;了解可能出现的问题 。 WinUI 3 支持三种窗口模式&#xff0c;分别为&#xff1a;常规窗口模式、画中画模式、全屏模式。 窗口模式&#xff1a;常规 即我们最常见的普通窗口。 支持&#xff1a;显示最大化按钮…

《云原生监控体系构建实录:从Prometheus到Grafana的观测革命》

PrometheusGrafana部署配置 Prometheus安装 下载Prometheus服务端 Download | PrometheusAn open-source monitoring system with a dimensional data model, flexible query language, efficient time series database and modern alerting approach.https://prometheus.io/…

VBA 数据库同一表的当前行与其他行的主键重复判断实现方案1

目的&#xff0c;判断是否主键重复&#xff0c;不重复则登录新数据&#xff0c;重复则不登录。 定义类型&#xff1a; DataRecord   tableName 表名   rowNumber 行号   columnName 列名   data 数据 想要实现的代码逻辑如下&#xff1a; 模拟数据库的登录过程。假设…

MySql的in和join对比谁更高效

公司有个SQl根据时间判断是否变化进而更新到主表通知下游服务告知变化 首先看下优化前和优化后的sql&#xff1a; 优化前&#xff1a;执行很慢 UPDATE vrs_video SET updated_at now() WHEREvrs_video.id IN (SELECT DISTINCTvideo_id FROMvrs_play_source WHEREvrs_play_…

用BGE Large ZH 1.5获取向量以及重排序构建生产环境可用restful API的Python代码讲解

开篇 嘿&#xff0c;各位小伙伴&#xff01;今天我们来聊一个超级有趣的话题&#xff1a;embedding向量化数据。听起来很高大上对不对&#xff1f;别担心&#xff0c;让我用最简单的方式告诉你这是啥。 想象一下&#xff0c;你有一大堆文字、图片或者其他数据&#xff0c;想要…

【OneAPI】网页截图API-V2

API简介 生成指定URL的网页截图或缩略图。 旧版本请参考&#xff1a;网页截图 V2版本新增全屏截图、带壳截图等功能&#xff0c;并修复了一些已知问题。 全屏截图&#xff1a; 支持全屏截图&#xff0c;通过设置fullscreentrue来支持全屏截图。全屏模式下&#xff0c;系统…