ONNXRUNTUIME c++使用(分割网络)与相关资料(暂记)

        下面的教程是在linux系统上运行的,如果想在windows系统上运行,可以看官方链接中文教程https://bbs.huaweicloud.com/blogs/335706,官方链接中有完整的VS的带.sln的项目。

ONNXRUNTUIME

  • OPENCV不支持某些算子(挤压层在opencv 中不支持)

安装 github.com/microsoft/onnxruntime

配置

cmake_minimum_required(VERSION 3.15)
project(aaa)
set(CMAKE_CXX_STANDARD 14)

option(ONNXRUNTIME_ROOTDIR "/home/dell/CLionProjects/onnxruntime-linux-x64-1.12.1")
find_package(OpenCV REQUIRED)
set(SOURCE_FILES main.cpp)
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories("/home/dell/下载/onnxruntime-1.12.1/include/onnxruntime/core/session/")
include_directories("/home/dell/下载/onnxruntime-1.12.1/include/")

add_executable(aaa main.cpp)
target_link_libraries(aaa ${OpenCV_LIBS})
target_link_libraries(aaa "/home/dell/CLionProjects/onnxruntime-linux-x64-1.12.1/lib/libonnxruntime.so")

安装ONNXRUNTIME

新版本(1.13)弃用函数GetInputName 到 GetInputNameAllocator,所以可以使用1.12版本

session->GetInputName(i, allocator));

自己build

运行一个实力

在这里插入图片描述在这里插入图片描述

//PP-HumanSeg-opencv-onnxrun-main
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <string>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <onnxruntime_cxx_api.h>
//#include <cuda_provider_factory.h>  ///如果使用cuda加速,需要取消注释
#include <tensorrt_provider_factory.h>  ///如果使用cuda加速,需要取消注释


using namespace cv;
using namespace std;
using namespace Ort;

class pphuman_seg
{
public:
    pphuman_seg();
    Mat inference(Mat cv_image);
private:

    void preprocess(Mat srcimg);
    int inpWidth;
    int inpHeight;
    vector<float> input_image_;
    const float conf_threshold = 0.5;

    Env env = Env(ORT_LOGGING_LEVEL_ERROR, "pphuman-seg");
    Ort::Session *ort_session = nullptr;
    SessionOptions sessionOptions = SessionOptions();
    vector<char*> input_names;
    vector<char*> output_names;
    vector<vector<int64_t>> input_node_dims; // >=1 outputs
    vector<vector<int64_t>> output_node_dims; // >=1 outputs
};

pphuman_seg::pphuman_seg()
{
    string model_path = "../model_float32.onnx";
    //std::wstring widestr = std::wstring(model_path.begin(), model_path.end());  windows写法
    ///OrtStatus* status = OrtSessionOptionsAppendExecutionProvider_CUDA(sessionOptions, 0);   ///如果使用cuda加速,需要取消注释

    sessionOptions.SetGraphOptimizationLevel(ORT_ENABLE_BASIC);
    //ort_session = new Session(env, widestr.c_str(), sessionOptions); windows写法
    ort_session = new Session(env, model_path.c_str(), sessionOptions); //linux写法

    size_t numInputNodes = ort_session->GetInputCount();
    size_t numOutputNodes = ort_session->GetOutputCount();
    AllocatorWithDefaultOptions allocator;
    for (int i = 0; i < numInputNodes; i++)
    {
        input_names.push_back(ort_session->GetInputName(i, allocator));
        Ort::TypeInfo input_type_info = ort_session->GetInputTypeInfo(i);
        auto input_tensor_info = input_type_info.GetTensorTypeAndShapeInfo();
        auto input_dims = input_tensor_info.GetShape();
        input_node_dims.push_back(input_dims);
    }
    for (int i = 0; i < numOutputNodes; i++)
    {
        output_names.push_back(ort_session->GetOutputName(i, allocator));
        Ort::TypeInfo output_type_info = ort_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);
    }
    this->inpHeight = input_node_dims[0][2];
    this->inpWidth = input_node_dims[0][3];
}

void pphuman_seg::preprocess(Mat srcimg)
{
    Mat dstimg;
    resize(srcimg, dstimg, Size(this->inpWidth, this->inpHeight), INTER_LINEAR);

    int row = dstimg.rows;
    int col = dstimg.cols;
    this->input_image_.resize(row * col * dstimg.channels());
    for (int c = 0; c < 3; c++)
    {
        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                float pix = dstimg.ptr<uchar>(i)[j * 3 + c];
                this->input_image_[c * row * col + i * col + j] = (pix / 255.0 - 0.5) / 0.5;
            }
        }
    }
}

Mat pphuman_seg::inference(Mat srcimg)
{
    this->preprocess(srcimg);
    array<int64_t, 4> input_shape_{1, 3, this->inpHeight, this->inpWidth};

    auto allocator_info = MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
    Value input_tensor_ = Value::CreateTensor<float>(allocator_info, input_image_.data(), input_image_.size(), input_shape_.data(), input_shape_.size());
    vector<Value> ort_outputs = ort_session->Run(RunOptions{ nullptr }, input_names.data(), &input_tensor_, 1, output_names.data(), output_names.size());   // 开始推理
    // post process.
    Value &mask_pred = ort_outputs.at(0);
    const int out_h = this->output_node_dims[0][1];
    const int out_w = this->output_node_dims[0][2];
    float *mask_ptr = mask_pred.GetTensorMutableData<float>();

    Mat segmentation_map;
    Mat mask_out(out_h, out_w, CV_32FC2, mask_ptr);
    resize(mask_out, segmentation_map, Size(srcimg.cols, srcimg.rows));
    Mat dstimg = srcimg.clone();

    for (int h = 0; h < srcimg.rows; h++)
    {
        for (int w = 0; w < srcimg.cols; w++)
        {
            float pix = segmentation_map.ptr<float>(h)[w * 2];
            if (pix > this->conf_threshold)
            {
                float b = (float)srcimg.at<Vec3b>(h, w)[0];
                dstimg.at<Vec3b>(h, w)[0] = uchar(b * 0.5 + 1);
                float g = (float)srcimg.at<Vec3b>(h, w)[1];
                dstimg.at<Vec3b>(h, w)[1] = uchar(g * 0.5 + 1);
                float r = (float)srcimg.at<Vec3b>(h, w)[2];
                dstimg.at<Vec3b>(h, w)[2] = uchar(r * 0.5 + 1);
            }
        }
    }

    for (int h = 0; h < srcimg.rows; h++)
    {
        for (int w = 0; w < srcimg.cols; w++)
        {
            float pix = segmentation_map.ptr<float>(h)[w * 2 + 1];
            if (pix > this->conf_threshold)
            {
                float b = (float)dstimg.at<Vec3b>(h, w)[0];
                dstimg.at<Vec3b>(h, w)[0] = uchar(b * 0.5 + 1);
                float g = (float)dstimg.at<Vec3b>(h, w)[1] + 255.0;
                dstimg.at<Vec3b>(h, w)[1] = uchar(g * 0.5 + 1);
                float r = (float)dstimg.at<Vec3b>(h, w)[2];
                dstimg.at<Vec3b>(h, w)[2] = uchar(r * 0.5 + 1);
            }
        }
    }
    return dstimg;
}

int main()
{
    //return 0;
    const int use_video = 1;
    pphuman_seg mynet;
    if (use_video)
    {
        cv::VideoCapture video_capture("/home/dell/CLionProjects/a.mp4");  ///也可以是视频文件
        if (!video_capture.isOpened())
        {
            std::cout << "Can not open video " << endl;
            return -1;
        }

        cv::Mat frame;
        while (video_capture.read(frame))
        {
            Mat dstimg = mynet.inference(frame);
            string kWinName = "Deep learning ONNXRuntime with pphuman seg";
            namedWindow(kWinName, WINDOW_NORMAL);
            imshow(kWinName, dstimg);
            waitKey(1);
        }
        destroyAllWindows();
    }
    else
    {
        string imgpath = "testimgs/1.jpg";
        Mat srcimg = imread(imgpath);
        Mat dstimg = mynet.inference(srcimg);

        namedWindow("srcimg", WINDOW_NORMAL);
        imshow("srcimg", srcimg);
        static const string kWinName = "Deep learning ONNXRuntime with pphuman seg";
        namedWindow(kWinName, WINDOW_NORMAL);
        imshow(kWinName, dstimg);
        waitKey(0);
        destroyAllWindows();
    }
}


CG

似乎 opencv 不支持具有动态输入形状的 onnx 模型,请查看此链接。尝试构建最新版本的 opencv。另外,请检查此链接 .已经提到对Yunet使用固定的输入形状。如果以前的建议不起作用,请使用以下方法。
如果您使用的是 tf2 并且您的权重是 .h5 形式,您将能够处理 onnx 麻烦 .您可以从 .h5 生成 .pb,然后在 C++ 中轻松使用 program.to 目标生成 .pb,使用以下代码:
之后,通过使用OpenCV,您将能够导入您的模型,然后享受!

在这里插入图片描述

opencv_sample-master

https://github.com/dlunion/tensorRTIntegrate

  • https://github.com/ttanzhiqiang/onnx_tensorrt_project
cmake_minimum_required(VERSION 3.15)
project(onnx)
set(CMAKE_CXX_STANDARD 14)

MESSAGE(STATUS "Project: onnx")              
find_package(OpenCV REQUIRED)
set(SOURCE_FILES main.cpp)
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories("/home/dell/CLionProjects/onnxruntime-linux-x64-1.12.1/include")# https://blog.csdn.net/sinat_31608641/article/details/121736503

add_executable(onnx main.cpp)
target_link_libraries(onnx ${OpenCV_LIBS})
link_directories("/home/dell/CLionProjects/onnxruntime-linux-x64-1.12.1/lib")
- https://www.w3cschool.cn/doc_cmake_3_6/cmake_3_6-command-target_link_libraries.html
- https://www.cnblogs.com/stonemjl/articles/12668208.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值