百度飞桨PP-YOLOE ONNX 在LabVIEW中的部署推理(含源码)


前言

PP-YOLOE是百度基于其之前的PP-YOLOv2所改进的卓越的单阶段Anchor-free模型,超越了多种流行的YOLO模型。如何使用python进行该模型的部署,官网已经介绍的很清楚了,但是对于如何在LabVIEW中实现该模型的部署,笔者目前还没有看到相关介绍文章,所以笔者在实现PP-YOLOE ONNX 在LabVIEW中的部署推理后,决定和各位读者分享一下如何使用LabVIEW实现PP-YOLOE的目标检测。


一、什么是PP-YOLO

在这里插入图片描述
PP-YOLOE是百度基于其之前的PP-YOLOv2所改进的卓越的单阶段Anchor-free模型,超越了多种流行的YOLO模型。PP-YOLOE,有更高的检测精度且部署友好。
PP-YOLOE基于anchor-free的架构,使用强大的backbone和neck,引入了CSPRepResStage,ET-head 和动态标签分配算法TAL。针对不同应用场景,提供了不同大小的模型。即s/m/l/x,可以通过width multiplier和depth multiplier配置。PP-YOLOE避免了使用诸如Deformable Convolution或者Matrix NMS之类的特殊算子,以使其能轻松地部署在多种多样的硬件上。
在这里插入图片描述
PP-YOLOE-l在COCO test-dev2017达到了51.6的mAP, 同时其速度在Tesla V100上达到了78.1 FPS。
PP-YOLOE提供了一键转出 ONNX 格式,可顺畅对接 ONNX 生态。本文主要实现百度PP-YOLOE ONNX 在LabVIEW上的部署推理。


二、环境搭建

1、部署本项目时所用环境

  • 操作系统:Windows10
  • python:3.6及以上
  • LabVIEW:2018及以上 64位版本
  • AI视觉工具包:techforce_lib_opencv_cpu-1.0.0.73.vip
  • onnx工具包:virobotics_lib_onnx_cuda_tensorrt-1.0.0.16.vip【1.0.0.16及以上版本】

2、LabVIEW工具包下载及安装


三、模型的获取与转化

注意:本教程已经为大家提供了PP-YOLOE的模型,可跳过本步骤,直接进行步骤四-推理。若是想要了解PP-YOLO的onnx模型如何获取,则可继续阅读本部分内容。

PP-YOLOE并没有直接提供onnx模型,但是我们可以通过paddle2onnx实现onnx模型的导出。

1、安装paddle

  • PPYOLO需要使用百度paddle框架,我们打开百度飞桨官网:https://www.paddlepaddle.org.cn/,在下方的快速安装选择适合自己版本的paddlepaddle

在这里插入图片描述

  • cmd中执行以下命令安装:
python -m pip install paddlepaddle-gpu==2.3.1.post112 -f https://www.paddlepaddle.org.cn/whl/windows/mkl/avx/stable.html

2、安装依赖的库

  • 从github上下载PaddleDetection并解压到目录,下载地址:https://github.com/PaddlePaddle/PaddleDetection ,将paddledetection根目录添加到环境变量。
  • 在PaddleDetection-release-2.4文件夹中打开cmd,输入以下指令安装需要的库
pip3 install -U pip && pip3 install -r requirements.txt

3、安装pycocotools

pip install pycocotools

若安装pycocotools时遇到ERROR: Could not build wheels for pycocotools ……,则可以使用以下指令来安装:

pip install pycocotools-windows

4、导出onnx模型

(1)导出推理模型

python tools/export_model.py -c configs/ppyoloe/ppyoloe_crn_l_300e_coco.yml --output_dir=output_inference -o weights=https://paddledet.bj.bcebos.com/models/ppyoloe_crn_l_300e_coco.pdparams

(2) 安装paddle2onnx

pip install paddle2onnx

(3) 转换成onnx格式

paddle2onnx --model_dir output_inference/ppyoloe_crn_l_300e_coco --model_filename model.pdmodel --params_filename model.pdiparams --opset_version 11 --save_file ppyoloe_crn_l_300e_coco.onnx

至此已成功导出PP-YOLOE ONNX模型

注意: ONNX模型目前只支持batch_size=1


四、在LabVIEW实现PP-YOLOE的部署推理

本项目整体的文件结构如下图所示,各位读者可在文章末尾链接处下载整个项目源码。
在这里插入图片描述

1、LabVIEW调用PP-YOLOE实现目标检测pp-yolox_main.vi

本例中使用LabvVIEW ONNX工具包中的Create_Session.vi载入onnx模型,可选择使用cpu,cuda进行推理加速。

(1)查看模型

我们可以使用netron 查看ppyoloe_crn_s_300e_coco.onnx的网络结构,浏览器中输入链接:https://netron.app/,点击Open Model,打开相应的网络模型文件即可。
在这里插入图片描述
查看模型属性,可看到模型的输入输出如下图所示:
在这里插入图片描述
我们发现,该模型有两个输入和两个输出,所以推理时候需要有两个输入,需要用到我们的多输入处理vi,run.vi

  • 可以看到图片输入大小为640x640
  • 第一个输出为8400x6[6分别为classese_id,cofidence,框]

(2)实现过程

  • 读取图片并进行图像预处理(-1到1的归一化)
    在这里插入图片描述

  • 初始化一个Vector_Value,新增两个输入tensor(图片及scal_factor)
    在这里插入图片描述

  • 加载模型并选择加速类型(cpu、CUDA、tensorRt)
    在这里插入图片描述

  • 实现多输入推理
    在这里插入图片描述

  • 获取第一层的输出
    在这里插入图片描述

  • 进行后处理
    在这里插入图片描述

  • 绘制检测出的目标及及置信度
    在这里插入图片描述

(3)项目运行

配置本项目所需环境。在文章末尾链接处下载整个项目源码,将我们已经转化好的onnx模型放置到model文件夹中,打开pp_yolo_main.vi,在前面板中修改程序中加载的模型路径为实际模型路径,本项目中已经将PP-YOLOE onnx模型【ppyoloe_crn_s_300e_coco.onnx】放置到了model文件夹中,如需其他模型,读者也可自行放置到model文件及下,实现模型的加载。修改检测图片的路径为实际图片路径,运行程序,可得到目标检测的结果。

  • 主程序源码如下:
    在这里插入图片描述

  • 运行结果如下:

在这里插入图片描述
大家也可以检测其他图片来测试检测效果。

2、LabVIEW调用PP-YOLOE实现实时目标检测ppyolo_camera.vi

实时检测过程,我们可以选择使用CUDA实现推理加速,整个程序的实现过程和加载图片进行检测基本一致。

(1)LabVIEW调用PP-YOLOE实时目标检测源码

在这里插入图片描述

(2)LabVIEW调用PP-YOLOE实现实时目标检测结果

在这里插入图片描述

可以看到使用CUDA进行推理加速,速度还是很快的。


五、完整项目下载链接

链接:https://pan.baidu.com/s/1h4I__FqrfimKauJT8jmOiQ?pwd=yiku

总结

以上就是今天要给大家分享的内容。大家可根据链接下载相关源码与模型。

如果有问题可以在评论区里讨论,提问前请先点赞支持一下博主哦。

如果文章对你有帮助,欢迎✌关注、👍点赞、✌收藏、👍订阅专栏

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
好的,我可以帮你完成这个任务。 首先,需要安装ONNX运行库和YOLOv5模型。你可以从官方网站下载这些文件。在本例,我们将使用ONNX运行库版本1.8.0和YOLOv5模型。 然后,创建一个C++项目,并将ONNX运行库和YOLOv5模型添加到项目。你需要在代码以下头文件: ```cpp #include <onnxruntime_cxx_api.h> #include <iostream> #include <fstream> #include <string> #include <opencv2/opencv.hpp> ``` 接下来,创建一个函数来加载模型和进行推理。以下是一个示例函数: ```cpp void yolov5_inference(const char* model_path, const char* image_path, float confidence_threshold) { Ort::SessionOptions session_options; Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "test"); Ort::Session session(env, model_path, session_options); Ort::AllocatorWithDefaultOptions allocator; Ort::MemoryInfo memory_info = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU); // Load image cv::Mat image = cv::imread(image_path); cv::cvtColor(image, image, cv::COLOR_BGR2RGB); cv::resize(image, image, cv::Size(640, 640)); std::vector<float> input_data; input_data.reserve(640 * 640 * 3); for (int c = 0; c < 3; ++c) { for (int i = 0; i < 640; ++i) { for (int j = 0; j < 640; ++j) { input_data.push_back(static_cast<float>(image.at<cv::Vec3b>(i, j)[c]) / 255.f); } } } std::vector<int64_t> input_dims = { 1, 3, 640, 640 }; size_t input_size = sizeof(float) * input_data.size(); // Create input tensor Ort::Value input_tensor = Ort::Value::CreateTensor<float>(memory_info, input_data.data(), input_size, input_dims.data(), input_dims.size()); // Run inference std::vector<const char*> input_node_names = { "images" }; std::vector<const char*> output_node_names = { "output" }; std::vector<Ort::Value> output_tensors = session.Run(Ort::RunOptions{ nullptr }, input_node_names.data(), &input_tensor, 1, output_node_names.data(), 1); // Process output const float* output_data = output_tensors[0].GetTensorMutableData<float>(); std::vector<int64_t> output_dims = output_tensors[0].GetTensorTypeAndShapeInfo().GetShape(); int num_boxes = static_cast<int>(output_dims[1]); int num_classes = static_cast<int>(output_dims[2]) - 5; std::vector<std::vector<float>> boxes(num_boxes, std::vector<float>(4, 0.f)); std::vector<std::vector<float>> scores(num_boxes, std::vector<float>(num_classes, 0.f)); std::vector<int> classes(num_boxes, 0); for (int i = 0; i < num_boxes; ++i) { int offset = i * output_dims[2]; for (int c = 0; c < 4; ++c) { boxes[i][c] = output_data[offset + c]; } float max_score = 0.f; for (int j = 0; j < num_classes; ++j) { scores[i][j] = output_data[offset + 5 + j]; if (scores[i][j] > max_score) { max_score = scores[i][j]; classes[i] = j; } } } // Filter results by confidence threshold std::vector<int> indices; for (int i = 0; i < num_boxes; ++i) { float max_score = *std::max_element(scores[i].begin(), scores[i].end()); if (max_score > confidence_threshold) { indices.push_back(i); } } // Print results for (int i : indices) { std::cout << "Box " << i << ": "; for (float c : boxes[i]) { std::cout << c << ", "; } std::cout << "Class: " << classes[i] << ", Score: " << *std::max_element(scores[i].begin(), scores[i].end()) << std::endl; } } ``` 此函数使用ONNX运行库加载YOLOv5模型并对给定图像进行推理。它还采用置信度阈值作为输入参数,并仅返回置信度大于该值的边界框。 最后,将此函数编译为动态连接库: ```cpp #include <windows.h> #include <onnxruntime_cxx_api.h> #include <iostream> #include <fstream> #include <string> #include <opencv2/opencv.hpp> #define DllExport __declspec(dllexport) extern "C" DllExport void yolov5_inference(const char* model_path, const char* image_path, float confidence_threshold); void yolov5_inference(const char* model_path, const char* image_path, float confidence_threshold) { // Same as the previous function } ``` 最后,你可以使用LabVIEW调用此动态链接库。在LabVIEW调用动态链接库的方法因版本而异。可以在LabVIEW帮助文档找到有关如何调用动态链接库的更多信息。 至于生成源码,你可以使用Visual Studio生成动态链接库项目的源代码。在Visual Studio,选择“生成”->“生成解决方案”,然后在项目文件夹找到生成的源代码文件。这些文件将包括所有源文件和头文件,以及生成的动态链接库。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

virobotics

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值