于c++中使用onnxruntime调用ppyoloe的onnx模型

于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);
    //bgr2rgb
    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) {
    //根据yml文件进行预处理输入参数
    Mat det1, det2;
    //double scale_x, scale_y;
    get_scale({ img.rows, img.cols }, { 640, 640 }, scale_x, scale_y);
    resize(img, det1, Size(), scale_x, scale_y, 2);
    //img = det1;
    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);
    //sess_opts.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED);
    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) };
    // //输入节点信息,为输入数据创建一个Tensor对象

    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;
    //cout << "ok\n";
    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);
        // Get pointer to output tensor float values
        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");
}

你可能感兴趣的:(图像处理,c++)