model_infer.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. #include <gflags/gflags.h>
  2. #include <string>
  3. #include <vector>
  4. #include "model_deploy/common/include/paddle_deploy.h"
  5. PaddleDeploy::Model* model;
  6. /*
  7. * 模型初始化/注册接口
  8. *
  9. * model_type: 初始化模型类型: det,seg,clas,paddlex
  10. *
  11. * model_filename: 模型文件路径
  12. *
  13. * params_filename: 参数文件路径
  14. *
  15. * cfg_file: 配置文件路径
  16. *
  17. * use_gpu: 是否使用GPU
  18. *
  19. * gpu_id: 指定第x号GPU
  20. *
  21. * paddlex_model_type: model_type为paddlx时,返回的实际paddlex模型的类型: det, seg, clas
  22. */
  23. 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)
  24. {
  25. // create model
  26. model = PaddleDeploy::CreateModel(model_type); //FLAGS_model_type
  27. // model init
  28. model->Init(cfg_file);
  29. // inference engine init
  30. PaddleDeploy::PaddleEngineConfig engine_config;
  31. engine_config.model_filename = model_filename;
  32. engine_config.params_filename = params_filename;
  33. engine_config.use_gpu = use_gpu;
  34. engine_config.gpu_id = gpu_id;
  35. bool init = model->PaddleEngineInit(engine_config);
  36. if (init)
  37. {
  38. std::cout << "init model success" << std::endl;
  39. }
  40. // det, seg, clas, paddlex
  41. if (strcmp(model_type, "paddlex") == 0) // 是paddlex模型,则返回具体支持的模型类型: det, seg, clas
  42. {
  43. // detector
  44. if (model->yaml_config_["model_type"].as<std::string>() == std::string("detector"))
  45. {
  46. strcpy(paddlex_model_type, "det");
  47. }
  48. else if (model->yaml_config_["model_type"].as<std::string>() == std::string("segmenter"))
  49. {
  50. strcpy(paddlex_model_type, "seg");
  51. }
  52. else if (model->yaml_config_["model_type"].as<std::string>() == std::string("classifier"))
  53. {
  54. strcpy(paddlex_model_type, "clas");
  55. }
  56. }
  57. }
  58. /*
  59. * 检测推理接口
  60. *
  61. * img: input for predicting.
  62. *
  63. * nWidth: width of img.
  64. *
  65. * nHeight: height of img.
  66. *
  67. * nChannel: channel of img.
  68. *
  69. * output: result of pridict ,include category_id£¬score£¬coordinate¡£
  70. *
  71. * nBoxesNum£º number of box
  72. *
  73. * LabelList: label list of result
  74. */
  75. extern "C" __declspec(dllexport) void Det_ModelPredict(const unsigned char* img, int nWidth, int nHeight, int nChannel, float* output, int* nBoxesNum, char* LabelList)
  76. {
  77. // prepare data
  78. std::vector<cv::Mat> imgs;
  79. int nType = 0;
  80. if (nChannel == 3)
  81. {
  82. nType = CV_8UC3;
  83. }
  84. else
  85. {
  86. std::cout << "Only support 3 channel image." << std::endl;
  87. return;
  88. }
  89. cv::Mat input = cv::Mat::zeros(cv::Size(nWidth, nHeight), nType);
  90. memcpy(input.data, img, nHeight * nWidth * nChannel * sizeof(uchar));
  91. //cv::imwrite("./1.png", input);
  92. imgs.push_back(std::move(input));
  93. // predict
  94. std::vector<PaddleDeploy::Result> results;
  95. model->Predict(imgs, &results, 1);
  96. // nBoxesNum[0] = results.size(); // results.size()得到的是batch_size
  97. nBoxesNum[0] = results[0].det_result->boxes.size(); // 得到单张图片预测的bounding box数
  98. std::string label = "";
  99. //std::cout << "res: " << results[num] << std::endl;
  100. for (int i = 0; i < results[0].det_result->boxes.size(); i++) // 得到所有框的数据
  101. {
  102. //std::cout << "category: " << results[num].det_result->boxes[i].category << std::endl;
  103. label = label + results[0].det_result->boxes[i].category + " ";
  104. // labelindex
  105. output[i * 6 + 0] = results[0].det_result->boxes[i].category_id; // 类别的id
  106. // score
  107. output[i * 6 + 1] = results[0].det_result->boxes[i].score; // 得分
  108. //// box
  109. output[i * 6 + 2] = results[0].det_result->boxes[i].coordinate[0]; // x1, y1, x2, y2
  110. output[i * 6 + 3] = results[0].det_result->boxes[i].coordinate[1]; // 左上、右下的顶点
  111. output[i * 6 + 4] = results[0].det_result->boxes[i].coordinate[2];
  112. output[i * 6 + 5] = results[0].det_result->boxes[i].coordinate[3];
  113. }
  114. memcpy(LabelList, label.c_str(), strlen(label.c_str()));
  115. }
  116. /*
  117. * 分割推理接口
  118. *
  119. * img: input for predicting.
  120. *
  121. * nWidth: width of img.
  122. *
  123. * nHeight: height of img.
  124. *
  125. * nChannel: channel of img.
  126. *
  127. * output: result of pridict ,include label_map
  128. */
  129. extern "C" __declspec(dllexport) void Seg_ModelPredict(const unsigned char* img, int nWidth, int nHeight, int nChannel, unsigned char* output)
  130. {
  131. // prepare data
  132. std::vector<cv::Mat> imgs;
  133. int nType = 0;
  134. if (nChannel == 3)
  135. {
  136. nType = CV_8UC3;
  137. }
  138. else
  139. {
  140. std::cout << "Only support 3 channel image." << std::endl;
  141. return;
  142. }
  143. cv::Mat input = cv::Mat::zeros(cv::Size(nWidth, nHeight), nType);
  144. memcpy(input.data, img, nHeight * nWidth * nChannel * sizeof(uchar));
  145. //cv::imwrite("./1.png", input);
  146. imgs.push_back(std::move(input));
  147. // predict
  148. std::vector<PaddleDeploy::Result> results;
  149. model->Predict(imgs, &results, 1);
  150. std::vector<uint8_t> result_map = results[0].seg_result->label_map.data; // vector<uint8_t> -- 结果map
  151. // 拷贝输出结果到输出上返回 -- 将vector<uint8_t>转成unsigned char *
  152. memcpy(output, &result_map[0], result_map.size() * sizeof(uchar));
  153. }
  154. /*
  155. * 识别推理接口
  156. *
  157. * img: input for predicting.
  158. *
  159. * nWidth: width of img.
  160. *
  161. * nHeight: height of img.
  162. *
  163. * nChannel: channel of img.
  164. *
  165. * score: result of pridict ,include score
  166. *
  167. * category: result of pridict ,include category_string
  168. *
  169. * category_id: result of pridict ,include category_id
  170. */
  171. extern "C" __declspec(dllexport) void Cls_ModelPredict(const unsigned char* img, int nWidth, int nHeight, int nChannel, float* score, char* category, int* category_id)
  172. {
  173. // prepare data
  174. std::vector<cv::Mat> imgs;
  175. int nType = 0;
  176. if (nChannel == 3)
  177. {
  178. nType = CV_8UC3;
  179. }
  180. else
  181. {
  182. std::cout << "Only support 3 channel image." << std::endl;
  183. return;
  184. }
  185. cv::Mat input = cv::Mat::zeros(cv::Size(nWidth, nHeight), nType);
  186. memcpy(input.data, img, nHeight * nWidth * nChannel * sizeof(uchar));
  187. //cv::imwrite("./1.png", input);
  188. imgs.push_back(std::move(input));
  189. // predict
  190. std::vector<PaddleDeploy::Result> results;
  191. model->Predict(imgs, &results, 1);
  192. *category_id = results[0].clas_result->category_id;
  193. // 拷贝输出类别结果到输出上返回 -- string --> char*
  194. memcpy(category, results[0].clas_result->category.c_str(), strlen(results[0].clas_result->category.c_str()));
  195. // 拷贝输出概率值返回
  196. *score = results[0].clas_result->score;
  197. }
  198. /*
  199. * MaskRCNN推理接口
  200. *
  201. * img: input for predicting.
  202. *
  203. * nWidth: width of img.
  204. *
  205. * nHeight: height of img.
  206. *
  207. * nChannel: channel of img.
  208. *
  209. * box_output: result of pridict ,include label+score+bbox
  210. *
  211. * mask_output: result of pridict ,include label_map
  212. *
  213. * nBoxesNum: result of pridict ,include BoxesNum
  214. *
  215. * LabelList: result of pridict ,include LabelList
  216. */
  217. 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)
  218. {
  219. // prepare data
  220. std::vector<cv::Mat> imgs;
  221. int nType = 0;
  222. if (nChannel == 3)
  223. {
  224. nType = CV_8UC3;
  225. }
  226. else
  227. {
  228. std::cout << "Only support 3 channel image." << std::endl;
  229. return;
  230. }
  231. cv::Mat input = cv::Mat::zeros(cv::Size(nWidth, nHeight), nType);
  232. memcpy(input.data, img, nHeight * nWidth * nChannel * sizeof(uchar));
  233. imgs.push_back(std::move(input));
  234. // predict -- 多次点击单张推理时会出错
  235. std::vector<PaddleDeploy::Result> results;
  236. model->Predict(imgs, &results, 1); // 在Infer处发生错误
  237. nBoxesNum[0] = results[0].det_result->boxes.size(); // 得到单张图片预测的bounding box数
  238. std::string label = "";
  239. for (int i = 0; i < results[0].det_result->boxes.size(); i++) // 得到所有框的数据
  240. {
  241. // 边界框预测结果
  242. label = label + results[0].det_result->boxes[i].category + " ";
  243. // labelindex
  244. box_output[i * 6 + 0] = results[0].det_result->boxes[i].category_id; // 类别的id
  245. // score
  246. box_output[i * 6 + 1] = results[0].det_result->boxes[i].score; // 得分
  247. //// box
  248. box_output[i * 6 + 2] = results[0].det_result->boxes[i].coordinate[0]; // x1, y1, x2, y2
  249. box_output[i * 6 + 3] = results[0].det_result->boxes[i].coordinate[1]; // 左上、右下的顶点
  250. box_output[i * 6 + 4] = results[0].det_result->boxes[i].coordinate[2];
  251. box_output[i * 6 + 5] = results[0].det_result->boxes[i].coordinate[3];
  252. //Mask预测结果
  253. for (int j = 0; j < results[0].det_result->boxes[i].mask.data.size(); j++)
  254. {
  255. if (mask_output[j] == 0)
  256. {
  257. mask_output[j] = results[0].det_result->boxes[i].mask.data[j];
  258. }
  259. }
  260. }
  261. memcpy(LabelList, label.c_str(), strlen(label.c_str()));
  262. }
  263. /*
  264. * 模型销毁/注销接口
  265. */
  266. extern "C" __declspec(dllexport) void DestructModel()
  267. {
  268. delete model;
  269. std::cout << "destruct model success" << std::endl;
  270. }