| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- #include <gflags/gflags.h>
- #include <string>
- #include <vector>
- #include "model_deploy/common/include/paddle_deploy.h"
- PaddleDeploy::Model* model;
- /*
- * 模型初始化/注册接口
- *
- * model_type: 初始化模型类型: det,seg,clas,paddlex
- *
- * model_filename: 模型文件路径
- *
- * params_filename: 参数文件路径
- *
- * cfg_file: 配置文件路径
- *
- * use_gpu: 是否使用GPU
- *
- * gpu_id: 指定第x号GPU
- *
- * paddlex_model_type: model_type为paddlx时,返回的实际paddlex模型的类型: det, seg, clas
- */
- extern "C" __declspec(dllexport) void InitModel(const char* model_type, const char* model_filename, const char* params_filename, const char* cfg_file, bool use_gpu, int gpu_id, char* paddlex_model_type)
- {
- // create model
- model = PaddleDeploy::CreateModel(model_type); //FLAGS_model_type
- // model init
- model->Init(cfg_file);
- // inference engine init
- PaddleDeploy::PaddleEngineConfig engine_config;
- engine_config.model_filename = model_filename;
- engine_config.params_filename = params_filename;
- engine_config.use_gpu = use_gpu;
- engine_config.gpu_id = gpu_id;
- bool init = model->PaddleEngineInit(engine_config);
- if (init)
- {
- std::cout << "init model success" << std::endl;
- }
- // det, seg, clas, paddlex
- if (strcmp(model_type, "paddlex") == 0) // 是paddlex模型,则返回具体支持的模型类型: det, seg, clas
- {
- // detector
- if (model->yaml_config_["model_type"].as<std::string>() == std::string("detector"))
- {
- strcpy(paddlex_model_type, "det");
- }
- else if (model->yaml_config_["model_type"].as<std::string>() == std::string("segmenter"))
- {
- strcpy(paddlex_model_type, "seg");
- }
- else if (model->yaml_config_["model_type"].as<std::string>() == std::string("classifier"))
- {
- strcpy(paddlex_model_type, "clas");
- }
- }
- }
- /*
- * 检测推理接口
- *
- * img: input for predicting.
- *
- * nWidth: width of img.
- *
- * nHeight: height of img.
- *
- * nChannel: channel of img.
- *
- * output: result of pridict ,include category_id£¬score£¬coordinate¡£
- *
- * nBoxesNum£º number of box
- *
- * LabelList: label list of result
- */
- extern "C" __declspec(dllexport) void Det_ModelPredict(const unsigned char* img, int nWidth, int nHeight, int nChannel, float* output, int* nBoxesNum, char* LabelList)
- {
- // prepare data
- std::vector<cv::Mat> imgs;
- int nType = 0;
- if (nChannel == 3)
- {
- nType = CV_8UC3;
- }
- else
- {
- std::cout << "Only support 3 channel image." << std::endl;
- return;
- }
- cv::Mat input = cv::Mat::zeros(cv::Size(nWidth, nHeight), nType);
- memcpy(input.data, img, nHeight * nWidth * nChannel * sizeof(uchar));
- //cv::imwrite("./1.png", input);
- imgs.push_back(std::move(input));
- // predict
- std::vector<PaddleDeploy::Result> results;
- model->Predict(imgs, &results, 1);
- // nBoxesNum[0] = results.size(); // results.size()得到的是batch_size
- nBoxesNum[0] = results[0].det_result->boxes.size(); // 得到单张图片预测的bounding box数
- std::string label = "";
- //std::cout << "res: " << results[num] << std::endl;
- for (int i = 0; i < results[0].det_result->boxes.size(); i++) // 得到所有框的数据
- {
- //std::cout << "category: " << results[num].det_result->boxes[i].category << std::endl;
- label = label + results[0].det_result->boxes[i].category + " ";
- // labelindex
- output[i * 6 + 0] = results[0].det_result->boxes[i].category_id; // 类别的id
- // score
- output[i * 6 + 1] = results[0].det_result->boxes[i].score; // 得分
- //// box
- output[i * 6 + 2] = results[0].det_result->boxes[i].coordinate[0]; // x1, y1, x2, y2
- output[i * 6 + 3] = results[0].det_result->boxes[i].coordinate[1]; // 左上、右下的顶点
- output[i * 6 + 4] = results[0].det_result->boxes[i].coordinate[2];
- output[i * 6 + 5] = results[0].det_result->boxes[i].coordinate[3];
- }
- memcpy(LabelList, label.c_str(), strlen(label.c_str()));
- }
- /*
- * 分割推理接口
- *
- * img: input for predicting.
- *
- * nWidth: width of img.
- *
- * nHeight: height of img.
- *
- * nChannel: channel of img.
- *
- * output: result of pridict ,include label_map
- */
- extern "C" __declspec(dllexport) void Seg_ModelPredict(const unsigned char* img, int nWidth, int nHeight, int nChannel, unsigned char* output)
- {
- // prepare data
- std::vector<cv::Mat> imgs;
- int nType = 0;
- if (nChannel == 3)
- {
- nType = CV_8UC3;
- }
- else
- {
- std::cout << "Only support 3 channel image." << std::endl;
- return;
- }
- cv::Mat input = cv::Mat::zeros(cv::Size(nWidth, nHeight), nType);
- memcpy(input.data, img, nHeight * nWidth * nChannel * sizeof(uchar));
- //cv::imwrite("./1.png", input);
- imgs.push_back(std::move(input));
- // predict
- std::vector<PaddleDeploy::Result> results;
- model->Predict(imgs, &results, 1);
- std::vector<uint8_t> result_map = results[0].seg_result->label_map.data; // vector<uint8_t> -- 结果map
- // 拷贝输出结果到输出上返回 -- 将vector<uint8_t>转成unsigned char *
- memcpy(output, &result_map[0], result_map.size() * sizeof(uchar));
- }
- /*
- * 识别推理接口
- *
- * img: input for predicting.
- *
- * nWidth: width of img.
- *
- * nHeight: height of img.
- *
- * nChannel: channel of img.
- *
- * score: result of pridict ,include score
- *
- * category: result of pridict ,include category_string
- *
- * category_id: result of pridict ,include category_id
- */
- extern "C" __declspec(dllexport) void Cls_ModelPredict(const unsigned char* img, int nWidth, int nHeight, int nChannel, float* score, char* category, int* category_id)
- {
- // prepare data
- std::vector<cv::Mat> imgs;
- int nType = 0;
- if (nChannel == 3)
- {
- nType = CV_8UC3;
- }
- else
- {
- std::cout << "Only support 3 channel image." << std::endl;
- return;
- }
- cv::Mat input = cv::Mat::zeros(cv::Size(nWidth, nHeight), nType);
- memcpy(input.data, img, nHeight * nWidth * nChannel * sizeof(uchar));
- //cv::imwrite("./1.png", input);
- imgs.push_back(std::move(input));
- // predict
- std::vector<PaddleDeploy::Result> results;
- model->Predict(imgs, &results, 1);
- *category_id = results[0].clas_result->category_id;
- // 拷贝输出类别结果到输出上返回 -- string --> char*
- memcpy(category, results[0].clas_result->category.c_str(), strlen(results[0].clas_result->category.c_str()));
- // 拷贝输出概率值返回
- *score = results[0].clas_result->score;
- }
- /*
- * MaskRCNN推理接口
- *
- * img: input for predicting.
- *
- * nWidth: width of img.
- *
- * nHeight: height of img.
- *
- * nChannel: channel of img.
- *
- * box_output: result of pridict ,include label+score+bbox
- *
- * mask_output: result of pridict ,include label_map
- *
- * nBoxesNum: result of pridict ,include BoxesNum
- *
- * LabelList: result of pridict ,include LabelList
- */
- extern "C" __declspec(dllexport) void Mask_ModelPredict(const unsigned char* img, int nWidth, int nHeight, int nChannel, float* box_output, unsigned char* mask_output, int* nBoxesNum, char* LabelList)
- {
- // prepare data
- std::vector<cv::Mat> imgs;
- int nType = 0;
- if (nChannel == 3)
- {
- nType = CV_8UC3;
- }
- else
- {
- std::cout << "Only support 3 channel image." << std::endl;
- return;
- }
- cv::Mat input = cv::Mat::zeros(cv::Size(nWidth, nHeight), nType);
- memcpy(input.data, img, nHeight * nWidth * nChannel * sizeof(uchar));
- imgs.push_back(std::move(input));
- // predict -- 多次点击单张推理时会出错
- std::vector<PaddleDeploy::Result> results;
- model->Predict(imgs, &results, 1); // 在Infer处发生错误
- nBoxesNum[0] = results[0].det_result->boxes.size(); // 得到单张图片预测的bounding box数
- std::string label = "";
- for (int i = 0; i < results[0].det_result->boxes.size(); i++) // 得到所有框的数据
- {
- // 边界框预测结果
- label = label + results[0].det_result->boxes[i].category + " ";
- // labelindex
- box_output[i * 6 + 0] = results[0].det_result->boxes[i].category_id; // 类别的id
- // score
- box_output[i * 6 + 1] = results[0].det_result->boxes[i].score; // 得分
- //// box
- box_output[i * 6 + 2] = results[0].det_result->boxes[i].coordinate[0]; // x1, y1, x2, y2
- box_output[i * 6 + 3] = results[0].det_result->boxes[i].coordinate[1]; // 左上、右下的顶点
- box_output[i * 6 + 4] = results[0].det_result->boxes[i].coordinate[2];
- box_output[i * 6 + 5] = results[0].det_result->boxes[i].coordinate[3];
-
- //Mask预测结果
- for (int j = 0; j < results[0].det_result->boxes[i].mask.data.size(); j++)
- {
- if (mask_output[j] == 0)
- {
- mask_output[j] = results[0].det_result->boxes[i].mask.data[j];
- }
- }
- }
- memcpy(LabelList, label.c_str(), strlen(label.c_str()));
- }
- /*
- * 模型销毁/注销接口
- */
- extern "C" __declspec(dllexport) void DestructModel()
- {
- delete model;
- std::cout << "destruct model success" << std::endl;
- }
|