1/3
2/3
3/3
如何在 Windows 上使用 FastDeploy C++ 部署 PaddleDetection 目标检测模型
梦醒南天
2022年09月27日 14:07
收录于文集
共8篇

一、简介

        FastDeploy 是百度开发的一款易用高效的推理部署开发套件。覆盖业界热门 AI 模型并提供开箱即用的部署体验,包括图像分类、目标检测、图像分割、人脸检测、人脸识别、人体关键点识别、文字识别、语义理解等多任务,满足开发者多场景,多硬件、多平台的产业部署需求。

        PaddleDetection 是基于飞桨 PaddlePaddle 的端到端目标检测套件,内置30+模型算法及250+预训练模型,覆盖目标检测、实例分割、跟踪、关键点检测等方向,其中包括服务器端和移动端高精度、轻量级产业级 SOTA 模型、冠军方案和学术前沿算法,并提供配置化的网络模块组件、十余种数据增强策略和损失函数等高阶优化支持和多种部署方案,在打通数据处理、模型开发、训练、压缩、部署全流程的基础上,提供丰富的案例及教程,加速算法产业落地应用。

        在本文中,我们将介绍如何在 Windows 上基于 Visual Studio 2019,使用 FastDeploy C++ 部署 PaddleDetection 的目标检测模型。

FastDeploy

二、环境配置

        首先,我们需要明确 FastDeploy 对环境配置的要求,这一点我们在官方文档中就可以看到(https://github.com/PaddlePaddle/FastDeploy/blob/develop/docs/environment.md)。

FastDeploy环境要求

根据上面的环境配置要求,大家逐一安装即可,本文不做过多介绍。关于 CUDA Toolkit 和 cuDNN,下面是我电脑所安装的版本。

CUDA Toolkit:11.6.0;

cuDNN:cuDNN v8.2.0 (April 23rd, 2021), for CUDA 11.x;

查看CUDA的版本

三、下载 FastDeploy 预编译 C++ 库

fastdeploy-win-x64-gpu-0.2.1.zip:https://bj.bcebos.com/fastdeploy/release/cpp/fastdeploy-win-x64-gpu-0.2.1.zip。这里我们使用的是支持 GPU 的版本。

FastDeploy 预编译 C++ 库

下载完成后,解压到本地,以备后用。

解压 fastdeploy-win-x64-gpu-0.2.1

四、下载 PaddleDetection 套件的目标检测模型 PicoDet

        当然了,在进行部署测试之前,我们首先得知道当前 FastDeploy 都支持哪些模型,否则后续模型推理的时候会报错。从下图中可以看到,PicoDet 是在 FastDeploy 的支持列表中的。

FastDeploy 支持模型列表

在本实验中,我们选择 picodet_l_320_coco_lcnet.tgz(https://bj.bcebos.com/paddlehub/fastdeploy/picodet_l_320_coco_lcnet.tgz)。

picodet_l_320_coco_lcnet 模型

五、使用 Visual Studio 2019 进行部署测试

5.1 创建新项目->控制台应用

创建控制台应用

配置新项目

填写好项目名称和保存位置后,点击“创建”按钮即可完成工程的创建。

Visual Studio 工程创建成功

5.2 参考 FastDeploy 例程编写测试程序

这里我们参考的例程是 FastDeploy fastdeploy-win-x64-gpu-0.2.1 中提供的,具体位置是:fastdeploy-win-x64-gpu-0.2.1\examples\vision\detection\paddledetection\cpp\

FastDeploy 模型推理例程

下面是我们参考例程,然后结合自己的实际情况编写完成的测试代码:

代码块
text/x-c++src
自动换行
复制代码
#include <iostream>
#include "fastdeploy/vision.h"


void PicoDetGpuInfer(const std::string& model_dir, const std::string& image_file)
{
	std::string model_file = model_dir + "model.pdmodel";
	std::string params_file = model_dir + "model.pdiparams";
	std::string config_file = model_dir + "infer_cfg.yml";

	auto option = fastdeploy::RuntimeOption();
	option.UseGpu(0);
	auto model = fastdeploy::vision::detection::PicoDet(model_file, params_file, config_file, option);
	if (!model.Initialized()) {
		printf("[%s][%d] Error: fastdeploy::vision::detection::PicoDet initialized failed !\n", __func__, __LINE__);
		return;
	}

	auto im = cv::imread(image_file);
	auto im_bak = im.clone();

	auto start = std::chrono::system_clock::now();

	fastdeploy::vision::DetectionResult result;
	if (!model.Predict(&im, &result)) {
		printf("[%s][%d] Error: Failed to predict !\n", __func__, __LINE__);
		return;
	}
	//std::cout << res.Str() << std::endl;

	auto end = std::chrono::system_clock::now();
	auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
	double costTime = double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den;
	//printf("[%s][%d] model.Predict success, cost time: %lf s \n", __func__, __LINE__, costTime);

	std::cout << "==========================================================================" << std::endl;
	auto start_time = std::chrono::system_clock::now();
	int test_num = 10;
	for (size_t i = 0; i < test_num; i++)
	{
		if (!model.Predict(&im, &result)) {
			printf("[%s][%d] Error: Failed to predict !\n", __func__, __LINE__);
			return;
		}
	}
	auto end_time = std::chrono::system_clock::now();
	duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
	costTime = double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den;
	costTime /= test_num;
	printf("[%s][%d] test number: %d, average cost time: %lf s \n", __func__, __LINE__, test_num, costTime);
	std::cout << "==========================================================================" << std::endl;

	float score_thereshold = 0.8;
	int line_size = 2;
	float font_size = 1;
	auto vis_image = fastdeploy::vision::Visualize::VisDetection(im_bak, result, score_thereshold, line_size, font_size);
	std::string vis_image_path = "image/visualize/vis_result.jpg";
	cv::imwrite(vis_image_path, vis_image);
	printf("[%s][%d] Visualized result saved in %s !\n", __func__, __LINE__, vis_image_path.c_str());
}

int main()
{
	std::cout << "=============== TEST ===============" << std::endl;

	std::string model_dir = "../models/picodet_l_320_coco_lcnet/";
	//std::string image_file = "image/test/2022-09-26-001.jpeg";
	std::string image_file = "image/test/wangbingbing_003.jpeg";

	//计时
	auto start = std::chrono::system_clock::now();

	PicoDetGpuInfer(model_dir, image_file);

	//计时
	auto end = std::chrono::system_clock::now();
	auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
	double costTime = double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den;

	printf("[%s][%d] Model infer success, cost time: %lf s \n", __func__, __LINE__, costTime);

	std::cout << "=============== Finished ===============" << std::endl;
}
复制成功

5.3 将解决方案配置为“Release x64”

因为我们测试程序依赖的库文件是以 release 的形式发布的,如果这里我们不设置为 release,则在后面链接时会抱错。

解决方案配置

5.4 为工程添加头文件路径

鼠标选择项目,然后单击右键即可弹出下来菜单,在其中单击“属性”。

点击“属性”

在弹出来的属性页中选择:C/C++ —> 常规 —> 附加包含目录,然后在添加 fastdeploy 和 opencv 的头文件路径。如:

E:\PaddlePaddle\FastDeploy\FastDeployInference\fastdeploy-win-x64-gpu-0.2.1\third_libs\install\opencv-win-x64-3.4.16\build\include

E:\PaddlePaddle\FastDeploy\FastDeployInference\fastdeploy-win-x64-gpu-0.2.1\include

注意:上面这两个路径是我自己电脑的,小伙伴们记得根据自己电脑中 fastdeploy-win-x64-gpu-0.2.1 解压的实际路径来填写。

添加头文件路径

5.5 为工程添加库文件及其所在路径

方法和上一个步骤差不多,不过这里选择的是:链接器—>常规—> 附加库目录。

我电脑中的 FastDeploy 和 opencv 的库文件路径如下:

E:\PaddlePaddle\FastDeploy\FastDeployInference\fastdeploy-win-x64-gpu-0.2.1\lib

E:\PaddlePaddle\FastDeploy\FastDeployInference\fastdeploy-win-x64-gpu-0.2.1\third_libs\install\opencv-win-x64-3.4.16\build\x64\vc15\lib

注意:小伙伴们记得根据自己的实际情况进行修改。

添加库文件路径

添加完库文件所在路径后,我们还要添加库文件的名称。这里我们填写的是:

opencv_world3416.lib

fastdeploy.lib

添加库文件

5.6 编译工程

进行上面的一系列配置后,我们点击菜单栏的“生成”,然后在下拉菜单中单击“生成解决方案”就可以对我们的测试程序进行编译了。

编译工程

从上图中可以看到,我们编译成功了,一个报错和警告都没有,非常完美。

5.7 将 exe 可执行程序所依赖的 dll 库文件复制到其所在目录

复制库文件到可执行程序所在目录

5.8 执行测试程序,查看效果

在执行测试程序之前,我们先准备好待测的图片(代码中的 image_file 记得指定路径):

待测图片

按快捷键【Ctrl+F5】或者在菜单栏选择“调试—>开始执行”都可以。

执行程序

从输出的日志中,我们可以看到,picodet_l_320_coco_lcnet 模型的推理耗时 45ms .

程序运行成功

下面是 picodet_l_320_coco_lcnet 检测模型的预测结果:

模型预测结果

至此,关于如何在 Windows 中使用 FastDeploy C++ 部署 PaddleDetection 目标检测模型的介绍就结束了。如果小伙伴们觉得有收获的话,也可以点个赞再走哦。