于c++中使用onnxruntime调用ppyoloe的onnx模型
struct Output {
int id;
float confidence;
cv::Rect box;
};
float scale_x, scale_y;
void standard_Process(const Mat& image, Mat& image_blob)
{
Mat input;
image.copyTo(input);
std::vector<Mat> channels, channel_p;
split(input, channels);
Mat R, G, B;
B = channels.at(0);
G = channels.at(1);
R = channels.at(2);
B = B;
G = G;
R = R;
channel_p.push_back(R);
channel_p.push_back(G);
channel_p.push_back(B);
Mat outt;
merge(channel_p, outt);
image_blob = outt;
}
void get_scale(pair<int, int>origin, pair<int, int> target, float& scale_x, float& scale_y, bool keep_radio = false) {
if (keep_radio) {
int o_mnsize = origin.first, o_mxsize = origin.second;
if (o_mnsize > o_mxsize)swap(o_mnsize, o_mxsize);
int t_mnsize = target.first, t_mxsize = target.second;
if (t_mnsize > t_mxsize)swap(t_mnsize, t_mxsize);
double scale = 1.0 * t_mnsize / o_mnsize;
if ((int)(t_mxsize * scale + 0.5) > o_mxsize)scale = 1.0 * t_mxsize / o_mxsize;
scale_x = scale;
scale_y = scale;
}
else {
scale_x = 1.0 * target.first / origin.second;
scale_y = 1.0 * target.second / origin.first;
}
}
void PreProcess(Mat& img, Mat& det) {
Mat det1, det2;
get_scale({ img.rows, img.cols }, { 640, 640 }, scale_x, scale_y);
resize(img, det1, Size(), scale_x, scale_y, 2);
det1.convertTo(det1, CV_32FC3, 1.0 / 255.0);
standard_Process(det1, det2);
det = dnn::blobFromImage(det2, 1.0);
}
void detect(const string img_path) {
vector<Output> result;
const wchar_t* model_path = L"models/ppyoloe.onnx";
Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "Default");
Ort::AllocatorWithDefaultOptions allocator;
Ort::SessionOptions sess_opts;
sess_opts.SetIntraOpNumThreads(1);
Ort::Session session(Ort::Session(env, model_path, sess_opts));
size_t num_input = session.GetInputCount();
size_t num_output = session.GetOutputCount();
vector<const char*> input_node_names = { session.GetInputName(0, allocator), session.GetInputName(1, allocator) };
vector<const char*> output_node_names = { session.GetOutputName(0, allocator),session.GetOutputName(1, allocator) };
auto image_dims = session.GetInputTypeInfo(0).GetTensorTypeAndShapeInfo().GetShape();
image_dims[0] = 1;
auto scale_factor_dims = session.GetInputTypeInfo(1).GetTensorTypeAndShapeInfo().GetShape();
scale_factor_dims[0] = 1;
vector<Ort::Value> input_tensor;
Mat img = imread(img_path), blob;
auto image_memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
PreProcess(img, blob);
Ort::Value image_val = Ort::Value::CreateTensor<float>(image_memory_info, blob.ptr<float>(), blob.total(), image_dims.data(), image_dims.size());
assert(image_val.IsTensor());
input_tensor.push_back(move(image_val));
auto scale_factor_memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
float scale_factor[] = { scale_y ,scale_x };
Ort::Value scale_factor_val = Ort::Value::CreateTensor<float>(scale_factor_memory_info, scale_factor, 2U, scale_factor_dims.data(), scale_factor_dims.size());
assert(scale_factor_val.IsTensor());
input_tensor.push_back(move(scale_factor_val));
try {
auto output_tensors = session.Run(Ort::RunOptions{ nullptr }, input_node_names.data(), input_tensor.data(), input_tensor.size(), output_node_names.data(), 2);
float* floatarr = output_tensors[0].GetTensorMutableData<float>();
auto out_put0 = output_tensors[0].GetTensorTypeAndShapeInfo().GetShape();
vector<vector<float>> bboxs;
float threshold = 0.5;
for (int i = 0; i < out_put0[0]; i++) {
vector<float> bbox;
for (int j = 0; j < 6; j++) {
bbox.push_back(floatarr[i * 6 + j]);
}
bboxs.push_back(bbox);
}
for (auto bbox : bboxs) {
if (bbox[0] > -1 && bbox[1] > threshold) {
cout << "type:" << (int)bbox[0] << ":" << box_class[(int)bbox[0]] << "\t";
cout << "threshold:" << bbox[1] << "\t";
cout << "x1:" << bbox[2] << "\t";
cout << "y1:" << bbox[3] << "\t";
cout << "x2:" << bbox[4] << "\t";
cout << "y2:" << bbox[5] << "\n";
}
}
}
catch (Ort::Exception& e) {
printf(e.what());
}
}
int main(){
detect("4.JPG");
}