基于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

SpyGlass Lint脚本实战:从环境配置到报告生成的完整流程解析

本文详细解析了使用SpyGlass Lint脚本进行数字芯片设计代码质量检查的完整自动化流程。从环境配置、目录结构设计,到核心TCL脚本的编写与模块化配置,再到脚本执行、调试技巧及报告解读,提供了构建健壮、可维护自动化检查框架的实战指南。文章重点阐述了如何通过脚本实现从环境配置到报告生成的一键式操作,并探讨了与企业级CI/CD流程集成的进阶方案。

weixin_29196613的博客 439

基于c++ onnxruntime部署yolov5模型

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

二爷的博客 4410

在线考试系统源码+数据库+word+ppt(高分毕业设计)

本系统通过Spring Cloud实现微服务拆分,将授权、考试、监控等功能解耦,既保证了系统的扩展性,也便于后期维护。基于OAuth2.0的单点登录,解决多服务统一认证问题;考试与练习模式分离,满足不同场景需求;集成Druid与Hystrix,保障系统监控与稳定性。

weixin_44355158的博客 737

python怎样按某一列值拆分Excel表格

pd.ExcelWriter@python #用python按某一列拆分Excel工作表,将内容写入一个工作簿 本次以“按照表中的某一列,将一张表格拆分为多张表”的需求为例,简单介绍这个过程中用到的pd.ExcelWriter,及每一句的作用。 如上表《学生.xlsx》,假设有14万行28列,请按照学校名,拆分表格(不想用复制粘贴)。 ##代码及解释如下 import pandas as pd from time import time#用来计算时间,展示进度,减少焦虑 in_ws='学生.xlsx'#

learn_get的博客 6787

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

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

qq_69194611的博客 1万+

【Python&RS】Rasterio库安装+基础函数使用教程

Rasterio是一个Python库,专门用于栅格数据的读写操作。它支持多种栅格数据格式,如GeoTIFF、ENVI和HDF5,为处理和分析栅格数据提供了强大的工具。RasterIO适用于各种栅格数据应用,如卫星遥感、地图制作等。这篇文章跟大家介绍一下Rasterio库的安装以及一些基本函数的使用教程,附带源码。

Remote Sensing迷途小书童 1万+

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

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

1万+

InsightFace(RetinaFace + ArcFace)人脸识别实战:从模型部署到Web服务构建

本文详细介绍了如何利用InsightFace框架,结合其集成的RetinaFace人脸检测与ArcFace人脸识别预训练模型,从零开始构建一个高性能的Web人脸识别服务。内容涵盖环境搭建、模型部署、核心代码解析(包括五点仿射对齐关键步骤)、FAISS向量检索集成以及基于FastAPI的Web服务开发,并提供了实战优化与常见问题排查指南,帮助开发者快速实现工业级应用。

weixin_29054245的博客 226

实现Win10环境下的MATLAB与虚拟机Ubuntu中的ROS的通讯的方法

   本文主要介绍如何实现Win10环境下的MATLAB与虚拟机Ubuntu中的ROS的通讯,虚拟机我采用的是VMware16.1.1中安装了Ubuntu20.04,并安装ROS Noetic 版本    一、虚拟机Ubuntu中配置    1、在ubuntu终端输入以下命令查看本机地址 ifconfig    如下图所示我目前的IP是192.168.3.128    2、将本机IP写入到.bashrc文件    打开home文件夹,按Ctrl+h显示隐藏的文件,选择.bashrc并打开(

慕羽★的博客 7517

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

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

DUT_LYH 2489

推理引擎终极对决:TensorRT vs ONNX Runtime,YOLOv8速度差30%的核心原因与实操指南

若你使用NVIDIA GPU,且追求极致速度和低延迟,TensorRT是唯一选择,尤其是边缘设备和实时场景;若你需要跨硬件部署、快速验证原型,或预算有限(无需NVIDIA GPU),ONNX Runtime是性价比之王;对于YOLOv8这类检测模型,TensorRT的FP16/INT8量化是“免费的速度提升”,建议优先采用。最后提醒:推理引擎的优化是“细节决定成败”——同样的引擎,不同的预处理方式、显存配置、批大小,都会导致10%-20%的性能差异。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1026

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

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

qq_22487889的博客 1万+

TC397 EB MCAL开发从0开始系列 之 [13.1] Dma配置实战 -实现M2M数据传输(读存储写存储)

TC3XX TC397 MCAL DMA 从0搭建测试用例-实现M2M 存储到存储数据传输

yy九歌的博客 1914

老版QQ原生表情gif动态

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

YOLOv5-Openvino和ONNXRuntime推理【CPU】

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

weixin_45679938的博客 1925

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

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

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

小叶MW 的博客 1750

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

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、付费专栏及课程。

余额充值