yolov5-7在opencv里跑自己的onnx模型

news2024/11/26 21:25:09

先把模型放在如下目录

运行如下代码

import cv2
import numpy as np

class Onnx_clf:
    def __init__(self, onnx:str='dnn_model1/plane02.onnx', img_size=640, classlist:list=['plane']) -> None:
        '''	@func: 读取onnx模型,并进行目标识别
            @para	onnx:模型路径
                 	img_size:输出图片大小,和模型直接相关
                    classlist:类别列表
            @return: None
        '''
        self.net = cv2.dnn.readNet(onnx) # 读取模型
        self.img_size = img_size # 输出图片尺寸大小
        self.classlist = classlist # 读取类别列表

    def img_identify(self, img, ifshow=True) -> np.ndarray:
        '''	@func: 图片识别
            @para	img: 图片路径或者图片数组
                    ifshow: 是否显示图片
            @return: 图片数组
        '''
        if type(img) == str: src = cv2.imread(img)
        else: src = img
        height, width, _ = src.shape #注意输出的尺寸是先高后宽
        _max = max(width, height)
        resized = np.zeros((_max, _max, 3), np.uint8)
        resized[0:height, 0:width] = src  # 将图片转换成正方形,防止后续图片预处理(缩放)失真
        # 图像预处理函数,缩放裁剪,交换通道  img     scale              out_size              swapRB
        blob = cv2.dnn.blobFromImage(resized, 1/255.0, (self.img_size, self.img_size), swapRB=True)
        prop = _max / self.img_size  # 计算缩放比例
        dst = cv2.resize(src, (round(width/prop), round(height/prop)))
        # print(prop)  # 注意,这里不能取整,而是需要取小数,否则后面绘制框的时候会出现偏差
        self.net.setInput(blob) # 将图片输入到模型
        out = self.net.forward() # 模型输出
        # print(out.shape)
        out = np.array(out[0])
        out = out[out[:, 4] >= 0.5]  # 利用numpy的花式索引,速度更快, 过滤置信度低的目标
        boxes = out[:, :4]
        confidences = out[:, 4]
        class_ids = np.argmax(out[:, 5:], axis=1)
        class_scores = np.max(out[:, 5:], axis=1)
        # out2 = out[0][out[0][:][4] > 0.5]
        # for i in out[0]: # 遍历每一个框
        #     class_max_score = max(i[5:])
        #     if i[4] < 0.5 or class_max_score < 0.25: # 过滤置信度低的目标
        #         continue
        #     boxes.append(i[:4]) # 获取目标框: x,y,w,h (x,y为中心点坐标)
        #     confidences.append(i[4]) # 获取置信度
        #     class_ids.append(np.argmax(i[5:])) # 获取类别id
        #     class_scores.append(class_max_score) # 获取类别置信度
        indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.25, 0.45) # 非极大值抑制, 获取的是索引
        # print(indexes)
        iffall = True if len(indexes)!=0 else False
        # print(iffall)
        for i in indexes:   # 遍历每一个目标, 绘制目标框
            box = boxes[i]
            class_id = class_ids[i]
            score = round(class_scores[i], 2)
            x1 = round((box[0] - 0.5*box[2])*prop)
            y1 = round((box[1] - 0.5*box[3])*prop)
            x2 = round((box[0] + 0.5*box[2])*prop)
            y2 = round((box[1] + 0.5*box[3])*prop)
            # print(x1, y1, x2, y2)
            self.drawtext(src,(x1, y1), (x2, y2), self.classlist[class_id]+' '+str(score))
            dst = cv2.resize(src, (round(width/prop), round(height/prop)))
        if ifshow:
            cv2.imshow('result', dst)
            cv2.waitKey(0)
        return dst, iffall

    def video_identify(self, video_path:str) -> None:
        '''	@func: 视频识别
            @para  video_path: 视频路径
            @return: None
        '''
        cap = cv2.VideoCapture(video_path)
        fps = cap.get(cv2.CAP_PROP_FPS)
        # print(fps)
        while cap.isOpened():
            ret, frame = cap.read()
            #键盘输入空格暂停,输入q退出
            key = cv2.waitKey(1) & 0xff
            if key == ord(" "): cv2.waitKey(0)
            if key == ord("q"): break
            if not ret: break
            img, res = self.img_identify(frame, False)
            cv2.imshow('result', img)
            print(res)
            if cv2.waitKey(int(1000/fps)) == ord('q'):
                break
        cap.release()
        cv2.destroyAllWindows()

    @staticmethod
    def drawtext(image, pt1, pt2, text):
        '''	@func: 根据给出的坐标和文本,在图片上进行绘制
            @para	image: 图片数组; pt1: 左上角坐标; pt2: 右下角坐标; text: 矩形框上显示的文本,即类别信息
            @return: None
        '''
        fontFace = cv2.FONT_HERSHEY_COMPLEX_SMALL  # 字体
        # fontFace = cv2.FONT_HERSHEY_COMPLEX  # 字体
        fontScale = 1.5  # 字体大小
        line_thickness = 3  # 线条粗细
        font_thickness = 2  # 文字笔画粗细
        line_back_color = (0, 0, 255)  # 线条和文字背景颜色:红色
        font_color = (255, 255, 255)  # 文字颜色:白色

        # 绘制矩形框
        cv2.rectangle(image, pt1, pt2, color=line_back_color, thickness=line_thickness)
        # 计算文本的宽高: retval:文本的宽高; baseLine:基线与最低点之间的距离(本例未使用)
        retval, baseLine = cv2.getTextSize(text,fontFace=fontFace,fontScale=fontScale, thickness=font_thickness)
        # 计算覆盖文本的矩形框坐标
        topleft = (pt1[0], pt1[1] - retval[1]) # 基线与目标框上边缘重合(不考虑基线以下的部分)
        bottomright = (topleft[0] + retval[0], topleft[1] + retval[1])
        cv2.rectangle(image, topleft, bottomright, thickness=-1, color=line_back_color) # 绘制矩形框(填充)
        # 绘制文本
        cv2.putText(image, text, pt1, fontScale=fontScale,fontFace=fontFace, color=font_color, thickness=font_thickness)

if __name__ == '__main__':
    clf = Onnx_clf()
    import tkinter as tk
    from tkinter.filedialog import askopenfilename
    tk.Tk().withdraw() # 隐藏主窗口, 必须要用,否则会有一个小窗口
    source = askopenfilename(title="test2.mp4")
    # source = r'C:\Users\Zeoy\Desktop\YOLOData\data\IMG_568.jpg'
    if source.endswith('.jpg') or source.endswith('.png') or source.endswith('.bmp'):
        res, out = clf.img_identify(source, False)
        print(out)
        cv2.imshow('result', res)
        cv2.waitKey(0)
    elif source.endswith('.mp4') or source.endswith('.avi'):
        print('视频识别中...按q退出')
        clf.video_identify(source)
    else:
        print('不支持的文件格式')

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

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

相关文章

Codeforces Round 962 (Div. 3) D. Fun (数学,暴力枚举)

非常好题目&#xff0c;使我思考良多。 经典的数学问题&#xff0c;题目给出了两道数学式子&#xff0c;当然就是要让我们推啊。 首先纠正一个错误&#xff0c;当我发现了这两个式子能凑出来平方式的时候我就想着去用两个式子来互相简化&#xff0c;但其实这样存在以下一个错误…

数据增强和数据平衡

数据增强&#xff08;Data Augmentation&#xff09; 数据增强是一种通过对数据进行变换来增加数据多样性的方法。它可以提高模型的泛化能力&#xff0c;特别是在图像和文本处理任务中。 原理 通过数据增强技术&#xff0c;生成更多样本&#xff0c;提高模型的泛化能力。例如…

Github个人网站搭建详细教程【Github+Jekyll模板】

文章目录 前言一、介绍1 Github Pages是什么2 静态网站生成工具3 Jekyll简介Jekyll 和 GitHub 的关系 4 Mac系统Jekyll的安装及使用安装Jekyll的简单使用 二、快速搭建第一个Github Pages网站三、静态网站模板——Chirpy1 个人定制 四、WordPress迁移到Github参考资料 前言 23…

chrome浏览器驱动(所有版本)

chrome浏览器驱动 114之前版本 https://chromedriver.storage.googleapis.com/index.html 125以后 125以后版本下载链接在此&#xff0c;只有后面status是绿色对勾的才可以下载&#xff0c;驱动大版本一致就可以使用&#xff0c;不需版本号一模一样&#xff1b;下载所需版本只…

STM32智能工业监控系统教程

目录 引言环境准备智能工业监控系统基础代码实现&#xff1a;实现智能工业监控系统 4.1 数据采集模块 4.2 数据处理与控制模块 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;工业监控与优化问题解决方案与优化收尾与总结 1. 引言 智能工业监控系统通…

Java集合框架2024最通俗易懂(图片超全)

集合 1.1、定义 集合就是类型统一的数据组合而成的数据结构&#xff0c;该数据结构可以任意的改变长度。 1.3、Set Set数据存储结构&#xff0c;无序&#xff0c;且不可以重复&#xff0c;元素可以为null&#xff0c;但是也只能出现一次&#xff0c;如下图: 1.3.1、HashSe…

2. 卷积神经网络无法绕开的神——LeNet

卷积神经网络无法绕开的大神——LeNet 1. 基本架构2. LeNet 53. LeNet 5 代码 1. 基本架构 特征抽取模块可学习的分类器模块 2. LeNet 5 LeNet 5: 5 表示的是5个核心层&#xff0c;2个卷积层&#xff0c;3个全连接层.核心权重层&#xff1a;卷积层、全连接层、循环层&#xff…

从零开始学习网络安全渗透测试之基础入门篇——(二)Web架构前后端分离站Docker容器站OSS存储负载均衡CDN加速反向代理WAF防护

Web架构 Web架构是指构建和管理Web应用程序的方法和模式。随着技术的发展&#xff0c;Web架构也在不断演进。当前&#xff0c;最常用的Web架构包括以下几种&#xff1a; 单页面应用&#xff08;SPA&#xff09;&#xff1a; 特点&#xff1a;所有用户界面逻辑和数据处理都包含…

Apache Nifi挂接MQTT与Kafka实践

目录 1. 说明&#xff1a; 2. 方案设计&#xff1a; 2.1 资源配置&#xff1a; 2.2 交互Topics: 3. 实现步骤 3.1 Nifi 桌面 3.2 MqttToKafka 3.2.1 配置 3.2.2 测试 3.2.3 结果 3.3 KafkaToMqtt 3.3.1 配置 3.3.1 测试 3.3.1 结果 ​编辑 4. 总结&#xff…

web学习笔记(八十三)git

目录 1.Git的基本概念 2.gitee常用的命令 3.解决两个人操作不同文件造成的冲突 4.解决两个人操作同一个文件造成的冲突 1.Git的基本概念 git是一种管理代码的方式&#xff0c;广泛用于软件开发和版本管理。我们通常使用gitee&#xff08;码云&#xff09;来云管理代码。 …

使用SpringTask框架

目录 一.什么是SpringTask&#xff1f; 二.cron表达式&#xff1a; 三.SpringTask框架的使用操作&#xff1a; 1.导入maven坐标spring-context&#xff1a; 2.启动类添加 EnableScheduling 以此来开启任务调度&#xff1a; 3.自定义定时任务类&#xff1a; 普通案例&#…

如何写好技术文档 - 来自Google十多年的文档经验

[导读]本文大部分内容翻译总结自《Software Engineering at Google》第10章节 Documentation。另外&#xff0c;该书电子版近日已经可以免费阅读了https://qiangmzsx.github.io/Software-Engineering-at-Google/#/?idsoftware-engineering-at-google&#xff0c;有兴趣的同学可…

Dockerfile指令详解和Docker操作命令

1.容器的特点&#xff1a;1&#xff09;自包含&#xff08;包括应用程序及其运行环境&#xff09;&#xff1b;2&#xff09;可移植&#xff1b;3&#xff09;相互隔离&#xff1b;4&#xff09;轻量级。 2.docker成为容器的事实标准在于&#xff1a;1&#xff09;在运行环境上…

Unity 资源 之 Pop It 3D 解压玩具与双人AI游戏 Unity 资源包分享

精彩呈现&#xff1a;Pop It 3D 解压玩具与双人AI游戏 Unity 资源包分享 一、Pop It 3D 解压玩具的魅力二、双人游戏的互动乐趣三、Unity 游戏资源包的优势四、如何获取资源包 亲爱的游戏爱好者们&#xff0c;今天为大家带来一款令人兴奋的游戏资源——Pop It 3D 解压玩具双人带…

ubuntu串口重命名助手arm64架构(下)Qt交叉编译arm64

✨✨ Rqtz 个人主页 : 点击✨✨ &#x1f388;PyQt系列专栏:点击&#x1f388; &#x1f388;Qt智能车上位机专栏: 点击&#x1f388; &#x1f388;Qt串口助手专栏:点击&#x1f388; &#x1f4ab;宗旨:共享IT之美,共创机器未来 目录 前言 设备介绍 查询系统架构 下载…

【JVM基础05】——组成-能不能解释一下方法区?

目录 1- 引言&#xff1a;方法区概述1-1 方法区是什么&#xff1f;(What)1-2 为什么用方法区&#xff1f;方法区的作用 (Why) 2- ⭐核心&#xff1a;详解方法区(How)2-1 能不能解释一下方法区&#xff1f;2-2 元空间内存溢出问题2-3 什么是常量池&#xff1f;2-4 运行时常量池 …

Stable Diffusion WebUI本地环境搭建

一、项目代码下载 git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui 二、环境配置 conda create --n stafu python3.10.6 实际上跟自己创建的环境没有关系&#xff0c;项目启动会自动复制这个环境&#xff0c;之后项目根据这个基础环境构建 也可以在自己…

【五】MySql8基于m2芯片arm架构Ubuntu24虚拟机安装

文章目录 1. 更新系统包列表2. 安装 MySQL APT Repository3. 更新系统包列表4. 安装 MySQL Server5. 运行安全安装脚本6. 验证 MySQL 安装7. 配置远程连接7.1 首先要确认 MySQL 配置允许远程连接&#xff1a;7.2 重启 MySQL 服务&#xff1a;7.3 检查 MySQL 用户权限&#xff1…

TensorRT推理时间不稳定的解决方案

目录 解决方案 第一步 第二步 效果 解除锁频方法 解决方案 锁定GPU时钟频率&#xff08;实测有效&#xff09; 第一步 使用 nvidia-smi -q -d SUPPORTED_CLOCKS 查询GPU支持的最高频率&#xff0c;如下图所示为 8001 MHz 第二步 cmd&#xff08;管理员权限&#xff09…

0719_驱动2 编写编译linux内核模块

一、编写linux内核模块 linux内核模块三要素&#xff1a; 入口&#xff1a;执行insmod 安装命令操作 出口&#xff1a; 执行rmmod 卸载命令操作 许可证&#xff1a;遵循GPL协议&#xff0c;开源&#xff0c;指定入口地址&#xff0c;出口地址 #include <linux/init.h> #i…