Windows PaddleSeg c++部署OCRNet+HRNet模型
1 准备环境
参考上一篇:Windows PaddleSeg c++部署
2 准备模型
2.1 训练得到model.pdparams
python train.py \
--config configs/ocrnet/ocrnet_hrnetw18_cityscapes_1024x512_160k_lovasz_softmax.yml \
--resume_model output/iter_12000 \
--do_eval \
--use_vdl \
--save_interval 750 \
--save_dir output
2.2 导出预测模型
在PaddleSeg
根目录下,执行如下命令,导出预测模型,保存在output/inference_model
目录。
python tools/export.py \
--config configs/ocrnet/ocrnet_hrnetw18_cityscapes_1024x512_160k_lovasz_softmax.yml \
--model_path output/iter_12000/model.pdparams \
--save_dir output/inference_model
2.3 导出dynamic_shape.pdtxt
(可选,当使用TensorRT
加速,并开启dynamic_shape
时,可直接加载该文件)
python deploy/python/collect_dynamic_shape.py \
--config output/inference_model/deploy.yaml \
--image_path path/to/test/image \
--dynamic_shape_path output/inference_model/dynamic_shape.pbtxt
2.3 预测模型文件
如下是导出的预测模型文件。
output/inference_model
├── deploy.yaml # 部署相关的配置文件,主要说明数据预处理方式等信息
├── dynamic_shape.pdtxt # 用于TensorRT加速的dynamic shape信息
├── model.pdmodel # 预测模型的拓扑结构文件
├── model.pdiparams # 预测模型的权重文件
└── model.pdiparams.info # 参数额外信息,一般无需关注
3 修改test_seg.cc
用Netron 打开model.pdmodel
,点击输入节点即可看到预测模型的输入输出的个数、数据类型。
修改deploy/cpp/src/test_seg.cc文件中的下面代码,改为输出对应的数据类别:
```clike
//std::vector<int64_t> out_data(out_num);
std::vector<float> out_data(out_num);//改为float
output_t->CopyToCpu(out_data.data());
cv::Size size = cv::Size(cols, rows);
int skip_index = size.height * size.width;
const int num_classes = 15;//改为对应的类别数
cv::Mat seg_planes[num_classes];
for (int i = 0; i < num_classes; i++) {
seg_planes[i].create(size, CV_32FC(1));
}
for (int i = 0; i < num_classes; i++) {
::memcpy(seg_planes[i].data, out_data.data() + i * skip_index, skip_index * sizeof(float));
}
cv::Mat seg_result;
cv::merge(seg_planes, num_classes, seg_result);
cv::Mat image_final;
cv::resize(seg_result, image_final, cv::Size(input_width, input_height - cut_height));
cv::Mat binary_image = cv::Mat::zeros(cv::Size(input_width, input_height), CV_8UC1);
for (int y = cut_height; y < image_final.rows + cut_height; y++) {
for (int x = 0; x < image_final.cols; x++) {
cv::Vec<float, num_classes> elem = image_final.at<cv::Vec<float, num_classes>>(y - cut_height, x);
int index = std::distance(&elem[0], max_element(&elem[0], &elem[0] + num_classes));
binary_image.at<uchar>(y, x) = index;
}
}
// Get pseudo image
cv::Mat out_eq_img;
cv::equalizeHist(binary_image, out_eq_img);
cv::imwrite("out_img_seg.jpg", binary_image * 255);
LOG(INFO) << "Finish, the result is saved in out_img_seg.jpg";
std::vector<int64_t> out_data(out_num)
不修改为float
报The type of data we are trying to retrieve does not match the type of data currently contained in the container
4 执行
test_seg.exe --model_dir=./inference_model --img_path=./1.jpg --devices=GPU