PaddleX模型C++部署,dll生成及python初步调用
绪言
之前由于项目需求需要用c++来推理PaddleX模型,Python读取预测结果,过程中遇到不少问题,遂写这篇帖子记录及分享用,也是本人第一次写技术贴。
目前PaddleX GUI囊括了四大类模型,检测、分类、语义分割、实例分割,我对这四种模型的推理代码都做了c++部署。
参考技术贴:https://zhuanlan.zhihu.com/p/148802739
https://mp.weixin.qq.com/s/Hlz7lcy59T507HBVEr4V-w
一、准备工作
Cmake3.16.5
VS2019 Community
Git
预测代码来源(选择develop分支)
Paddle预测库(选择win10下的cuda10版本)
都下载完毕后放在同一个文件夹下
二、利用CMake软件进行编译
- 首先在PaddleX\deploy\cpp\CMakeLists.txt中作如下修改
全部修改后如下
2. 点击config,选择vs2019 X64选项后,点击Generate
3. 根据报错进行修改,主要修改cuda_lib、opencv、paddle_dir路径
再次点击Generate, 再点击Open Project即可打开工程。
三、生成dll
-
在属性—常规—配置类型中修改成.dll文件。
-
在属性 – C/C++ – 常规中修改修改部分附加包含目录,添加ext-yaml-cpp\clude,如果没有的话需要到其他位置找
最好把想用的python安装路径加进来,需要python的dll和lib,为了后续python可读取返回值而准备。
VS调用python可参考这篇帖子:
添加链接描述 -
在属性 – 链接器 – 输入中修改附加依赖项
把原本名称不对的库名称改对,最后注意加上python36_d.lib
-
修改detector.cc作修改
#include <glog/logging.h>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "include/paddlex/paddlex.h"
#include "include/paddlex/visualize.h"
namespace PaddleX {
std::string image;
void PredictImage(std::string image,
PaddleX::DetResult result
);
void Loadmodel() {
std::string model_dir = "E:\\0608\\inference_model";
std::string key = "";
std::string image_list = "";
std::string save_dir = "output";
int gpu_id = 0;
bool use_trt = 0;
bool use_gpu = 1;
// Load model and create a object detector
PaddleX::DetResult result;
PredictImage(image, result);
}
void PredictImage(std::string image,
PaddleX::DetResult result
) {
image = "E:\\0608\\pic\\test.jpg";
cv::Mat im = cv::imread(image, 1);
// PaddleX::DetResult* result;
std::string model_dir = "E:\\0608\\inference_model";
std::string key = "";
std::string image_list = "";
int gpu_id = 0;
bool use_trt = 0;
bool use_gpu = 1;
PaddleX::Model model;
model.Init(model_dir, use_gpu, use_trt, gpu_id, key);
model.predict(im, &result);
for (int i = 0; i < result.boxes.size(); ++i) {
std::cout << ", predict label: " << result.boxes[i].category
<< ", label_id:" << result.boxes[i].category_id
<< ", score: " << result.boxes[i].score
<< ", box(xmin, ymin, w, h):(" << result.boxes[i].coordinate[0]
<< ", " << result.boxes[i].coordinate[1] << ", "
<< result.boxes[i].coordinate[2] << ", "
<< result.boxes[i].coordinate[3] << ")" << std::endl;
}
// 可视化
auto colormap = PaddleX::GenerateColorMap(model.labels.size());
cv::Mat vis_img =
PaddleX::Visualize(im, result, model.labels, colormap, 0.5);
std::string save_dir = "output";
std::string save_path = PaddleX::generate_save_path(save_dir, image);
cv::imwrite(save_path, vis_img);
//result->clear();
std::cout << "Visualized output saved as " << save_path << std::endl;
}
} // namespace Paddle
-
在paddlex.h文档中添加接口,接口如红框内所示
-
然后我们继续点击“重新生成”即可生成dll
四、使用python初步调用生成好的dll(这里暂不能传输结果数据)
Python部分代码如下:
from ctypes import *
dll=CDLL("detector.dll")
print(dll.Loadmodel())
结果图如下:
附言
这里只有结果图,bbox是在c++代码中画出来的,关于python如何读取c++的返回数据我会在下一篇帖子中讲解。