科技

带你使用PaddleDetection玩转Windows下可视化部署

| 点击:

【www.fsgl168.com--科技】

【飞桨开发者说】:余志良,菲特(天津)智能科技有限公司项目经理,百度黄埔学院二期学员

今年3月、4月我分别发布了两篇文章:《如何用PaddleDetection做一个完整的目标检测项目》以及《》,为大家讲解了从模型训练到模型部署的全过程,其中模型部署基于Paddle预测库的Python接口。本篇将教大家通过PaddleDetection编译C++预测库,并将其封装成dll,实现PaddleDetection在Windows环境下的模型部署。

本文内容主要包括:

    如何进行C++预测的编译(生成.sln解决方案)

    如何将C++预测代码封装成一个dll

  • 如何使用Python调用生成好的dll

  • 如何使用C#调用生成好的dll

    如何进行C++预测代码的编译

    (生成.sln解决方案)

    使用工具Cmake vs2019社区版 Git(提前下载好git,不然在后期编译过程中会不成功)预测代码来源:https://github.com/PaddlePaddle/PaddleDetection/tree/master(注意选择master分支)

    依赖库:OpenCV:选择3.4.6版本https://sourceforge.net/projects/opencvlibrary/files/3.4.6/opencv-3.4.6-vc14_vc15.exe/downloadPaddle预测库:选择win10下的cuda10版本。https://www.paddlepaddle.org.cn/documentation/docs/zh/advanced_guide/inference_deployment/inference/windows_cpp_inference.html

    一、首先将上述需要依赖的OpenCV和预测库,PaddleDetection下载好,并保存在某个文件夹中。如下图是我存放的一个文件夹。

    二、将OpenCV添加到环境变量里面,如下图所示。

    三、利用Cmake软件进行编译。源码路径为cpp文件所在目录,因为里面有CMakeLists.txt文件,同时在该目录下创建了新的文件夹/out用于生成编译后的文件。

    四、点击Configure,选择vs2019 X64选项后,点击Generate。

    五、根据报错进行修改,主要修改cuda_lib、OpenCV、paddle_dir路径。

    六、再次点击Generate。

    七、点击Open Project,同时我们在out文件夹下发现了生成了解决方案。

    八、针对“main”项目进行“重新生成”。同时一定要将模式配置成为Release。

    九、出现报错。

    十、修改报错---根据报错,应该是编译过程中,cudnn.lib寻找不正确。通过修改路径实现。方式为点击属性--连接器--输入--附加依赖项。

    十一、改正上述错误后的正确的形式。

    十二、重新生成,如下图是重新生成后的结果。

    十三、运行该生成的main.exe文件。方式为打开out/release文件,会发现有一个main.exe文件。利用命令行打开后,运行即可。运行过程中需要添加模型的路径以及预测图像的路径。注意:此时此刻进行预测的模型是按照《》中export.py文件形式导出“__model__”和“__params__”的形式,但是在后续paddle的升级过程中,export.py文件不仅仅会导出“__model__”和“__params__”,还会导出一个infer_cfg.yml的文件。在这个过程中,是使用PaddleDetection-release0.3版本进行导出的,因为之前安装的paddle版本是1.7的,而目前的master分支是必须使用paddle2.0版本的。因此小伙伴们需要注意这个问题。如下图是所示的模型保存后的结果形式,依旧使用水果检测的模型进行预测。

    其中yml文件内容

    十四、预测结果如下图所示,我们看到输出的结果中有检测框的坐标、置信度、类别信息。

    如下是在out文件夹生成的命名为“output.jpeg”的检测后图像

    十五、对代码进行一下小修改。之前我们需要在命令行中输入图像和模型的路径,在代码中添加图像和模型的路径,查看预测情况。修改src/main.cpp这个文件如下:

    十六、修改上述两处代码后,设置“设为启动项目”,并点击“本地windows调试器”,直接查看输出的结果。

    至此,完成了第一步以及第一步的所有测试。

    如何将C++预测代码

    封装成一个dll

    一、 我们需要修改CMakeLists.txt文件,修改倒数第十三行,将add_executable(main src/main.cc src/preprocess_op.cc src/object_detector.cc) 变成ADD_library(main SHARED src/main.cc src/preprocess_op.cc src/object_detector.cc)

    二、按照上文继续重新cmake一次。三、再次经历之前的cudnn的路径问题,同时需要在属性—常规—配置类型中修改成.dll文件。

    四、修改完上述内容后,点击“重新生成”,会发现out/release中出现了main.dll文件。

    五、看到dll后,我们仿佛看到了曙光,但是还是需要进行修改,因为这样我们才能被调用,我简化了main.cc文件中的内容,并且配置了dll的接口,代码如下。其中有两个dll的接口,其中“add”是为了测试。
    #include <glog/logging.h>#include <iostream>#include <string>#include <vector>#include "include/object_detector.h"extern "C" __declspec(dllexport) void  Loadmodel();extern "C" __declspec(dllexport) int add(int a, int b);void PredictImage(const std::string& image_path,    PaddleDetection::ObjectDetector* det);int add(int a, int b) {    return a + b;}void Loadmodel() {    std::string model_dir = "D:\\0524\\test\\model";    std::string image_path = "D:\\0524\\test\\orange_71.jpg";    std::string video_path = "";    std::string run_mode = "fluid";    bool use_gpu = true;    // Load model and create a object detector    PaddleDetection::ObjectDetector det(model_dir, use_gpu, run_mode);    PredictImage(image_path, &det);}void PredictImage(const std::string& image_path,    PaddleDetection::ObjectDetector* det) {    // Open input image as an opencv cv::Mat object    cv::Mat im = cv::imread(image_path, 1);    // Store all detected result    std::vector<PaddleDetection::ObjectResult> result;    det->Predict(im, &result);    for (const auto& item : result) {        printf("class=%d confidence=%.2f rect=[%d %d %d %d]\n",            item.class_id,            item.confidence,            item.rect[0],            item.rect[1],            item.rect[2],            item.rect[3]);    }    // Visualization result    auto labels = det->GetLabelList();    auto colormap = PaddleDetection::GenerateColorMap(labels.size());    cv::Mat vis_img = PaddleDetection::VisualizeResult(        im, result, labels, colormap);    std::vector<int> compression_params;    compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);    compression_params.push_back(95);    cv::imwrite("output.jpeg", vis_img, compression_params);    printf("Visualized output saved as output.jpeg\n");}
    六、继续点击“重新生成”,重新生成的dll就是下述步骤中我们即将调用的dll。

    如何使用Python调用

    生成好的dll

    在上一章节我们说了如何生成dll,这一章节,我们需要进行测试,在这里我们使用Python进行测试,利用Python调用dll。在生成的dll的文件中创建一个叫mian.py的Python文件。Python部分代码如下:
    from ctypes import *dll=CDLL("main.dll")print(dll.add(1,2))print(dll.Loadmodel())
    运行Python代码,可以看到最终输出结果如下图:

    至此说明利用Python调用dll成功了。

    如何使用C#调用生成好的dll

    在上一个章节中我们说了如何使用Python调用dll,接着,我们尝试使用C#调用一个dll,此方式为工业上经常使用的一种方式。一、首先创建一个C#的窗体应用程序。

    二、在改窗体应用程序中设置一个button事件。

    三、设置dll接口代码以及设置button,相关代码如下
    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;using System.Runtime.InteropServices;namespace WindowsFormsApp1{    public partial class Form1 : Form    {        int a = 3;        int b = 2;        public Form1()        {            InitializeComponent();        }        [DllImport("main.dll", EntryPoint = "Loadmodel", CharSet = CharSet.Ansi)]        public static extern void Loadmodel();        [DllImport("main.dll", EntryPoint = "add", CharSet = CharSet.Ansi)]        public static extern int add(int a, int b);        private void button1_Click(object sender, EventArgs e)        {            int c = add(a, b);            Loadmodel();        }        private void Form1_Load(object sender, EventArgs e)        {        }    }}
    四、将C++ release路径下生成的文件全部复制到C#项目运行目录下,在C++的release文件中,有一些文件只有dll,没有对应的lib文件,这个时候,我们需要搜索到这些dll对应的lib文件,全部放在C#的运行目录下。(PS#这些对应的文件都在我们下载的paddle预测库中可以找到)

    五、点击“启动按钮”进行测试;

    六、我们在C#的运行目录下发现了生成了一张output.jpeg图片,证明我们调用成功

    至此,该系列文章基本上完成了从训练到部署的所有流程,十分感谢在写作过程中飞桨同学的帮助,非常感谢高松鹤、梁钰同学的大力帮助。后续会根据飞桨针对C++预测的更新,继续更新完善该文章。

    更多资源

    更多PaddleDetection的应用方法,欢迎访问项目地址:GitHub: https://github.com/PaddlePaddle/PaddleDetection Gitee: https://gitee.com/paddlepaddle/PaddleDetection如在使用过程中有问题,可加入飞桨官方QQ群进行交流:703252161。如果您想详细了解更多飞桨的相关内容,请参阅以下文档。官网地址:https://www.paddlepaddle.org.cn飞桨开源框架项目地址:GitHub:https://github.com/PaddlePaddle/PaddleGitee: https://gitee.com/paddlepaddle/Paddle

    END

    本文来源:http://www.fsgl168.com/keji/204188/