0%

Onnxruntime C++ API 简介

使用Onnxruntime C++/Python API也有两年时间了,对常用的API做一个简单的介绍。
OnnxRuntime的运行流程如下:

  1. 创建运行环境,可以设置日志级别,Log ID等
    1
    Ort::Env env(OrtLoggingLevel::ORT_LOGGING_LEVEL_WARNING,"APP NAME");
  2. 创建Session, model_path为ONNX模型存储的地址。另外可以通过SessionOptions设置优化级别、推理运行的Provider,如CPU, CUDA, TensorRT等。
    1
    2
    3
    4
    Ort::SessionOptions session_options;
    // session_options.SetGraphOptimizationLevel(Ort::ORT_ENABLE_BASIC);
    // session_options.AppendExecutionProvider_CUDA(providerOptions);
    Ort::Session ort_session = Ort::Session(env_, model_path_.c_str(), session_options);
  3. 获取模型输入输出信息
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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);
    }
  4. 图像预处理,如调整大小转换通道,MAT->Tensor等
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    Mat img;
    Mat srcimg = imread(imgpath);
    resize(srcimg, img, Size(tgtWidth, tgtHeight));
    vector<float> tensor(tgtWidth * tgtHeight * img.channels());
    for(int i = 0; i < img.rows * img.cols * 3; i++)
    {
    if(i % 3 == 0)
    {
    tensor[i + 2] = img.data[i];
    }
    else if(i % 3 == 1)
    {
    tensor[i] = img.data[i];
    }
    else if(i % 3 ==2)
    {
    tensor[i - 2] = img.data[i];
    }
    }
  5. 分配内存
    1
    2
    3
    array<int64_t, 4> input_shape{ 1, 3, tgtWidth, tgtHeight};
    auto allocator_info = MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
    Value input_tensor = Value::CreateTensor<float>(allocator_info, tensor.data(), tensor.size(), input_shape.data(), input_shape.size());
  6. 执行推理
    1
    vector<Value> ort_outputs = ort_session->Run(RunOptions{ nullptr }, &input_names[0], &input_tensor, 1, output_names.data(), output_names.size());
  7. 获取输出
    1
    float* preds = ort_outputs[0].GetTensorMutableData<float>();