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

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 nn

CLASSES = ['cat', 'dog']
model_path = '../output_onnx_model'


def draw(image, box_data, CLASSES):
    # -------------------------------------------------------
    #	取整,方便画框
    # -------------------------------------------------------

    boxes = box_data[..., :4].astype(np.int32)  # x1 x2 y1 y2
    scores = box_data[..., 4]
    classes = box_data[..., 5].astype(np.int32)
    for box, score, cl in zip(boxes, scores, classes):
        top, left, right, bottom = box
        print('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 image


def 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_name


class Yolov5ONNX(nn.Module):
    def __init__(self, onnx_session, input_name):
        super(Yolov5ONNX,self).__init__()
        self.model = onnx_session
        self.input_name = input_name

    def inference(self, img):
        """ 1.cv2读取图像并resize
        2.图像转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转cwh
        img = img.astype(dtype=np.float32)  # onnx模型的类型是type: float32[ , , , ]
        img /= 255.0
        img = np.expand_dims(img, axis=0)  # [3, 640, 640]扩展为[1, 3, 640, 640]
        # img尺寸(1, 3, 640, 640)
        return img,resize_img

    def 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 keep

    def xywh2xyxy(self,x):
        # [x, y, w, h] to [x1, y1, x2, y2]
        y = np.copy(x)
        y[:, 0] = x[:, 0] - x[:, 2] / 2
        y[:, 1] = x[:, 1] - x[:, 3] / 2
        y[:, 2] = x[:, 0] + x[:, 2] / 2
        y[:, 3] = x[:, 1] + x[:, 3] / 2
        return y
    def 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_cls
                    curr_cls_box.append(box[j][:6])  # 左闭右开,0 1 2 3 4 5

            curr_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 class
            curr_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 output

    def 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_img




if __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)
    



相关文章:

  • AutoGen学习笔记系列(九)Advanced - Selector Group Chat
  • PawSQL for MSSQL:PawSQL 支持 SQL Server 的SQL优化、SQL审核、性能巡检
  • 【redis】type命令和定时器的两种实现方式(优先级队列、时间轮)
  • elasticsearch是哪家的
  • 每天五分钟深度学习pytorch:基于Pytorch搭建ResNet模型的残差块
  • 分布式ETCD面试题及参考答案
  • 2025 年 AI 网络安全预测
  • 使用 Java 在后端 为 PDF 添加水印
  • 电脑中本地部署阉割版DeepSeek或其他大模型的方法
  • ES-分词器安装与使用详解
  • MWC 2025 | 移远通信推出AI智能无人零售解决方案,以“动态视觉+边缘计算”引领智能零售新潮流
  • Hive的架构
  • Python 相对路径写法
  • 掌握MiniQMT:程序化下单与撤单的高效实现
  • 【vLLM 教程】使用 TPU 安装
  • 《Natural Actor-Critic》译读笔记
  • DMR协议空中接口部分
  • Vulnhub-election靶机
  • shell编程——运算符和运算命令
  • 硬件基础(4):(1)AD采集电路设计
  • 中青报观察:年轻人偏好沉浸式“慢游”,历史古迹受欢迎
  • 林诗栋/蒯曼不敌日本组合,无缘晋级世乒赛混双四强
  • 科学与艺术的跨界对话可能吗?——评“以蚁为序的生命网络”
  • 丹泽尔·华盛顿惊喜收获戛纳终身成就奖
  • 印尼总统20年来首次访泰:建立战略伙伴关系,加强打击网络诈骗等合作
  • 花旗回应减员传闻:持续评估人力资源战略,将为受影响的个人提供支持