参考:
https://blog.csdn.net/weixin_35894210/article/details/114789700
https://blog.csdn.net/yzl819819/article/details/104743106/
这里以maskrcnn为例(路径要改成你自己的):
python tools/export_model.py -c C:\Users\Administrator\.cache\paddle\configs\mask_rcnn_r50_fpn_1x_coco.yml --output_dir=./inferModel -o weights=C:\Users\Administrator\.cache\paddle\weights\mask_rcnn_r50_fpn_1x_coco.pdparams
c++端的代码
// QString imgPath = "C:/Users/Administrator/Desktop/paddleDemo/PaddleDetection/demo/000000014439_640x640.jpg";
QString imgPath = "C:/Users/Administrator/Desktop/paddleDemo/PaddleDetection/demo/000000014439.jpg";
cv::Mat img = cv::imread(imgPath.toStdString());
cv::resize(img, img, cv::Size(640, 480)); //有一些图片尺寸无法处理,不过好像只要是2的n次方的都可以
cv::imshow("the img", img);
//这里我没有减去均值,减均值也许会更好?
auto blob = cv::dnn::blobFromImage(img, 1.0 / 255.0, cv::Size(img.cols, img.rows), cv::Scalar(), false, false);
int imgHeight = blob.size.p[3];
int imgWidth = blob.size.p[2];
qDebug() << "img size:" << imgWidth << imgHeight;
// 创建默认配置对象
paddle_infer::Config config;
QString modelName;
modelName = "mask_rcnn_r50_fpn_1x_coco";
// modelName = "yolov3_darknet53_270e_coco";
QString modelPath = QString("C:/Users/Administrator/Desktop/paddleDemo/PaddleDetection/inferModel/%1/model.pdmodel").arg(modelName);
QString paraPath = QString("C:/Users/Administrator/Desktop/paddleDemo/PaddleDetection/inferModel/%1/model.pdiparams").arg(modelName);
config.SetModel(modelPath.toStdString(),
paraPath.toStdString());
// config.SetModel("resnet50/inference.pdmodel",
// "resnet50/inference.pdiparams");
// // 启用 GPU 和 MKLDNN 预测
config.EnableUseGpu(500, 0);
config.EnableMKLDNN();
// config.EnableTensorRtEngine();
// // 开启 内存/显存 复用
config.EnableMemoryOptim();
auto predictor = paddle_infer::CreatePredictor(config);
// 获取输入 Tensor
auto input_names = predictor->GetInputNames();
auto imgShape_tensor = predictor->GetInputHandle(input_names[0]);
auto img_tensor = predictor->GetInputHandle(input_names[1]);
auto scaleFactor_tensor = predictor->GetInputHandle(input_names[2]);
for(int i = 0; i < input_names.size(); i++)
{
qDebug() << "input:" << input_names[i].data();
}
// qDebug() << input_tensor->shape();
// 设置输入 Tensor 的维度信息
std::vector<int> imgShape_SHAPE = {1, 2};
imgShape_tensor->Reshape(imgShape_SHAPE);
std::vector<int> img_SHAPE = {1, 3, imgWidth, imgHeight};
img_tensor->Reshape(img_SHAPE);
std::vector<int> scaleFactor_SHAPE = {1, 2};
scaleFactor_tensor->Reshape(scaleFactor_SHAPE);
// qDebug() << input_tensor->shape();
// 准备输入数据
std::vector<float> imgShape_data(1*2);
imgShape_data[0] = imgWidth;
imgShape_data[1] = imgHeight;
// std::vector<float> img_data(3 * imgWidth * imgHeight);
std::vector<float> scaleFactor_data(1*2, 1.0);
// 设置输入 Tensor 数据
imgShape_tensor->CopyFromCpu(imgShape_data.data());
// img_tensor->CopyFromCpu(img_data.data());
img_tensor->CopyFromCpu((float*)blob.data);
scaleFactor_tensor->CopyFromCpu(scaleFactor_data.data());
for(int i = 0; i < 4; i++)
{
QTime begin = QTime::currentTime();
// 执行预测
predictor->Run();
qDebug() << "interval:" << begin.msecsTo(QTime::currentTime());
}
// 获取 Output Tensor
auto output_names = predictor->GetOutputNames();
//导出模型输出统一为NMS的输出,形状为[N, 6], 其中N为预测框的个数,6为[class_id, score, x1, y1, x2, y2]
auto output_tensor0 = predictor->GetOutputHandle(output_names[0]);
//这个的shape为[1], 不知道是啥, 是检测到的物体个数
auto output_tensor1 = predictor->GetOutputHandle(output_names[1]);
//这个应该是mask
auto output_tensor2 = predictor->GetOutputHandle(output_names[2]);
for(int i = 0; i < output_names.size(); i++)
{
qDebug() << "output:" << output_names[i].data();
}
qDebug() << "output shape:" << output_tensor0->shape();
qDebug() << "output shape:" << output_tensor1->shape();
qDebug() << "output shape:" << output_tensor2->shape();
// 获取 Output Tensor 的维度信息
std::vector<int> output_shape = output_tensor0->shape();
int output_size = std::accumulate(output_shape.begin(), output_shape.end(), 1,
std::multiplies<int>());
// 获取 Output Tensor 的数据
std::vector<float> output_data;
output_data.resize(output_size);
output_tensor0->CopyToCpu(output_data.data());
output_shape = output_tensor2->shape();
qDebug() << "tensor type:" << output_tensor2->type();
output_size = std::accumulate(output_shape.begin(), output_shape.end(), 1,
std::multiplies<int>());
std::vector<qint32> masks_data;
masks_data.resize(output_size);
output_tensor2->CopyToCpu(masks_data.data());
int objectCount = output_tensor0->shape()[0];
for(int i = 0; i < objectCount; i++)
{
float *ptr = output_data.data() + 6 * i;
float score = *(ptr + 1);
// qDebug() << score;
if(score < 0.9)
{
continue;
}
float x1 = *(ptr + 2);
float y1 = *(ptr + 3);
float x2 = *(ptr + 4);
float y2 = *(ptr + 5);
cv::rectangle(img, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(0, 255, 125), 3);
qint32 *maskPtr = masks_data.data() + imgWidth * imgHeight * i;
cv::Mat mask(img.rows, img.cols, CV_32SC1, maskPtr);
mask.convertTo(mask, CV_32FC1);
QString maskName = QString("mask%1").arg(i);
cv::imshow(maskName.toStdString(), mask);
};
cv::imshow("result", img);