基于OnnxRuntime在C++端部署YOLOV5

使用C++部署应用onnx模型 在C++下部署onnx模型的示例程序,包含各个API的解释。 阅读详情
// OnnxRuntimeInference.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#pragma once
#include <iostream>
#include <assert.h>
#include <vector>
#include <onnxruntime_cxx_api.h>
#include <string>
#include <opencv2/opencv.hpp>

#include "postProcess.h"

using namespace std;
using namespace cv;
using namespace postProcess;


void preDataDet(cv::Mat& matSrc, int& model_width, int& model_height, cv::Mat& matDst)
{
    cv::cvtColor(matSrc, matDst, cv::COLOR_BGR2RGB);
    cv::resize(matDst, matDst, cv::Size(model_width, model_height));
    matDst.convertTo(matDst, CV_32FC3);

    matDst = matDst / 255.0f;
}

int main()
{
    Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "ONNX_DETECTION"); //设置图优化类型
    Ort::SessionOptions session_options;
    session_options.SetIntraOpNumThreads(1);
    session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_BASIC);
#ifdef _WIN32
    const wchar_t* model_path = L"/OnnxRuntimeInference/weights/yolov5_model/best.onnx";
#else
    const char* model_path = "/OnnxRuntimeInference/weights/yolov5_model/best.onnx";
#endif

    Ort::Session session(env, model_path, session_options); // 创建会话,把模型加载到内存中 CPU
    // print model input layer (node names, types, shape etc.)
    Ort::AllocatorWithDefaultOptions allocator;
    size_t num_input_nodes = session.GetInputCount();

    size_t numInputNodes = session.GetInputCount(); //输入输出节点数量                         
    size_t numOutputNodes = session.GetOutputCount();


    vector<char*> input_names;  // 定义一个字符指针vector
    vector<char*> output_names; // 定义一个字符指针vector
    vector<vector<int64_t>> input_node_dims; // >=1 outputs  ,二维vector
    vector<vector<int64_t>> output_node_dims; // >=1 outputs ,int64_t C/C++标准

    for (int i = 0; i < numInputNodes; i++)
    {
        input_names.push_back(session.GetInputName(i, allocator));		// 内存
        Ort::TypeInfo input_type_info = session.GetInputTypeInfo(i);   // 类型
        auto input_tensor_info = input_type_info.GetTensorTypeAndShapeInfo();  // 
        auto input_dims = input_tensor_info.GetShape();    // 输入shape
        input_node_dims.push_back(input_dims);	// 保存
        
        std::cout << "InputName: " << session.GetInputName(i, allocator)<< "  InputShape: ";
        std::copy(input_dims.begin(), input_dims.end(), std::ostream_iterator<int64_t>(std::cout, " "));
        std::cout << std::endl;
    }

    for (int i = 0; i < numOutputNodes; i++)
    {
        output_names.push_back(session.GetOutputName(i, allocator));
        Ort::TypeInfo output_type_info = session.GetOutputTypeInfo(i);
        auto output_tensor_info = output_type_info.GetTensorTypeAndShapeInfo();
        auto output_dims = output_tensor_info.GetShape();
        output_node_dims.push_back(output_dims);

        std::cout << "OutputName: " << session.GetOutputName(i, allocator) << "  OutputShape: ";
        std::copy(output_dims.begin(), output_dims.end(), std::ostream_iterator<int64_t>(std::cout, " "));
        std::cout << std::endl;
    }

    int nModelwidth = 640; //模型input width
    int nModelheigh = 640; //模型input height

    // 定义一个输入矩阵,int64_t是下面作为输入参数时的类型
    array<int64_t, 4> input_shape_{ 1, 3, nModelheigh, nModelwidth };  //NCHW  1,3,640,640 

    //std::array<float, nModelheigh * nModelwidth * 3> input_image_{}; //输入图片,HWC,不建议这样写,在栈上创建较大的数组容易出现栈溢出(Stack Overflow)的问题
    std::vector<float> input_image_(nModelheigh * nModelwidth * 3, 0.0f);


    std::string imgPath = "\\OnnxRuntimeInference\\weights\\yolov5_model\\test.bmp";
    cv::Mat srcMat = cv::imread(imgPath);

    int srch = srcMat.rows, srcw = srcMat.cols;

    cv::Mat matNormImage;
    preDataDet(srcMat, nModelwidth, nModelheigh, matNormImage); // 减均值除方差

    for (int i = 0; i < nModelheigh; ++i) {
        for (int j = 0; j < nModelwidth; ++j) {
            for (int c = 0; c < srcMat.channels(); ++c) {
                //input_image_[c * nModelheigh * nModelwidth + i * nModelwidth + j]= matNormImage.at<cv::Vec<float, 3>>(i, j)[c];
                input_image_[c * nModelheigh * nModelwidth + i * nModelwidth + j]= matNormImage.at<float>(i, j * srcMat.channels() + c);
            }


        }
    }

    //创建输入tensor
    /*
    这一行代码的作用是创建一个指向CPU内存的分配器信息对象(AllocatorInfo),用于在运行时分配和释放CPU内存。它调用了CreateCpu函数并传递两个参数:OrtDeviceAllocator和OrtMemTypeCPU。
    其中,OrtDeviceAllocator表示使用默认的设备分配器,OrtMemTypeCPU表示在CPU上分配内存。通过这个对象,我们可以在运行时为张量分配内存,并且可以保证这些内存在计算完成后被正确地释放,避免内存泄漏的问题。
    */
    auto allocator_info = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
    //使用Ort库创建一个输入张量,其中包含了需要进行目标检测的图像数据。
    Ort::Value input_tensor_ = Ort::Value::CreateTensor<float>(allocator_info, input_image_.data(), input_image_.size(), input_shape_.data(), input_shape_.size());

    // 开始推理
    vector<Ort::Value> ort_outputs = session.Run(Ort::RunOptions{ nullptr }, &input_names[0], &input_tensor_, 1, output_names.data(), output_names.size());   // 开始推理

    // generate proposals
    std::cout<<"ort_outputs_size: "<<ort_outputs.size()<<std::endl;

    const float* prob = ort_outputs[0].GetTensorMutableData<float>(); // 数组,存放预测数据 [bs,anchor'classes,anchor'number,pos+conf+ num'classes]

    int img_w = 8;
    int img_h = 25200;

    cv::Mat probImg = cv::Mat(cv::Size(img_w, img_h), CV_32FC1);
    //单张图
    memcpy(probImg.data, (float*)prob, (size_t)img_w * img_h * sizeof(float));

    std::vector<int> candi;
    for (size_t y = 0; y < probImg.rows; ++y)
    {
        float tmpVal = probImg.at<float>(y, 4);

        //std::cout << y << " " << tmpVal << std::endl;

        if (tmpVal > 0.5)
        {
            //std::cout << y << " " << tmpVal << std::endl;
            candi.push_back(y);
        }
    }

    //Detections matrix nx6 (xyxy, conf, cls)
    std::vector<TDetectBbox> all_box;
    for (size_t g = 0; g < candi.size(); ++g)
    {
        float* ptr = probImg.ptr<float>(candi[g]);  //候选行的首地址

        TDetectBbox candi_single;
        std::vector<float> score;

        for (size_t m = 0; m < 3; ++m) //3个类别 获取类别得分
        {
            float _temVal = ptr[m + 5];
            score.push_back(_temVal);
        }

        //返回score的最大值和index
        float _score{ 0.0 };
        int classIndx = findVectorMax(score, _score); // 获取得分最高的类别

        candi_single.x0 = ptr[0] - ptr[2] / 2;
        candi_single.y0 = ptr[1] - ptr[3] / 2;
        candi_single.x1 = ptr[0] + ptr[2] / 2;
        candi_single.y1 = ptr[1] + ptr[3] / 2;
        float _confThresh = ptr[4];
        candi_single.confidence = ptr[4] * _score;
        candi_single.classIndx = classIndx;
        all_box.push_back(candi_single);
    }

    //计算nms
    nms(all_box, 0.4);

    //计算坐标映射关系
    int shift_x{ 0 }, shift_y{ 0 };
    float scale_x{ .0f }, scale_y{ .0f };
    //当前是直接resize

    scale_x = (float)nModelwidth / srcw;
    scale_y = (float)nModelheigh / srch;

    for (size_t i = 0; i < all_box.size(); i++)
    {
        if (all_box[i].confidence > 0.1)
        {
            int x1 = max(0, (int)(all_box[i].x0 - shift_x) / scale_x);
            int y1 = max(0, (int)(all_box[i].y0 - shift_y) / scale_y);
            int x2 = min(srcMat.cols, (int)(all_box[i].x1 - shift_x) / scale_x);
            int y2 = min(srcMat.rows, (int)(all_box[i].y1 - shift_y) / scale_y);

            cv::rectangle(srcMat, cv::Rect(x1, y1, x2 - x1, y2 - y1), cv::Scalar(255, 255, 255));

            std::cout << "confidence: " << all_box[i].confidence << std::endl;
        }
    }
    //cv::imwrite("\\OnnxRuntimeInference\\weights\\yolov5\\output.bmp", srcMat);
    cv::imshow("Image", srcMat);
    cv::waitKey(0);

    std::cout << "Hello World!\n";
    return 0;


}



C++ 上用 ONNXruntime 部署自己的模型 利用C++ ONNXruntime部署自己的模型,这里用Keras搭建好的一个网络模型来举例,转换为onnx的文件,在C++上进行部署,另外可以利用tensorRT加速。 目录一、模型的准备二、配置ONNXruntime三、模型的部署1. 模型的初始化设置2. 构建推理构建推理函数computPoseDNN()步骤:函数具体代码:四、应用参考 一、模型的准备 搭建网络模型训练: tensorflow keras 搭建相机位姿估计网络–例 网络的输入输出为: 网络的输入: [image_ref , ima 阅读详情

相关推荐

VS c++ onnxruntime 环境配置、onnx教程、部署推理模型、sklearn pkl模型转onnx、问题汇总

VS c++ onnxruntime 环境配置、onnx教程、部署推理模型、sklearn pkl模型转onnx、问题汇总

AIcar_lrm的博客 1万+

【AI芯片】ONNXRuntime

ONNXRuntime是微软推出的一款推理框架,用户可以非常便利的用其运行一个onnx模型。ONNXRuntime支持多种运行后端包括CPU,GPU,TensorRT,DML等。可以说ONNXRuntime是对ONNX模型最原生的支持。 虽然大家用ONNX时更多的是作为一个中间表示,从pytorch转到onnx后直接喂到TensorRT或MNN等各种后端框架,但这并不能否认ONNXRuntime是一款非常优秀的推理框架。而且由于其自身只包含推理功能(最新的ONNXRuntime甚至已经可以训练),通过阅读其

qq_35608277的博客 2352

使用onnx c++部署pytorch神经网络模型全流程

C++调用ONNXRUNTIME推理pytorch模型

amateur_的博客 1万+

如何5分钟用 lite.ai.toolkit 跑通 YOLOv5 目标检测?Linux 环境配置与编译完整指南

lite.ai.toolkit 是一个轻量的 C++ AI 工具箱,内置 100+ 视觉模型的开箱即用推理实现。本文手把手带你完成 Linux 环境配置与编译,5 分钟跑通 **YOLOv5 目标检测**:从克隆仓库、一键编译,到运行示例并得到带检测框的结果图,全程无需手动安装 OpenCV 和 ONNXRuntime。 ## 为什么选 lite.ai.toolkit 跑 YOLOv5?🎯

gitblog_00956的博客 505

Onnxruntime部署C++,基于YOLOV5,YoloV8(ONNXruntime逐行讲解)

onnxruntime版本:1.20.0 网址csdn - 安全中心opencv版本:4.5.5将压缩得到的include和lib添加到程序运行所需环境中。我使用的是Clion,使用的cmkelist,代码如下。

qq_54700713的博客 3450

C++ OnnxRuntime部署yolov8模型

本篇主要介绍yolov8检测和分割模型利用OnnxRuntime进行部署

君莫笑 2861

yolov5使用onnxruntime进行c++部署

c++单文件部署之使用onnxruntime通过代码熟悉onnxrununtime用于检测部署的整个流程,c++部署。

weixin_41311686的博客 9008

什么是论文的创新点?公式化描述算是创新点吗?

写科研论文时,挑战之一就是如何让你的工作“脱颖而出”,也就是要有创新性。不管实验多么精确、推导多么复杂,若没有真正的创新,论文很可能会被拒。关于如何创新问题上,我最近在看刘雪峰老师的《科技论文写作指南》,看到了很多关于写作的新论述,在这里和大家进行分享。

加百力 的技术博客 1926

基于c++ onnxruntime部署yolov5模型

最近因业务需要需要使用yolo模型来做目标检测的任务,翻了网上的各种博客没有比较完整的教程,在部署过程踩了不少坑,特别是在装英伟达驱动和cuda\cudnn版本时,甚至把ubuntu系统搞坏。于是想把训练及部署过程记录下来,并留给后来者方便使用。实验的系统是ubuntu20.04。

二爷的博客 4410

OpenMV模块视觉测距(避障)+颜色识别+TFT-LCD显示(实现原理与代码分析)

上图所示代码实际运行的帧率比较低,主要原因有以下两个:1.硬件问题,博主使用的版本比较低,可以尝试使用高版本OpenMV2.图像滤波问题。之前加入图像滤波是想提高色块识别的准确性,但是相应的运算速度也会下降。

ediykk的博客 1万+

Jasypt 开源加密库使用教程

Jasypt 加密框架概述 1、Jasypt Spring Boot 为 spring boot 应用程序中的属性源提供加密支持,出于安全考虑,Spring boot 配置文件中的敏感信息通常需要对它进行加密/脱敏处理,尽量不使用明文,要实现这一点,办法有很多,自己手动对敏感信息进行加解密也是可以的。 2、有需求就有人奉献,Jasypt 开源安全框架就是专门用于处理 Spring boot 属性加密的,在配置文件中直接配置密文,然后应用启动的时候,Jasypt 会自动将密码解密成明文供程序使用。 3、

蚩尤后裔-汪茂雄 3万+

使用c++onnxruntime部署yolov5模型并使用CUDA加速(超详细)

接到一个项目,需要用c++和单片机通信,还要使用yolo模型来做到目标检测的任务,但目前网上的各种博客并没有完整的流程教程,让我在部署过程费了不少劲,也踩了不少坑(甚至一度把ubuntu干黑屏)。于是想把训练及部署过程记录下来,并留给后来者方便使用。(博主使用的系统是ubuntu20.04)

qq_69194611的博客 1万+

华为OD机试真题 新系统【查找能被整除的最大整数】

华为OD新系统机试真题【查找能被整除的最大整数】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【查找能被整除的最大整数】

qq_45776114的博客 673

C++模型部署:qt+yolov5/6+onnxruntime+opencv

很多时候出于性能或者环境的原因,必须要使用 C++ 进行深度学习模型的前向推理。文章主要是给大家介绍一个整体的设计思路,其中包含一些常用第三方库的使用方法,并使用 QT 设计了一个简单的界面。...

1万+

手把手教你学PCIE(5.1)--pcie固件初始化的硬件初始化

PCIe 固件初始化的硬件初始化是一个复杂但至关重要的过程。通过正确配置 PCIe 控制器和相关硬件,可以确保系统的稳定性和性能。以上步骤和示例代码提供了一个基本的框架,实际开发中可能需要根据具体的硬件和需求进行调整和优化。

MHD0815的博客 1689

4. SAP ABAP OData 服务 Data Provider Class 的 GET_ENTITYSET 方法实现指南

首先第19行CREATEDATA创建er_entityset实例,指定其类型为zcl_zbook_manage_mpc=>tt_book,接着把这个引用映射到刚刚第五行定义的FIELD-SYMBOLS变量上去,这样的话,接下来我们对FIELD-SYMBOLS进行的操作,就会自动反应回引用变量er_entityset.因为我们可能在这个方法里,返回多条图书信息,所以需要用内表类型,而非单条记录的ts_book.ts_book代表一本图书的数据结构。......

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 2962

使用c++onnxruntime部署yolov5模型并使用CUDA加速

YOLOv5模型在目标检测领域具有广泛的应用,通过使用C++、ONNX Runtime和CUDA进行部署和加速,可以进一步提高模型的实时性和性能。模型压缩和加速:通过模型压缩技术,如知识蒸馏、量化等,进一步减小模型大小,提高推理速度。硬件优化:利用新型硬件,如TPU、FPGA等,进行模型部署和加速。模型可解释性:提高模型的可解释性,以便更好地理解模型的决策过程。数据隐私和安全:在部署模型时,保护用户数据隐私和安全。

DUT_LYH 2489

出现 Error occurred during initialization of VMagent library failed Agent OnLoad 解决方法

ntelliJ IDEA启动时出现"Agent library failed to load"错误,主要原因是JVM代理加载失败。解决方法包括:1)完全卸载并删除用户目录下的JetBrains配置文件;2)检查并修改idea64.exe.vmoptions文件,确保路径正确并删除不必要的-javaagent参数;

码农研究僧的博客 2484

Yolov5 转 ONNX模型 + 使用ONNX Runtime的 C++ 部署(包含官方文档的介绍以及使用不同推理引擎作为ONNXRuntime后端)

ONNX Runtime (C++) 部署 yolov5s的模型,也可使用自己的模型

qq_22487889的博客 1万+

【异常】Codybuddy Error Code: 14003 too many requests 限流报错问题排查与解决指南

14003报错本质为服务端限流拦截,并非账号封禁或程序致命故障,90%以上的场景可通过等待冷却+规范使用行为解决。通过本文的排查步骤,可快速恢复工具使用,同时规避后续重复触发该问题。

奶爸的编程之路,也就一周冷个三天 1253

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

YOLOv5-Openvino和ONNXRuntime推理【CPU】

Openvino是由Intel开发的专门用于优化和部署人工智能推理的半开源的工具包,主要用于对深度推理做优化。Openvino内部集成了Opencv、TensorFlow模块,除此之外它还具有强大的Plugin开发框架,允许开发者在Openvino之上对推理过程做优化。Openvino整体框架为:Openvino前端→ Plugin中间层→ Backend后端。

weixin_45679938的博客 1925

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

超详细-使用Win11+Visual Studio 2022 Cmake工程部署YOLOv8+CPP+OnnxRuntime-GPU 适用于YOLOv11

超详细-使用Win11+Visual Studio 2022 Cmake工程部署YOLOv8+CPP+OnnxRuntime-GPU 适用于YOLOv11

小叶MW 的博客 1750

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

YOLOV8 Onnxruntime OpenCV C++ VS2019部署推理

在windows设备上基于CPU部署yolov8测试,依赖opencv和onnxruntime。

qq_42493281的博客 2446

VS2015 + OpenCV + OnnxRuntime-Cpp + YOLOv8 部署

本文详细介绍了使用 VS2015+OpenCV+OnnxRuntime+YOLOv8进行模型 C++ 部署的方法

佚失的诗篇 2441

【深度学习】【目标检测】【OnnxRuntime】【C++】YOLOV5模型部署

【深度学习】【目标检测】【OnnxRuntime】【C++】YOLOV5模型部署

yangyu0515的博客 1705

[深度学习]基于C++和onnxruntime部署yolov10的onnx模型

使用C#部署yolov8的目标检测tensorrt模型,C# winform部署yolov10的onnx模型,YOLOv8检测界面-PyQt5实现,2024年新版【YOLOV5从入门到实战教程】B站最良心的YOLOV5全套教程(适合小白)含源码!:解析模型输出的结果,这通常涉及将输出的张量数据转换为可理解的检测结果,如边界框坐标和类别标签。:通过ONNX Runtime的推理引擎,将图像数据输入到模型中,并执行目标检测任务。:使用ONNX Runtime的API加载转换后的YOLOv10 ONNX模型。

FL1623863129的博客 2498
上一篇: 3D点云检测网络训练踩坑记录(看这一篇就够了)
下一篇: Windows照片查看器设置
WD-ss
博客等级 码龄7年 44粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值