【深度学习】【Opencv】Python/C++调用onnx模型【基础】
【深度学习】【Opencv】python/C++调用onnx模型【基础】
提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论
文章目录
- 【深度学习】【Opencv】python/C++调用onnx模型【基础】
- 前言
- Python版本OpenCV
- Windows平台安装OpenCV
- opencv调用onnx模型
- C++版本OpenCV
- Windows平台安装OpenCV
- opencv调用onnx模型
- 简单使用
- 调用onnx模型
- 总结
前言
OpenCV是一个基于BSD许可发行的跨平台计算机视觉和机器学习软件库(开源),可以运行在Linux、Windows、Android和Mac OS操作系统上。可以将pytorch中训练好的模型使用ONNX导出,再使用opencv中的dnn模块直接进行加载使用。
系列学习目录:
【CPU】Pytorch模型转ONNX模型流程详解
【GPU】Pytorch模型转ONNX格式流程详解
【ONNX模型】快速部署
【ONNX模型】多线程快速部署
【ONNX模型】Opencv调用onnx
Python版本OpenCV
Windows平台安装OpenCV
博主在win10环境下装anaconda环境,而后搭建onnx模型运行所需的openCV环境。
# 搭建opencv环境
conda create -n opencv_onnx python=3.10 -y
# 激活环境
activate opencv_onnx
# 安装opencv
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python
查看opencv版本
import cv2
cv2.__version__
opencv调用onnx模型
现在代码抛开任何pytorch相关的依赖,也抛开了onnx相关的依赖,只使用opencv完成了整个推理流程。
import cv2
import numpy as npdef normalizeImage(image,mean,std):normalized = image.astype(np.float32)normalized = normalized / 255.0 - meannormalized = normalized / stdreturn normalizeddef main():# 读取图片image = cv2.imread(r"./animal-1.jpg")# 将BGR图像转换为RGB格式image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)# 获取图像的大小ori_w, ori_h, = image.shape[0], image.shape[1]# 指定调整后的大小new_width = 416new_height = 416# 图片尺寸缩放resized_img = cv2.resize(image, (new_width, new_height), interpolation=cv2.INTER_AREA)# 定义每个通道的归一化参数mean = np.array([0.485, 0.456, 0.406]).astype(np.float32) # 均值std = np.array([0.229, 0.224, 0.225]).astype(np.float32) # 标准差# 图片归一化normalized = normalizeImage(resized_img, mean, std)# 加载ONNX模型net = cv2.dnn.readNetFromONNX("PFNet.onnx") # 加载训练好的识别模型# onnx是多输出,每个输出都会对应一个name,因此需要获取所有输出的nameoutput_layer_names = net.getUnconnectedOutLayersNames()blob = cv2.dnn.blobFromImage(normalized) # 由图片加载数据 这里还可以进行缩放、归一化等预处理# 将Blob设置为模型的输入net.setInput(blob)# 运行前向传播,将所有输出name作为参数传递out = net.forward(output_layer_names)out = np.squeeze(out[3]) * 255.0output = cv2.resize(out, (ori_h, ori_w), interpolation=cv2.INTER_AREA)# 保存图像cv2.imwrite('saved_opencv_python_image.png', output)if __name__ == '__main__':main()
C++版本OpenCV
Windows平台安装OpenCV
官网下载安装文件地址,博主使用opencv-4.8.0-windows.exe版本双击运行解压后即可获得以下文件:
打开VS 2019:新建新项目---->控制台应用---->配置项目---->项目路径以及勾选“将解决方案和项目放在同一目录中---->点击创建。
设置OpenCV路径:项目---->属性。
添加附加包含目录:Debug | x64---->C/C+±—>常规---->附加包含目录。
D:\C++_demo\opencv\build\x64\vc16\bin
D:\C++_demo\opencv\build\bin
D:\C++_demo\opencv\build\include
D:\C++_demo\opencv\build\include\opencv2
链接器:Debug | x64---->链接器---->常规---->附加包含目录。
D:\C++_demo\opencv\build\x64\vc16\lib
链接器:Debug | x64---->链接器---->输入---->附加依赖项。
在D:\C++_demo\opencv\build\x64\vc16\lib下找到附加依赖项的文件。
opencv_world480d.lib
在Debug x64模式下测试,要将带有d的opencv_world480d.dll文件复制到自己项目的Debug下。
没有Debug目录时,需要在Debug | x64模式下运行一遍代码。
D:\C++_demo\opencv\build\x64\vc16\bin
===>
D:\C++_demo\opencv_onnx\x64\Debug
这里博主为了方便调试安装的是debug版本的,读者可以安装release版本的,只需要将属性的Debug | x64变成Release | x64即可,再将opencv_world480.dll文件复制到自己项目的Release下。
opencv调用onnx模型
简单使用
这里简单验证一下opencv是否安装成功,适用于包括博主在内的许多对c++不熟悉的人来说,代码完成了简单的图像的读取与显示。
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {Mat src = imread("./animal-1.jpg");//没有图像输入if (src.empty()) {printf("....\n");return -1;}//namedWindow("输入窗口", WINDOW_FREERATIO);imshow("输入窗口", src);waitKey(0);destroyAllWindows();return 0;
}
调用onnx模型
将python版本的opencv转化成对应的c++版本的,发现输出的效果完全一致,onnx模型可以作为c++的接口来供其他应用调用。
#include <iostream>
#include <string>
#include <vector>
#include<opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
using namespace std;
cv::Mat normalizeImage(const cv::Mat& image, const cv::Scalar& mean, const cv::Scalar& std) {cv::Mat normalized;image.convertTo(normalized, CV_32F);cv::subtract(normalized / 255.0, mean, normalized);cv::divide(normalized, std, normalized);return normalized;
}
int main()
{ // 读取图片cv::Mat bgrImage = cv::imread("./animal-1.jpg", cv::IMREAD_COLOR);// 图片格式转化bgr-->rgbcv::Mat rgbImage;cv::cvtColor(bgrImage, rgbImage, cv::COLOR_BGR2RGB);// 获取图像的大小cv::Size originalSize(rgbImage.cols, rgbImage.rows);cv::Mat resizedImage;// 定义目标图像大小cv::Size targetSize(416, 416);//图片尺寸缩放cv::resize(rgbImage, resizedImage, targetSize, 0, 0, cv::INTER_AREA);// 定义每个通道的归一化参数cv::Scalar mean(0.485, 0.456, 0.406); // 均值cv::Scalar std(0.229, 0.224, 0.225); // 标准差// 图片归一化cv::Mat normalized = normalizeImage(resizedImage, mean, std);// 加载ONNX模型cv::dnn::Net net = cv::dnn::readNetFromONNX("D:/C++_demo/opencv_onnx/PFNet.onnx");cv::Mat blob = cv::dnn::blobFromImage(normalized);// 将Blob设置为模型的输入net.setInput(blob);// 运行前向传播std::vector<cv::Mat> output_probs;// 获取多输出对应的名称std::vector<cv::String> output_layer_names = net.getUnconnectedOutLayersNames();net.forward(output_probs, output_layer_names);cv::Mat prediction = output_probs[3];cv::Mat mask;cv::resize(prediction.reshape(1, 416) * 255.0, mask, originalSize, 0, 0, cv::INTER_AREA);cv::imwrite("saved_opencv_c++_image.png", mask);return 0;
}
总结
尽可能简单、详细的介绍Python和C++下POpencv调用ONNX模型的流程。
相关文章:

【深度学习】【Opencv】Python/C++调用onnx模型【基础】
【深度学习】【Opencv】python/C调用onnx模型【基础】 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【深度学习】【Opencv】python/C调用onnx模型【基础】前言Python版本OpenCVWindows平台安装OpenCVopencv调用onnx模型 C版本OpenCVWindows平…...

C# MQTT通讯
文章目录 前言MQTTnetMQTT初始变量生成option连接Mqtt服务器发送数据添加订阅 前言 MQTTnet是Mqtt的net版本。国内MQTTnet教程比较老旧,都是2.x版本。MQTTnet在4.x版本版本代码逻辑有比较大的改动。所以最后还是面向Github编程。 EMQ X介绍及安装 长链接(MQTT)测…...

使用c++实现输出爱心(软件:visual Studio)
#include <iostream> using namespace std;int main() {//爱心曲线方程(x^2y^2-a)^3-x^2*y30double a 0.5;//定义绘图边界double bound 1.3 * sqrt(a);//x,y坐标变化步长double step 0.05;//二维扫描所有点,外层逐层扫描for (double y bound; y > -bound; y - ste…...

uploadifive上传工具php版使用
uploadifive自带的DEMO文件。 下载地址: http://www.uploadify.com/download/ <!DOCTYPE HTML> <html> <head> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"> <title>UploadiFive Test&…...
Docker容器管理
docker容器相当于一个进程,性能接近于原生,几乎没有损耗; docker容器在单台主机上支持的数量成百上千; 容器与容器之间相互隔离; 镜像是创建容器的基础,可以理解镜像为一个压缩包 Docker容器的管理 容…...

【文末送书】用Chat GPT轻松玩转机器学习与深度学习
欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和技术。关…...

Redis的学习
Redis Redis特征 键值型,value支持多种不同数据结构,功能丰富单线程,每个命令具有原子性低延迟,速度快(基于内存,IO多路复用,良好的编码)支持数据持久化支持主从集群,分…...

java版Spring Cloud+Mybatis+Oauth2+分布式+微服务+实现工程管理系统
鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展,企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性,公司对内部工程管…...
Vue 3的 h 函数详解
Vue 3的 h 函数详解 文章目录 Vue 3的 h 函数详解1、什么是h函数2、基本用法3、动态组件4、事件监听器5、条件渲染 Vue 3的 h函数( createVNode)是前端开发中一个强大的工具,用于创建虚拟DOM节点。虚拟DOM是Vue框架中的核心概念,…...

防近视台灯什么牌子好?推荐有效预防近视的台灯
作为一名家长,平常最关心的应该就是孩子能够健康成长了。但是通过调查数据我们可以发现我国青少年近视率位居世界第一,儿童青少年总体近视率为52.7%;其中6岁儿童为14.5%,小学生为36.0%,初中生为71.6%,高中生…...

五、C#—字符串
🌻🌻 目录 一、字符串1.1 字符类型1.2 转义字符1.3 字符串的声明及赋值1.3.1 c# 中的字符串1.3.2 声明字符串1.3.3 使用字符串1.3.4 字符串的初始化1.3.4.1 引用字符串常量之初始化1.3.4.2 利用字符数组初始化1.3.4.3 提取数组中的一部分进行初始化 1.3.…...

【Vue3 源码解析】nextTick
nextTick 是 Vue 3 中用于异步执行回调函数的函数,它会将回调函数延迟到下一个微任务队列中执行。其中,Vue 更新 DOM 是异步的。下面是对 nextTick 函数的详细解释: export function nextTick<T void, R void>(this: T,fn?: (this:…...

基于ModebusRTU通信采集温度湿度项目案例
目录 一、模拟温湿度模拟 【1.1】温湿度仪表参数 【1.1】使用电脑模拟传感器 【1.2】使用Codesys软件模拟传感器 二、自定义控件UI设计 【2.1】自定义控件温度湿度柱状设计 编辑 【2.1.1】设置温度湿度柱状实际显示【属性】 【2.1.2】设置温度湿度柱状的背景颜色【属…...

【已解决】关于如何将Doccano标注的文本转换成NER模型可以直接处理的CoNLL 2003格式
笔者要做命名实体识别(NER)的工作,选择了Doccano平台来进行文本标注。 Doccano平台对标注结果的导出格式是JSONL格式,我们导出了NER.jsonl文件。 但是用python语言搭建深度学习模型来实现NER时,一般接收的输入数据格式…...

网络编程day03(UDP中的connect函数、tftp)
今日任务:tftp的文件上传下载(服务端已经准备好) 服务端(已上传) 客户端: 代码: #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h…...

flarum 论坛 User Statistics插件修改
此插件在中国使用日期不是很理想,于是决定修改代码 下面是插件信息: User Statistics A Flarum extension. Add some user statistics in flarum posts, this extension require clarkwinkelmann/flarum-ext-likes-received and will be installed au…...

阿里云产品试用系列-容器镜像服务 ACR
阿里云容器镜像服务(简称 ACR)是面向容器镜像、Helm Chart 等符合 OCI 标准的云原生制品安全托管及高效分发平台。 ACR 支持全球同步加速、大规模/大镜像分发加速、多代码源构建加速等全链路提效,与容器服务 ACK 无缝集成,帮助企业…...
Langchain里的“记忆力”,让AI只记住有用的事
今天要讲以下内容: 1.ConversationBufferWindowMemory:基于一个固定长度的滑动窗口的“记忆”功能 2.ConversationSummaryMemory:总结对话“记忆”功能 3.ConversationSummaryBufferMemory:上面两个的结合,超过一定…...

从零开始的LINUX(一)
LINUX本质是一种操作系统,用于对软硬件资源进行管理,其管理的方式是指令。指令是先于图形化界面产生的,相比起图形化界面,指令显然更加难以理解,但两者只是形式上的不同,本质并没有区别。 简单的指令&…...

CH34X-MPHSI高速Master扩展应用—I2C设备调试
一、前言 本文介绍,基于USB2.0高速USB转接芯片CH347,配合厂商提供的USB转MPHSI(Multi Protocol High-Speed Serial Interface)Master总线驱动(CH34X-MPHSI-Master)为系统扩展I2C总线的用法,除…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...