C++ onnxruntime 推理例子

C++ onnxruntime 推理例子

flyfish

假如一个模型的输入和输出如图所示

在这里插入图片描述

输入节点名字是 input,形状是[batch_size,3,128,64]
输出节点名字是output,形状是 [batch_size,512]

源码如下

#include <assert.h>
#include <vector>
#include <onnxruntime_cxx_api.h>
#include <opencv2/opencv.hpp>
#include "cpu_provider_factory.h"
#include <iostream>


int main(int argc, char* argv[]) {
    Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "Default");

    const char* model_path = "./model.onnx";



    Ort::Session session_{env, model_path, Ort::SessionOptions{nullptr}}; //CPU


    static constexpr const int height_ = 128; //model input height
    static constexpr const int width_ = 64; //model input width

    Ort::Value input_tensor_{nullptr};
    std::array<int64_t, 4> input_shape_{1, 3, height_, width_}; //mode input shape NCHW = 1x3xHxW

    Ort::Value output_tensor_{nullptr};
    std::array<int64_t, 2> output_shape_{1, 512}; //model output shape,

    std::array<float, width_ * height_ * 3> input_image_{};
    std::array<float, 512> results_{};

    //rows = height 128
    //cols = weight 64

    std::string imgPath = "./1.jpg";
    cv::Mat img = cv::imread(imgPath);
    cv::resize(img, img, cv::Size(64, 128));//size
    cv::cvtColor(img, img, cv::COLOR_BGR2RGB);//bgr -> rgb
    std::cout<<"dim:"<< img.rows<<":"<<img.cols<<":"<<img.channels()<<std::endl;
    //根据自己的处理更改
    int index=0;
    for (unsigned c = 0; c < 3; c++)
    {
        for (unsigned i = 0; i < img.rows; i++)
        {
            for (unsigned j = 0; j < img.cols; j++)
            {
                input_image_[index++] = (static_cast<float>(img.at<cv::Vec3b>(i, j)[c]));
            }
        }
    }


    auto memory_info = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeDefault);
    input_tensor_ = Ort::Value::CreateTensor<float>(memory_info, input_image_.data(), input_image_.size(), input_shape_.data(), input_shape_.size());
    output_tensor_ = Ort::Value::CreateTensor<float>(memory_info, results_.data(), results_.size(), output_shape_.data(), output_shape_.size());
    const char* input_names[] = {"input"};
    const char* output_names[] = {"output"};


    session_.Run(Ort::RunOptions{nullptr}, input_names, &input_tensor_, 1, output_names, &output_tensor_, 1);


    float* out = output_tensor_.GetTensorMutableData<float>();
    for(int i = 0; i < 512; i++)
    {
        std::cout<< out[i]<<":";
    }

    return 0;
}

CMakeLists.txt内容如下

cmake_minimum_required(VERSION 3.5)

project(onnx_example LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)



set(ONNXRUNTIME_DIR "/libpath/onnxruntime-linux-x64-1.12.1")
include_directories("${ONNXRUNTIME_DIR}/include"
    )
find_package(OpenCV REQUIRED )


include_directories(
    ${OpenCV_INCLUDE_DIRS}/include
    )


add_executable(onnx_example
main.cpp)
target_link_libraries(onnx_example PRIVATE "${ONNXRUNTIME_DIR}/lib/libonnxruntime.so" ${OpenCV_LIBS} )
### C++ ONNX Runtime 使用教程 #### 1. 准备工作 为了使用 C++ONNX Runtime 进行推理,首先需要安装必要的依赖项以及配置开发环境。这通常涉及设置 CMake 构建工具链,并确保已下载并编译了 ONNX Runtime 库。 对于项目构建脚本 `CMakeLists.txt` 的编写,可以参照以下模板[^4]: ```cmake cmake_minimum_required(VERSION 3.5) project(onnx_example LANGUAGES CXX) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 设置 ONNXRuntime 路径 set(ONNXRUNTIME_DIR "/libpath/onnxruntime-linux-x64-1.12.1") # 添加头文件路径 include_directories("${ONNXRUNTIME_DIR}/include") find_package(OpenCV REQUIRED ) include_directories(${OpenCV_INCLUDE_DIRS}) add_executable(onnx_example main.cpp) target_link_libraries(onnx_example PRIVATE "${ONNXRUNTIME_DIR}/lib/libonnxruntime.so" ${OpenCV_LIBS}) ``` 此段代码定义了一个简单的 CMake 工程结构,指定了所需的最低版本号、编程标准以及其他必要参数来创建可执行文件 `onnx_example` 并链接到 OpenCV 及 ONNX Runtime 库。 #### 2. 加载模型与初始化会话 加载 `.onnx` 模型并通过 ONNX Runtime 创建会话对象是启动推理流程的第一步。下面是一个基本的例子展示如何实现这一点[^3]: ```cpp #include "onnxruntime_cxx_api.h" #include <iostream> using namespace Ort; void LoadModel(const char* model_path){ Env env(ORT_LOGGING_LEVEL_WARNING, "test"); SessionOptions session_options; // 初始化Session实例 unique_ptr<Session> session{new Session(env, model_path, session_options)}; } ``` 这段代码展示了怎样通过给定的模型路径初始化一个新的会话实例。这里还设置了日志级别为警告以上的信息才会打印出来,从而减少不必要的输出干扰调试过程。 #### 3. 执行推理操作 一旦成功建立了会话连接,则可以通过提供输入张量来进行实际的数据预测处理。以下是具体做法的一个简单示范: ```cpp // 定义输入数据形状和类型 vector<int64_t> input_shape = {1, 3, 224, 224}; // 假设这是一个图像分类任务 TensorType tensor_type = TensorType::Float; // 创建内存信息描述符 MemoryInfo memory_info{"Cpu", OrtcProviderType::OrtArenaAllocator}; // 分配空间存储输入数据 Value input_tensor = Value::CreateTensor<float>(memory_info, /*data=*/nullptr, /*num_bytes=*/0, input_shape); // 将准备好的输入传递给session.run()函数以获取输出结果 auto output_tensors = session->Run(RunOptions{}, {"input"}, {&input_tensor}, {"output"}); ``` 上述片段说明了如何构造适当格式化的输入张量,并将其传入至先前建立起来的会话当中去完成一次完整的前向传播计算周期。 #### 4. 结果解析 最后一步是从返回的结果集中提取有用信息。由于不同类型的神经网络会产生各异形式的结果集,因此这部分逻辑需依据具体情况而定制化设计。一般情况下,可能涉及到对概率分布取最大值索引的操作或是其他更复杂的后处理步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二分掌柜的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值