【深度学习】【Opencv】【GPU】python/C++调用onnx模型【基础】

这篇具有很好参考价值的文章主要介绍了【深度学习】【Opencv】【GPU】python/C++调用onnx模型【基础】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【深度学习】【Opencv】【GPU】python/C++调用onnx模型【基础】

提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论


前言

OpenCV是一个基于BSD许可发行的跨平台计算机视觉和机器学习软件库(开源),可以运行在Linux、Windows、Android和Mac OS操作系统上。可以将pytorch中训练好的模型使用ONNX导出,再使用opencv中的dnn模块直接进行加载使用。
系列学习目录:
【CPU】Pytorch模型转ONNX模型流程详解
【GPU】Pytorch模型转ONNX格式流程详解
【ONNX模型】快速部署
【ONNX模型】多线程快速部署
【ONNX模型】opencv_cpu调用onnx
【ONNX模型】opencv_gpu调用onnx


Python版本OpenCV

Windows平台安装OpenCV

博主在win10环境下装anaconda环境,而后搭建onnx模型运行所需的openCV环境。

# 搭建opencv环境
conda create -n opencv_onnx_gpu python=3.10.9 -y
# 激活环境
activate opencv_onnx_gpu 

博主使用opencv-4.8.0版本,GPU版本不能直接通过pip下载安装进行使用,必须要在本地进行编译。编译过程具体参考博主的博文windows10下opencv4.8.0-cuda Python版本源码编译教程。

import cv2
cv2.__version__

opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python

opencv调用onnx模型

随便拷贝一组数据用来测试数据GPU版本相比于CPU版本在速度上的提升。在项目路径下博主拷贝了CAMO数据集。
opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python
将PFNet.onnx也拷贝到项目路径下。
opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python
使用opencv并调用gpu完成了整个推理流程。

import cv2
import numpy as np
import glob
import os
import time

def readImagesInFolder(folderPath,images):
    fileNames = glob.glob(os.path.join(folderPath, '*.jpg'))
    for fileName in fileNames:
        bgrImage = cv2.imread(fileName, cv2.IMREAD_COLOR)
        if bgrImage is not None:
            rgbImage = cv2.cvtColor(bgrImage, cv2.COLOR_BGR2RGB)
            images.append(rgbImage)

def transformation(image, targetSize, mean, std):
    resizedImage = cv2.resize(image, targetSize, interpolation=cv2.INTER_AREA)
    normalized = resizedImage.astype(np.float32)
    normalized /= 255.0
    normalized -= mean
    normalized /= std
    return normalized

def loadModel(onnx_path):
    net = cv2.dnn.readNetFromONNX(onnx_path)
    return net

def main():
    # 图片存放文件路径
    folderPath = "D:/deeplean_demo/opencv_onnx_gpu/CAMO/c"
    rgbImages = []
    readImagesInFolder(folderPath, rgbImages)
    # 加载ONNX模型
    onnx_path = "D:/deeplean_demo/opencv_onnx_gpu/PFNet.onnx"
    net = loadModel(onnx_path)
    # 设置CUDA为后端
    # net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
    # net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
    output_probs = []
    output_layer_names = net.getUnconnectedOutLayersNames()
    # 定义目标图像大小
    target_size = (416, 416)
    # 定义每个通道的归一化参数
    mean = (0.485, 0.456, 0.406) # 均值
    std = (0.229, 0.224, 0.225)  # 标准差
    # 开始计时
    start = time.time()
    for rgb_image in rgbImages:
        # 获取图像的大小
        original_size = (rgb_image.shape[1], rgb_image.shape[0])
        # 图片归一化
        normalized = transformation(rgb_image, target_size, mean, std)
        print(normalized.shape[:2])
        blob = cv2.dnn.blobFromImage(normalized)
        # 将Blob设置为模型的输入
        net.setInput(blob)
        # 运行前向传播
        output_probs = net.forward(output_layer_names)
        # 获取最完整的预测
        prediction = output_probs[3]
        # 预测图变mask
        mask = cv2.resize(np.squeeze(prediction)* 255.0, original_size, interpolation=cv2.INTER_AREA)
    end = time.time()
    # 计算耗时
    elapsed_time = end - start
    # 打印耗时
    print("Elapsed time:", elapsed_time, "seconds")

if __name__ == "__main__":
    main()

gpu模式下250张图片只用了大约13秒。
opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python
假设注释掉与gou相关的代码

net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)

cpu模式下250张图片就用了大约95秒。
opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python


C++版本OpenCV_GPU

Windows平台编译安装OpenCV

博主使用opencv-4.8.0版本,GPU版本不能直接通过官网下载exe进行使用,必须要在本地进行编译。编译过程具体参考博主的博文【windows10下opencv4.8.0-cuda C++版本源码编译教程】。
编译完成后,在输出的文件夹内找到install文件,将其拷贝合适的位置。
opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python
博主新建了一个名为opencv_gpu的文件夹,并将install重命名位build放在其中。
opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python
打开VS 2019:新建新项目---->空项目---->配置项目---->项目路径以及勾选“将解决方案和项目放在同一目录中---->点击创建。
opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python
在解决方案–>源文件–>右键添加新建项。这里暂时可以默认空着不做处理。
opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python
设置OpenCV路径:项目---->属性。假设没有新建cpp文件,空项目的属性页就不会存在C/C++这一项目。
opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python
添加附加包含目录:Release | x64---->C/C+±—>常规---->附加包含目录。
opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python

D:\C++_demo\opencv_gpu\build\x64\vc16\bin
D:\C++_demo\opencv_gpu\build\bin
D:\C++_demo\opencv_gpu\build\include
D:\C++_demo\opencv_gpu\build\include\opencv2

链接器:Release | x64---->链接器---->常规---->附加包含目录。
opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python

D:\C++_demo\opencv_gpu\build\x64\vc16\lib

链接器:Release | x64---->链接器---->输入---->附加依赖项。
opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python
在D:\C++_demo\opencv_gpu\build\x64\vc16\lib下找到附加依赖项的文件。

opencv_world480.lib

在Release x64模式下测试,将opencv_world480.dll文件复制到自己项目的Release下。

没有Release目录时,需要在Release | x64模式下运行一遍代码,代码部分在下一节提供,读者可以先行新建文件复制代码。

D:\C++_demo\opencv_gpu\build\x64\vc16\bin
===>
D:\C++_demo\opencv_onnx_gpu\x64\Releas

opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python
这里博主为了方便安装的是release版本的,读者可以安装debug版本的,流程基本一致,只需要将属性的Release | x64变成Debug | x64,然后附加依赖项由opencv_world480.lib变成opencv_world480d.lib,再将opencv_world480d.dll文件复制到自己项目的Release下。前提是你编译了debug版本oepncv。

opencv调用onnx模型

随便拷贝一组数据用来测试数据GPU版本相比于CPU版本在速度上的提升。在项目路径下博主拷贝了CAMO数据集。
opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python
将PFNet.onnx也拷贝到项目路径下。
opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python
将python版本的opencv转化成对应的c++版本的,发现输出的效果完全一致,onnx模型可以作为c++的接口来供其他应用调用。

#include <iostream>
#include <string>
#include <vector>
#include<opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
using namespace std;
void readImagesInFolder(const std::string& folderPath, std::vector<cv::Mat>& images)
{
    cv::String path(folderPath + "/*.jpg"); // 这里假设你的图片格式是.jpg,如果是其他格式请相应修改
    std::vector<cv::String> fileNames;
    cv::glob(path, fileNames, true); // 通过glob函数获取文件夹内所有符合格式的文件名
    for (const auto& fileName : fileNames)
    {   // 使用imread函数读取图片
        cv::Mat bgrImage = cv::imread(fileName, cv::IMREAD_COLOR); 
         // 图片格式转化bgr-->rgb
        if (!bgrImage.empty())
        {	
        	cv::Mat rgbImage;
            cv::cvtColor(bgrImage, rgbImage, cv::COLOR_BGR2RGB);
            images.push_back(rgbImage);
        }
    }
}

cv::Mat transformation(const cv::Mat& image, const cv::Size & targetSize, const cv::Scalar& mean, const cv::Scalar& std) {

    cv::Mat resizedImage;
    //图片尺寸缩放
    cv::resize(image, resizedImage, targetSize, 0, 0, cv::INTER_AREA);
    cv::Mat normalized;
    resizedImage.convertTo(normalized, CV_32F);
    cv::subtract(normalized / 255.0, mean, normalized);
    cv::divide(normalized, std, normalized);
    return normalized;
}
cv::dnn::Net loadModel(const string& onnx_path) {
    cv::dnn::Net net = cv::dnn::readNetFromONNX(onnx_path);
    return net;
}
int main()
{   // 图片存放文件路径
    string folderPath = "D:/C++_demo/opencv_onnx_gpu/CAMO/c";
    std::vector<cv::Mat> rgbImages;
    readImagesInFolder(folderPath, rgbImages);

   // string image_path = "./animal-1.jpg";
    // 加载ONNX模型
    string onnx_path = "D:/C++_demo/opencv_onnx_gpu/PFNet.onnx";
    cv::dnn::Net net = loadModel(onnx_path);
    // 设置CUDA为后端
    net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
    net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
    cv::Mat output_prob;
    std::vector<cv::Mat> output_probs;
    std::vector<cv::String> output_layer_names = net.getUnconnectedOutLayersNames();

    // 定义目标图像大小
    cv::Size targetSize(416, 416);
    // 定义每个通道的归一化参数
    cv::Scalar mean(0.485, 0.456, 0.406); // 均值
    cv::Scalar std(0.229, 0.224, 0.225);  // 标准差

    // 开始计时
    auto start = chrono::high_resolution_clock::now();
    for (const auto& rgbImage : rgbImages) {
        // 获取图像的大小
        cv::Size originalSize(rgbImage.cols, rgbImage.rows);
        //cv::imshow("输入窗口", rgbImage);
        //cv::waitKey(0);
        //cv::destroyAllWindows();
        // 图片归一化
        cv::Mat normalized = transformation(rgbImage, targetSize, mean, std);
        std::cout << normalized.size() << std::endl;
        cv::Mat blob = cv::dnn::blobFromImage(normalized);
        // 将Blob设置为模型的输入
        net.setInput(blob);
        // 运行前向传播
        net.forward(output_probs, output_layer_names);
        // 获取最完整的预测
        cv::Mat prediction = output_probs[3];
        // 预测图变mask
        cv::Mat mask;
        cv::resize(prediction.reshape(1, 416) * 255.0, mask, originalSize, 0, 0, cv::INTER_AREA);
    }
    auto end = std::chrono::high_resolution_clock::now();
    // 计算耗时
    std::chrono::duration<double> elapsed = end - start;
    double elapsedTime = elapsed.count();
    // 打印耗时
    std::cout << "Elapsed time: " << elapsedTime << " seconds" << std::endl;
    return 0;
}

gpu模式下250张图片只用了大约16秒。
opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python
假设注释掉与gou相关的代码

net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);

cpu模式下250张图片就用了大约95秒。
opencv加载onnx模型,opencv,onnx,深度学习,深度学习,opencv,python


总结

尽可能简单、详细的介绍Python和C++下Opencv_GPU调用ONNX模型的流程。文章来源地址https://www.toymoban.com/news/detail-760362.html

到了这里,关于【深度学习】【Opencv】【GPU】python/C++调用onnx模型【基础】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【深度学习】python使用opencv调用摄像头拍摄并保存图片

    打开pycharm,新建一个camerm.py文件,把下面代码复制粘贴进去就可以了。 需要安装两个库:pip install opencv-python;pip install numpy

    2024年02月11日
    浏览(42)
  • 【深度学习】pytorch pth模型转为onnx模型后出现冗余节点“identity”,onnx模型的冗余节点“identity”

    onnx模型的冗余节点“identity”如下图。 首先,确保您已经安装了onnx-simplifier库: 然后,您可以按照以下方式使用onnx-simplifier库: 通过这个过程,onnx-simplifier库将会检测和移除不必要的\\\"identity\\\"节点,从而减少模型中的冗余。 请注意,使用onnx-simplifier库可能会改变模型的计算

    2024年02月09日
    浏览(45)
  • 深度学习模型部署综述(ONNX/NCNN/OpenVINO/TensorRT)

    点击下方 卡片 ,关注“ 自动驾驶之心 ”公众号 ADAS巨卷干货,即可获取 今天自动驾驶之心很荣幸邀请到 逻辑牛 分享深度学习部署的入门介绍,带大家盘一盘ONNX、NCNN、OpenVINO等框架的使用场景、框架特点及代码示例。如果您有相关工作需要分享,请在文末联系我们! 点击

    2024年02月08日
    浏览(49)
  • ONNX格式模型 学习笔记 (onnxRuntime部署)---用java调用yolov8模型来举例

    ONNX(Open Neural Network Exchange)是一个开源项目,旨在建立一个开放的标准,使深度学习模型 可以在不同的软件平台和工具之间轻松移动和重用 。 ONNX模型可以用于各种应用场景,例如机器翻译、图像识别、语音识别、自然语言处理等。 由于ONNX模型的互操作性,开发人员 可以

    2024年01月22日
    浏览(47)
  • 【深度学习】ONNX 模型文件修改节点的名称,修改输入名称,修改输出名称

    想要修改onnx模型文件的节点名称,要么在最初的pytorch代码里去改,要么就直接在onnx模型文件里改。 而我这里直接在onnx模型文件改,我有一个onnx文件,输出节点的名字是这样的: 这不改就看着真难受,那么就用python改: 改完后: 其实修改其他节点的名称也可以这样去做,

    2024年02月15日
    浏览(46)
  • win10跑深度学习程序无法调用gpu的问题(已解决)

    win10跑深度学习真的是一言难尽,但是windows系统又使用的比较习惯,过去使用过ubuntu系统,里面写文档什么的确实不习惯,所以自己做的实验项目也主要是以win10为主工具是常见的pycharm+anaconda+win10 采用的是keras2.3.1,更改了程序中一些代码之后,每次跑模型都会中断 记录一下

    2024年01月16日
    浏览(48)
  • ONNX Runtime 加速深度学习(C++ 、python)详细介绍

    本文在 https://blog.csdn.net/u013250861/article/details/127829944 基础上进行了更改,感谢原作! ONNXRuntime(Open Neural Network Exchange)是微软推出的一款针对ONNX模型格式的推理框架,用户可以非常便利的用其运行一个onnx模型。ONNXRuntime支持多种运行后端包括CPU,GPU,TensorRT,DML等。可以说ONN

    2024年02月15日
    浏览(53)
  • 试用阿里云GPU服务器进行深度学习模型训练

    最近在用PyTorch时发现在本地训练模型速度一言难尽,然后发现阿里云可以白嫖gpu服务器,只要没有申请过PAI-DSW资源的新老用户都可以申请5000CU*H的免费额度,三个月内有效。 阿里云免费试用活动页面 一、申请试用并创建实例 点击试用,完成注册、实名、领取产品,然后前往

    2024年04月17日
    浏览(60)
  • 深度学习跑模型,关于电脑出现GPU0和1?

    不知道有没有小伙伴出现过这样的困扰? 笔记本电脑打开任务管理器后,发现自己的游戏本明明是独立显卡,比如我的RTX4060,特别是在跑深度学习模型时,指定device为cuda:0,进程中显示独显GPU1没什么利用率,而核显一直在很高的利用?甚至代码还会报错,提示没有可用的

    2024年02月12日
    浏览(37)
  • opencv调用yolov7 yolov7 c++ yolov7转onnx opencv调用yolov7 onnx 一、YOLOV7主要贡献:

            主要是现有的一些trick的集合以及模块重参化和动态标签分配策略,最终在 5 FPS 到 160 FPS 范围内的速度和准确度都超过了所有已知的目标检测器。         当前目标检测主要的优化方向:更快更强的网络架构;更有效的特征集成方法;更准确的检测方法;更精

    2023年04月22日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包