使用Onnxruntime C++/Python API也有两年时间了,对常用的API做一个简单的介绍。
OnnxRuntime的运行流程如下:
- 创建运行环境,可以设置日志级别,Log ID等
1
Ort::Env env(OrtLoggingLevel::ORT_LOGGING_LEVEL_WARNING,"APP NAME");
- 创建Session, model_path为ONNX模型存储的地址。另外可以通过SessionOptions设置优化级别、推理运行的Provider,如CPU, CUDA, TensorRT等。
1
2
3
4Ort::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); - 获取模型输入输出信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19size_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);
} - 图像预处理,如调整大小转换通道,MAT->Tensor等
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19Mat 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];
}
} - 分配内存
1
2
3array<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()); - 执行推理
1
vector<Value> ort_outputs = ort_session->Run(RunOptions{ nullptr }, &input_names[0], &input_tensor, 1, output_names.data(), output_names.size());
- 获取输出
1
float* preds = ort_outputs[0].GetTensorMutableData<float>();