系列文章 如何使用PaddleDetection做一个完整项目(三)

该文章是PaddleDetection的完结篇,请参考之前两篇文章

https://zhuanlan.zhihu.com/p/106981555​zhuanlan.zhihu.com

https://zhuanlan.zhihu.com/p/111807886​zhuanlan.zhihu.com

本文将针对如何使用PaddleDetection中C++预测库的编译,封装,调用进行说明。

  • 如何进行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/download​sourceforge.net

Paddle预测库:选择win10下的cuda10版本。

安装与编译 Windows 预测库​www.paddlepaddle.org.cn

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

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

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

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

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

六、再次点击Generate

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

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

九、出现报错

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

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

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

十二、运行该生成的main.exe文件。方式为打开out/release文件,会发现有一个main.exe文件。利用命令行打开后,运行即可。运行过程中需要添加模型的路径以及预测图像的路径。

Ps#####此时此刻进行预测的模型是按照《系列文章 如何适用PaddleDetection实现一完整的项目(一)》中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”的检测后图像

十四、对代码进行一下小修改。之前我们需要在命令行中输入图像和模型的路径,作者在代码中添加图像和模型的路径,查看预测情况。修改如下:

十五、修改上述两处代码后,设置“设为启动项目”,并点击“本地windows调试器”

,直接查看输出的结果。

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

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

  1. 我们需要修改CMakeLists.txt文件,修改倒数第十三行

将add_executable(main src/http://main.cc src/http://preprocess_op.cc src/http://object_detector.cc) 变成ADD_library(main SHARED src/http://main.cc src/http://preprocess_op.cc src/http://object_detector.cc)

  1. 然后按照上文中继续重新cmake一次。
  2. 再次经历之前的cudnn的路径问题,同时需要在属性—常规—配置类型中修改成.dll文件。
  1. 修改完上述内容后,点击“重新生成”,会发现out/release中出现了main.dll文件。
  1. 看到dll后,我们仿佛看到了曙光,但是还是需要进行修改,因为这样我们才能被调用,作者简化了http://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:0524testmodel";std::string image_path = "D:0524testorange_71.jpg";std::string video_path = "";std::string run_mode = "fluid";bool use_gpu = true;// Load model and create a object detectorPaddleDetection::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 objectcv::Mat im = cv::imread(image_path, 1);// Store all detected resultstd::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 resultauto 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.jpegn");
}

六、然后我们继续点击“重新生成”,重新生成的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,此方式为工业上经常使用的一种方式。

  1. 首先创建一个C#的窗体应用程序。
  1. 在改窗体应用程序中设置一个button事件。
  1. 设置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图片,证明我们调用成功

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

如有问题,欢迎沟通,作者微信yzl819819

如何使用graphpad做柱形图_系列文章 如何使用PaddleDetection做一个完整项目(三)...相关推荐

  1. golang适合做什么_这年头中年女人适合做什么兼职

    这年头中年女人适合做什么兼职 m6ergd 这年头中年女人适合做什么兼职 大家都友非常多,已经好几亿了,玩需要别人点赞,把视频刷上去,这样才有更好的访问量,然后就催生了点赞这样的平台.众所周知,戒烟的 ...

  2. 几天后自动领取java怎么做的_学了14天,终于把Java项目一做完啦

    原标题:学了14天,终于把Java项目一做完啦 今天是刘小爱自学Java的第113天. 感谢你的观看,谢谢你. 话不多说,开始今天的学习: 今天过后项目一也就算是结束了. 明天开始学SSM框架,再用S ...

  3. 3ml乐谱制作工具_每个数据科学家应在其下一个ml项目中使用两种工具

    3ml乐谱制作工具 by Braden Riggs and George Williams (gwilliams@gsitechnology.com) Braden Riggs和George Will ...

  4. WPF入门教程系列(一) 创建你的第一个WPF项目

    WPF基础知识 快速学习绝不是从零学起的,良好的基础是快速入手的关键,下面先为大家摞列以下自己总结的学习WPF的几点基础知识: 1) C#基础语法知识(或者其他.NET支持的语言):这个是当然的了,虽 ...

  5. 如何使用graphpad做柱形图_自建房如何做防雷接地?使用什么材料?卫生间等电位如何连接?...

    文章导语:如果我们家里是自己建造房屋的话,很多的朋友都会考虑做防雷和接地系统.这里所谓的防雷接地,就是指的人工接地极和接地极.那么对于楼房的人工接地体应该如何进行制作和安装呢?对于材料和安装上都有哪些 ...

  6. 如何使用graphpad做柱形图_用Graphpad Prism轻松搞定不同类型的柱形图

    原标题:用Graphpad Prism轻松搞定不同类型的柱形图 作者:解螺旋.子非鱼 解螺旋原创 转载请注明来源:解螺旋,医生科研助手 上一次小鱼介绍的两分钟搞定Graphpad Prism的速学法, ...

  7. 采集虚拟机_系列文章:Kubernetes日志采集最佳实践

    前言 上一期主要介绍Kubernetes日志输出的一些注意事项,日志输出最终的目的还是做统一的采集和分析.在Kubernetes中,日志采集和普通虚拟机的方式有很大不同,相对实现难度和部署代价也略大, ...

  8. 将输出结果以json类型打印在控制台上_系列文章:Kubernetes中日志的正确输出姿势...

    前言 上一期主要和大家介绍从全局维度考虑如何去构建K8s中的日志系统,本期我们从实践角度出发来一步步构建K8s中的日志监控体系.构建日志系统的第一步是如何去产生这些日志,而这也往往是最繁杂最困难的一步 ...

  9. string转map集合_[系列文章] Go - Map 集合

    概述 Map 集合是无序的 key-value 数据结构. Map 集合中的 key / value 可以是任意类型,但所有的 key 必须属于同一数据类型,所有的 value 必须属于同一数据类型, ...

最新文章

  1. 《Spring 5 官方文档》18. Web MVC 框架(五)
  2. oracle数据库的net manager配置监听(插图)
  3. windows 8 及vs2012 下载
  4. MYSQL 加密函数的用法
  5. python 增删列表_python 列表的增删改查
  6. Dotfuscator使用教程
  7. 超越提升和迁移 充分利用云计算的七种方法
  8. centos 本地化配置
  9. Lotus Domino服务器及其应用系统的高级管理(2)
  10. 微型计算机工作最小时间单位,2010~2011学年第1学期微机原理2试卷A(答案)
  11. 珠海空号检测的运行原理
  12. css页面载入动画,纯css创建网页加载动画
  13. 网易公开课“Programming Paradigms” 笔记
  14. 通过read_excel打开xls文件时,报错struct.error: unpack requires a bytes object of length 2
  15. 记2019届阿里校招第一面
  16. web前端开发--------CSS基础教程
  17. unity屏幕渐变黑白效果
  18. Linux添加PCF8563 RTC支持
  19. Linux下apache性能配置调优
  20. NJFU软件需求分析试卷

热门文章

  1. 如何将 SAP UI5 应用托管到 Github 网站上并运行
  2. SAP Spartacus module 延迟加载和正常加载的 chunk 内容差异
  3. 以 B2C 和 B2B 方式启动 SAP Spartacus 的批处理文件
  4. Web 应用客户端渲染和服务器端渲染的比较
  5. SAP Spartacus Definition of Done
  6. Rxjs takeWhile 和 filter 操作符的区别
  7. 关于Angular @Injectable的几种测试情况
  8. SAP Cloud Platform Neo环境的权限管理
  9. 浅谈Java和SAP ABAP的静态代理和动态代理,以及ABAP面向切面编程的尝试
  10. Fiori Hash url的生成原理