写在前面
背景:
飞桨官方提供了PaddleX部署的例子,下面的过程都是参考paddleX和paddleseg,在他们的github仓库都能找到相应的文档。这里只做为学习记录。
1、环境
- CUDA10.1 Cudnn 7.6
- opencv版本3.4.6
- PaddleInference 的预测库 C++版
- TensorRT 6.0.1.5
- Cmake 3.22.3
- VS2019 社区版(建议使用vs2019,其他版本会出问题,我用vs2022就被坑了)
2、准备
- 下载好PaddleX代码和PaddleInference预测库
- 下载Tensorrt,并设置系统环境变量 在本项目中使用的cuda版本是10.2,下载对应的trt版本
- 为了便于项目管理,将所有的文件汇总到一个文件夹中
- 设置OpenCV系统环境变量
3、代码编译
3.1 GPU+TRT版本
3.2 CPU版本
3.3 解决方案
最终在out文件夹中出现了.sln文件,则表示通过cmake生成成功了解决方案。
用vs2019打开项目。
4、修改文件
①修改CMakeLists.txt
修改第121行左右
# add_executable(model_infer model_infer.cpp ${SRC} ${ENGINE_SRC} ${DETECTOR_SRC} ${ENCRYPTION_SRC})
add_library(model_infer SHARED model_infer.cpp ${SRC} ${ENGINE_SRC} ${DETECTOR_SRC} ${ENCRYPTION_SRC})
②修改model_infer.cpp
在paddleX的github仓库里,找到paddleX/deploy/cpp/docs/csharp_deploy/model_infer.cpp
这个文件,替换掉本地项目中的PaddleX/deploy/cpp/demo/model_infer.cpp
③针对自己的项目需求再修改model_infer.cpp
比如这里我要做一个获取图像检测坐标的功能。我修改Seg_ModelPredict
函数
(如果没有特定的需求,就不用修改model_infer.cpp的源码)
extern "C" __declspec(dllexport) void Seg_ModelPredict(const unsigned char* img, int nWidth, int nHeight, int nChannel, unsigned char* output, unsigned int* tar_pos)
{
// prepare data
std::vector<cv::Mat> imgs;
std::deque<int> value_1_pos; // 记录当X=256时,Y对应的位置的值=1的坐标位置
int indexSrc = 0;
unsigned char color_id = 0;
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);
std::vector<uint8_t> result_map = results[0].seg_result->label_map.data; // vector<uint8_t> -- Result Map
// Copy output result to the output back -- from vector<uint8_t> to unsigned char *
memcpy(output, &result_map[0], result_map.size() * sizeof(uchar));
for (int i = 0; i < 512; i++) { // height
indexSrc = i * 512 + 256;
color_id = (int)output[indexSrc] % 256; // Pixel category ID
if (color_id == 1) {
value_1_pos.push_back(i);
}
}
if (value_1_pos.begin() != value_1_pos.end()) {
*tar_pos = round((value_1_pos.back() - value_1_pos.front()) / 2) + value_1_pos.front();
}
else {
*tar_pos = 0;
}
}
④生成DLL
不出什么意外的话
然后在F:\edge_download\px\PaddleX-2.0.0\deploy\cpp\out\paddle_deploy
你就会看到
我们再将Release中的model_infer.dll
复制过来,一共7个文件,就是我们需要的所有DLL了。
CPU版本只有5个文件
5、问题
1、找到不到G:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\lib\x64\cudnn.lib
在安装cuda
的时候,把cudnn
的lib
目录下的cudnn.lib
文件复制到....CUDA\v10.1\lib\x64
目录中去。
2、如果遇到,比如:
- 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int
- …未定义
- 没有找到声明
之类的问题,建议把所有文件删掉,重新开始。从第3步开始、解压文件,代码编译。。。。。。