基于OpenVINO部署PaddlePadle-YOLOE模型—4.Python实现

2023-11-06

1. 环境安装

 OpenVINOTM工具套件2022.1版于2022年3月22日正式发布,与以往版本相比发生了重大革新,提供预处理API函数、ONNX前端API、AUTO 设备插件,并且支持直接读入飞桨模型,在推理中中支持动态改变模型的形状,这极大地推动了不同网络的应用落地。2022年9月23日,OpenVINOTM 工具套件2022.2版推出,对2022.1进行了微调,以包括对英特尔最新 CPU 和离散 GPU 的支持,以实现更多的人工智能创新和机会。

 此处选用OpenVINOTM 2022.2 版本,对于Python本,我们可以直接使用PIP命令安装。建议使用Anaconda 创建虚拟环境安装,对于最新版,在创建好的虚拟环境下直接输入以下命令进行安装:

// 更新pip
python -m pip install --upgrade pip
// 安装
pip install openvino-dev[ONNX,tensorflow2]==2022.2.0

 安装过程中如出现下载安装包错误以及网络等原因时,可以重新运行安装命令,会继续上一次的安装。

2. 创建推理类 Predictor

from openvino.runtime import Core
class Predictor:
    """
    OpenVINO 模型推理器
    """
    def __init__(self, model_path):
        ie_core = Core()
        model = ie_core.read_model(model=model_path)
        self.compiled_model = ie_core.compile_model(model=model, device_name="CPU")
    def get_inputs_name(self, num):
        return self.compiled_model.input(num)
    
    def get_outputs_name(self, num):
        return self.compiled_model.output(num)
    
    def predict(self, input_data):
        return self.compiled_model([input_data])
        

 此处由于只进行PP-YOLOE模型推理,所以只简单地封装一下Predictor类:主要包括初始化函数,负责读取本地模型并加载到指定设备中;获取输入输出名称函数以及模型预测函数。

3.数据处理方法

3.1 输入图片预处理

def process_image(input_image, size):
    """输入图片与处理方法,按照PP-Yoloe模型要求预处理图片数据

    Args:
        input_image (uint8): 输入图片矩阵
        size (int): 模型输入大小

    Returns:
        float32: 返回处理后的图片矩阵数据
    """
    max_len = max(input_image.shape)
    img = np.zeros([max_len,max_len,3],np.uint8)
    img[0:input_image.shape[0],0:input_image.shape[1]] = input_image # 将图片放到正方形背景中
    img = cv.cvtColor(img,cv.COLOR_BGR2RGB)  # BGR转RGB
    img = cv.resize(img, (size, size), cv.INTER_NEAREST) # 缩放图片
    img = np.transpose(img,[2, 0, 1]) # 转换格式
    img = img / 255.0 # 归一化
    img = np.expand_dims(img,0) # 增加维度
    return img

 根据 PP-YOLOE模型输入要求,处理图片数据,主要包括图片通道转换、图片缩放、转换矩阵、数据归一化以及增加矩阵维度。按照PP-YOLOE模型输入设置,归一化方式是直接将像素点除255,将输入数据整合到0~1之间,加快模型的计算。PP-YOLOE模型ONNX格式只支持bath_size=1的推理,所以最后将数据矩阵维度直接增加一个维度即可。

3.2 模型输出结果处理

def process_result(box_results, conf_results):
    """按照PP-Yolove模型输出要求,处理数据,非极大值抑制,提取预测结果

    Args:
        box_results (float32): 预测框预测结果
        conf_results (float32): 置信度预测结果
    Returns:
        float: 预测框
        float: 分数
        int: 类别
    """
    conf_results = np.transpose(conf_results,[0, 2, 1]) # 转置
    # 设置输出形状
    box_results =box_results.reshape(8400,4) 
    conf_results = conf_results.reshape(8400,80)
    scores = []
    classes = []
    boxes = []
    for i in range(8400):
        conf = conf_results[i,:] # 预测分数
        score = np.max(conf) # 获取类别
        # 筛选较小的预测类别
        if score > 0.5:
            classes.append(np.argmax(conf)) 
            scores.append(score) 
            boxes.append(box_results[i,:])
    scores = np.array(scores)
    boxes = np.array(boxes)
    # 非极大值抑制筛选重复的预测结果
    indexs = tf.image.non_max_suppression(boxes,scores,len(scores),0.25,0.35)
    # 处理非极大值抑制后的结果
    result_box = []
    result_score = []
    result_class = []
    for i, index in enumerate(indexs):
        result_score.append(scores[index])
        result_box.append(boxes[index,:])
        result_class.append(classes[index])
    # 返沪结果转为矩阵
    return np.array(result_box),np.array(result_score),np.array(result_class)

 由于我们所使用的PP-YOLOE被我们裁剪过,因此模型的输出是未进行处理的结果数据,模型输出节点有两个,一个为预测框输出,一个节点为置信值输出,所以后期需要对输出结果进行处理。

 置信度结果输出形状为[1, 80, 8400],而实际80代表的一个预测结果对应的80个类别的置信值,而8400表示有8400个预测结果;而预测框输出结果为形状为[1, 8400, 4],对应了8400个预测结果的预测框,其中4代表预测框的左上顶点预右下顶点的横纵坐标。

 因此结果处理主要包含以下几个方面:

  • 置信度结果转置处理,并提取预测结果最大的类别、预测分数和对应的预测框;
  • 非极大值抑制提取预测框和类别。

3.3 绘制预测结果

def draw_box(image, boxes, scores, classes, lables):
    """将预测结果绘制到图像上

    Args:
        image (uint8): 原图片
        boxes (float32): 预测框
        scores (float32): 分数
        classes (int): 类别
        lables (str): 标签

    Returns:
        uint8: 标注好的图片
    """
    scale = max(image.shape) / 640.0 # 缩放比例
    for i in range(len(classes)):
        box = boxes[i,:]

        x1 = int(box[0] * scale)
        y1 = int(box[1] * scale)
        x2 = int(box[2] * scale)
        y2 = int(box[3] * scale)
        
        lable = lables[classes[i]]
        score = scores[i]
        cv.rectangle(image, (x1, y1), (x2, y2), (0,0,255), 2, cv.LINE_8)
        cv.putText(image,lable+":"+str(score),(x1,y1-10),cv.FONT_HERSHEY_SIMPLEX, 0.55, (0, 0, 255), 2)
        
    return image

 上一步经过结果处理,最终获得预测框、分数以及类别,最后通过OpenCV将预测结果绘制到图片上,主要是一个预测框绘制和分数、类别的书写两步。

4. 模型推理

    '''-------------------1. 导入相关信息 ----------------------'''
    # yoloe_model_path = "E:/Text_Model/pp-yoloe/ppyoloe_plus_crn_s_80e_coco.onnx"
    yoloe_model_path = "E:/Text_Model/pp-yoloe/ppyoloe_plus_crn_s_80e_coco.xml"
    image_path = "E:/Text_dataset/YOLOv5/0001.jpg"
    lable_path = "E:/Git_space/基于OpenVINO部署PP-YOLOE模型/model/lable.txt";
    '''-------------------2. 创建模型预测器 ----------------------'''
    predictor = Predictor(model_path = yoloe_model_path)
    '''-------------------3. 预处理模型输入数据 ----------------------'''
    image = cv.imread(image_path)
    input_image = process_image(image, 640)
    '''-------------------4. 模型推理 ----------------------'''
    results = predictor.predict(input_data=input_image)
    '''-------------------5. 后处理预测结果 ----------------------'''
    boxes_name = predictor.get_outputs_name(0)
    conf_name = predictor.get_outputs_name(1)
    
    boxes, scores, classes = process_result(box_results=results[boxes_name], conf_results=results[conf_name]) # 处理结果
    lables = read_lable(lable_path=lable_path) # 读取lable
    result_image = draw_box(image=image, boxes=boxes, scores=scores, classes=classes, lables=lables) # 绘制结果
    cv.imshow("result",result_image)
    cv.waitKey(0)

 根据模型推理流程,最后调用模型推理类进行实现:

  • 导入相关信息:主要是定义模型地址、待预测图片地址和类别文件;
  • 创建模型预测器:主要初始化预测类,读取本地模型,此处可以读取ONNX模型和IR模型两种格式;
  • 预处理图片:调用定义的图片处理方法,将本地图片数据转为模型推理的数据;
  • 模型推理:将处理好的图片数据加载到模型中,并获取模型推理结果;
  • 处理模型结果:主要是调用结果处理方法实现,如果需要可视化,可以将预测结果绘制到图片中。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于OpenVINO部署PaddlePadle-YOLOE模型—4.Python实现 的相关文章

  • “KMeans”对象没有属性“k”

    我使用 Yellowbrick 包绘制数据集的肘部曲线 以使用 KMeans 作为模型找到数据集的最佳簇数 我正在使用 Scikit learn KMeans 和 Yellowbrick kelbowvisualizer 函数 生成了肘部曲
  • 在python中使用编解码器utf-8打开文件错误

    我在 windows xp 和 python 2 6 4 上执行以下代码 但它显示 IOError 如何打开名称带有 utf 8 编解码器的文件 gt gt gt open unicode txt euc kr encode utf 8 T
  • 增强迪基-富勒测试中的 BIC 在 Python 中到底是如何工作的?

    这个问题是关于 statsmodels tsa stattools python 库 adfuller 中的增强迪基 富勒测试实现 原则上 AIC 和 BIC 应该计算一组可用模型的信息标准 并选择最好的模型 信息损失最低的模型 但它们在增
  • 使用 Microsoft Graph 创建用户

    如何使用 Microsoft graph 创建用户 因为我在保存过程中遇到了权限失败的问题 我确实有几个问题 在图中调用创建用户 API 将在哪里创建用户 是在 Azure AD 还是其他地方 我尝试通过传递 json 和必需的标头来调用创
  • C++ 析构函数:何时释放内存?

    如果我删除一个导致其析构函数被调用的对象 那么内存是在析构函数完成函数中的任何操作之前还是之后被释放 仅当最小派生类子对象被销毁后才会释放内存 所以如果你有 class Base class Derived public Base publ
  • 在字符串内打印单引号

    我想输出 XYZ s ABC 我在Python IDLE中尝试了以下3条语句 第一条和第二条语句输出 a before 带打印功能的第三条语句不输出 before 作为 Python 新手 我想了解为什么 之前输出 在第 1 条和第 2 条
  • 使用 cudamalloc()。为什么是双指针?

    我目前正在浏览有关的教程示例http code google com p stanford cs193g sp2010 http code google com p stanford cs193g sp2010 学习CUDA 演示的代码 g
  • python 中的 F 字符串前缀给出语法错误[重复]

    这个问题在这里已经有答案了 我有一个名为 method 的变量 它的值是 POST 但是当我尝试运行时print f method method is used 它不断在最后一个双引号处给出语法错误 我找不到它这样做的原因 我正在使用 py
  • .NET 的 HttpWebResponse 是否会自动解压缩 GZiped 和 Deflated 响应?

    我正在尝试执行一个接受压缩响应的请求 var request HttpWebRequest HttpWebRequest Create requestUri request Headers Add HttpRequestHeader Acc
  • 如果数组为空,LINQ 返回 null

    public class Stuff public int x other stuff 我有一个IEnumerable
  • fscanf 和 EOF 中的否定扫描集

    我的文件中有一个以逗号分隔的字符串列表 姓名 1 姓名 2 姓名 3 我想跳过所有逗号来阅读这些名字 我写了以下循环 while true if fscanf file my string 1 break 然而 它总是比预期多执行一次 给定
  • 使 C# 编译器相信执行将在成员返回后停止

    我认为目前这是不可能的 或者这是否是一个好主意 但这是我刚才正在考虑的事情 我使用 MSTest 对我的 C 项目进行单元测试 在我的一项测试中 我执行以下操作 MyClass instance try instance getValue
  • 获取大于某个数字的元素个数

    我正在尝试解决以下问题 数字被插入到容器中 每次插入数字时 我需要知道容器中有多少元素大于或等于当前插入的数字 我相信这两个操作都可以以对数复杂度完成 我的问题 C 库中有标准容器可以解决这个问题吗 我知道std multiset可以在对数
  • Intel 和 AMD 处理器有相同的汇编程序吗?

    C语言被用来编写Unix以实现可移植性 使用不同编译器编译的同一个C语言程序会产生不同的机器指令 为什么 Windows 操作系统能够在两者上运行Intel https en wikipedia org wiki Intel and AMD
  • Visual Studio 2015默认附加库

    当我在 VS 2015 中创建一个空项目时 它会自动将这些库放入 附加依赖项 中 kernel32 lib user32 lib gdi32 lib winspool lib comdlg32 lib advapi32 lib shell3
  • 在自定义 keras 层的调用函数中传递附加参数

    我创建了一个自定义 keras 层 目的是在推理过程中手动更改前一层的激活 以下是基本层 它只是将激活值乘以一个数字 import numpy as np from keras import backend as K from keras
  • JSONDecodeError:额外数据:Python [重复]

    这个问题在这里已经有答案了 我使用以下代码从文件加载 json file file name obj list with open file as f for json obj in f obj list append loads json
  • 请解释为什么Java和C对此代码给出不同的答案

    public class Test public static void main String args int i 10 i i System out println value of i is i 输出是 10 当我在中执行类似的代码
  • 将二进制数转换为包含每个二进制数的数组

    我试图将二进制值转换为每个 1 0 的列表 但我得到默认的二进制值而不是列表 我有一个字符串 我将每个字符转换为二进制 它给了我一个列表 其中每个字符都有一个字符串 现在我试图将每个字符串拆分为值为 0 1 的整数 但我什么也得不到 if
  • 如何设置 Swashbuckle 与 Microsoft.AspNetCore.Mvc.Versioning

    我们有asp net core webapi 我们添加了Microsoft AspNetCore Mvc Versioning and Swashbuckle拥有招摇的用户界面 我们将控制器指定为 ApiVersion 1 0 Route

随机推荐

  • Spring IOC容器初始化过程及其原理(源码层面)

    Spring大家族在Java技术生态体系中占有重要地位 其中Spring更是其中的佼佼者 它极大的简化了我们的代码开发量 提高我们的工作效率 其中Spring两大特性中的IOC特性是至关重要的 今天来从底层看一看Spring的容器的初始化过
  • USB描述符 包括bushound抓包

    USB描述符 USB描述符信息存储在USB设备中 在枚举过程中 USB主机会向USB设备发送GetDescriptor请求 USB设备在收到这个请求之后 会将USB描述符信息返回给USB主机 USB主机分析返回来的数据 判断出该设备是哪一种
  • 如何理解等错误率(EER, Equal Error Rate)?

    在语音vad和KWS任务中 经常用到EER 怎么正确理解EER FR定义 在一批本该全部正确 TRUE 的列表中出现几个没识别出正确的语音 这个就是错误拒识FR False Rejection 是Miss的 FA定义 在一批本该全部错误 F
  • 6、一个简单的新氧的小爬虫

    from bs4 import BeautifulSoup import requests import math url hos for i in range 1 15 url source http y soyoung com hosp
  • 输出二叉树的所有路径

    给你一个二叉树的根节点 root 按 任意顺序 返回所有从根节点到叶子节点的路径 叶子节点 是指没有子节点的节点 输入 root 1 2 3 null 5 输出 1 gt 2 gt 5 1 gt 3 解法一 深度优先搜索 递归 迭代也可以实
  • 聊聊cglib动态代理遇到的坑

    简介 cglib是另外一种动态代理的方法 他和jdk动态代理的实现是有区别的 我们在之前见过jdk动态代理类是必须实现了接口的 而cglib不需要实现接口 但是必须保证类不含有final关键字 否则是无法代理的 本文是从个人不小心遇到的cg
  • # SpringCloud集成 报错 An attempt was made to call a method that does not exist. The attempt was made

    SpringCloud集成 报错 An attempt was made to call a method that does not exist The attempt was made from the following locati
  • 【Git系列】Git概述

    Git概述 1 Git发展历史 2 Git与SVN的区别 3 Git本地结构 4 代码托管中心 4 1 代码托管中心是什么 4 2 托管中心种类 其他系列 Git最详细的体系化教程 1 Git发展历史 Git的发展历史可以追溯到2005年
  • Linux系统终端窗口ctrl+c,ctrl+z,ctrl+d的区别

    时常在Linux系统上 执行某命令停不下来 就这几个ctrl组合键按来按去 今天稍微总结下具体差别 便于以后linux系统运维操作 1 ctrl c强制中断程序 相应进程会被杀死 中断进程任务无法恢复执行 2 ctrl z暂停正在执行的进程
  • Oracle——基础知识汇总

    注意 在Oracle数据库的SQL命令中 关键字 表名和字段名都不区分大小写 语法是标准的 sql写法 参考链接 一 字符串类型 char 固定长度字符串 会用空格填充来达到最大长度 varchar2 变长度字符串 不补充空格 可以存储32
  • Ubuntu20.04无法开机/左上角小横杠闪烁/升级系统内核后与显卡驱动不匹配的问题

    问题描述 今天也不知道是因为升级了系统内核还是什么原因 导致系统开机后只有左上角一个小白杠一直闪烁 百度了以下确认了是nvidia显卡驱动和linux系统内核不匹配的问题 解决方法 1 安装nvidia显卡驱动 重装CUDA 左上角有小白杠
  • 线程安全和线程同步

    1 线程安全 每次执行的结果都是不确定的 因为线程的执行顺序是不可预见的 这是java同步产生的根源 synchronized 关键字保证了多个线程对于同步块是互斥的 synchronized作为一种同步手段 解决java多线程的执行有序性
  • 15 个最重要的 Java 多线程面试题及回答

    前言 在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分 如果你想获得任何股票投资银行的前台资讯职位 那么你应该准备很多关于多线程的问题 在投资银行业务中多线程和并发是一个非常受欢迎的话题 特别是电子交易发展方面相关的 他们会
  • http://mail.163.com/help/help_spam_16.htm?ip=118.186.207.7&hostid=smtp5&time=1358341921

    0INRMumLsiQwT0xVgvYVmNCBWS7mV8LzSeLOZGHzflL3ziBSx iej3G1syAeYvPZxqagQ0P7mgdX qgnEWWuIcv4cTR6ZI5QNmqULAGtRkCtCNsphAD7cLBi
  • Flink从入门到放弃(十二)-企业实战之事件驱动型场景踩坑(一)

    需求背景 某日 小明早上10点打卡到公司 先来一杯热水润润嗓子 打开音乐播放器带上心爱的降噪耳机看看新闻 静静等待11点半吃午饭 突然消息框亮了起来 这个时候小明心想要么来需求了 要么数据就有问题了 这个时候运营A部的同学发消息过来说想要分
  • 飞思卡尔Kinetis系列单片机被锁住后,怎么解锁

    Kinetis提供了相当可靠地知识产权保护机制 人为的给芯片上锁 这个对量产后的产品是必须的 但是 用户误擦写了芯片内部security的内存部分 0x400 0x40F 从而锁住了芯片 难道芯片就要报废了么 其实有解救办法 一旦芯片被锁
  • android 电池(二):android关机充电流程、充电画面显示【转】

    本文转载自 http blog csdn net xubin341719 article details 8498580 上一篇我们讲了锂电池的充放电的流程和电池的一些特性 这一节我们重点说一下android关机充电是怎么 充电画面显示是怎
  • 没有项目经验,如何通过面试 ?

    读者提问 阿常 我是培训班出来的 没有实际项目经验 害怕面试的时候通不过 有什么招可以教教我吗 阿常回答 培训班应该有实战项目 你把它当成公司项目来实践 一个月下来也能有所收获 另外你可以去牛客网上搜集一下面经 多刷面试题 参与一些企业项目
  • wireshark过滤规则

    http blog sina com cn s blog 48a0f2740100ka71 html 1 过 滤IP 如来源IP或者目标IP等于某个IP 例子 ip src eq 192 168 1 107 or ip dst eq 192
  • 基于OpenVINO部署PaddlePadle-YOLOE模型—4.Python实现

    1 环境安装 OpenVINOTM工具套件2022 1版于2022年3月22日正式发布 与以往版本相比发生了重大革新 提供预处理API函数 ONNX前端API AUTO 设备插件 并且支持直接读入飞桨模型 在推理中中支持动态改变模型的形状