FastDeploy+英特尔NUC+大疆无人机梦幻联动!推动智慧城市巡检应用落地
开发环境准备
核心软硬件
英特尔 NUC 迷你电脑套件
(型号:NUC8i5BEH)
FastDeploy >= 0.2.1
PaddleDetection >= 2.5
PaddleSeg >= 2.6
PySide6 >= 6.3.2
可选软硬件(户外实时采集时用)
大疆系列无人机及 DJI Fly APP
路由器(用于内网 RTMP 传输)
英特尔 NUC 迷你电脑硬件
无人机实时图传
RTMP(Real-Time Messaging Protocol,实时消息传送协议)是一个设计用来实时数据通信的网络协议,现多用于直播设备与支持 RTMP 协议的服务器之间进行音视频和数据通信。本项目无人机和推理硬件设备之间的实时图传环节利用的是大疆控制端 APP 的 RTMP 推流服务,为了最大限度地减少图传时间延迟,我们直接在英特尔 NUC 上利用 Nginx 搭建 RTMP 服务。
英特尔 NUC 预装的操作系统是 Windows10,所以可以直接下载带 RTMP 模块的 Nginx。
🔗下载链接http://nginx-win.ecsds.eu/download/nginx%201.7.11.3%20Gryphon.zip
events {
worker_connections 1024;
}
rtmp {
server {
listen 8899;
chunk_size 4000;
application live {
live on;
allow publish all;
allow play all;
}
}
}
打开 DJI Fly APP,找到 RTMP 直播推流,填入推流地址:rtmp://192.168.31.246:8899/live
APP 推流配置完成之后,可以在 NUC 设备端调用 OpenCV 的 API 进行拉流操作以获取无人机实时画面,Python 实现代码如下。
rtmpUrl = 'rtmp://192.168.31.246:8899/live'
vid = cv2.VideoCapture(rtmpUrl)
while vid.isOpened():
ret,frame = vid.read()
cv2.imshow('RTMP Test',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
vid.release()
cv2.destroyAllWindows()
运行这段代码后,Python 程序会实时获取无人机 APP 实时推送的 RTMP 流数据并更新到 OpenCV 窗口显示,运行效果如下图。
FastDeploy
模型推理部署
打通了无人机图像实时传输的环节之后,我们进入核心的推理部署环节。由以上 Python 代码可以看出,RTMP 数据流经过 OpenCV 解码后得到图像帧 (frame),因此推理环节的工作本质就是将每一帧图像输入模型然后得到结果并将输出结果可视化。本环节主要分为三个步骤:模型动静转换、推理脚本编写和前端集成。
模型动静转换
首先,我们需要把使用 PaddleSeg 和 PaddleDetection 开发套件训练好的动态图模型转换成静态图模型,这一步利用两个套件分别提供的脚本即可简单完成。已经训练好的动态图模型可以在 AI Studio 项目中获取。
🔗链接
https://aistudio.baidu.com/aistudio/projectdetail/4535658
语义分割目标检测动态图模型和语义分割分别在 AI Studio 项目中 ppyolo_inference_model 和 output_ppliteseg_stdc1/best_model/ 目录下,分别调用对应的动静转换脚本将两个动态图模型转换成静态图。
▎PaddleSeg
--config ppliteseg_stdc1.yml \ #配置文件路径,根据实际情况修改
--model_path output_ppliteseg_stdc1/best_model/model.pdparams \
# 动态图模型路径,根据实际情况修改
--save_dir inference_ppliteseg_stdc1 \ # 导出目录
--input_shape 1 3 512 1024 #模型输入尺寸
▎PaddleDetection
-c PaddleDetection/configs/ppyolo/ppyolo_tiny_650e_coco.yml \ # 配置文件路径,根据实际情况修改
--output_dir=./ppyolo_inference_model \ # 保存模型的路径
-o weights=ppyolo_tiny_650e_coco.pdparams # 动态图模型路径
注:模型转换的详细教程可参考https://github.com/PaddlePaddle/PaddleSeg/blob/release/2.6/docs/model_export_cn.mdhttps://github.com/PaddlePaddle/PaddleClas/blob/release/2.4/README_ch.md
完成转换之后,我们能分别得到两套 model.pdmodel 和 model.pdiparams 文件以及对应的 yaml 配置文件。
基于 FastDeploy 开发
OpenVINO 推理模块
本项目使用的是英特尔 NUC 迷你电脑套件,选择 FastDeploy 的 OpenVINO 后端作为推理部署解决方案。以往使用 OpenVINO 需要下载套件、安装和配置,过程比较繁琐,因此我采用了 FastDeploy 的部署方案,调用其内置的 OpenVINO 推理后端进行快速开发、部署。FastDeploy 的预编译库安装和使用教程可参考官方 Github 文档。
🔗链接
https://github.com/PaddlePaddle/FastDeploy
因为考虑到程序的适用性和多种硬件环境兼容,我首先写了 Option 配置,根据不同的硬件选择不同的推理后端,在 CPU 环境中,默认使用 OpenVINO 作为推理后端。
import numpy as np
import fastdeploy as fd
from PIL import Image
from collections import Counter
def FastdeployOption(device=0):
option = fd.RuntimeOption()
if device == 0:
option.use_gpu()
else:
# 使用OpenVino推理
option.use_openvino_backend()
option.use_cpu()
return option
然后,将语义分割模型推理代码封装成一个类,方便前端快速调用。在 init 方法中,直接调用了 SegModel()函数进行模型初始化(热加载),通过 SegModel.predict()完成结果的推理,得到推理结果之后执行 postprocess()对结果进行解析,提取建筑和绿地的像素数量,统计图像占比,得到环境要素的占比结果。最后调用 FastDeploy 内置的 vis_segmentation()可视化函数,对推理结果进行可视化。
def __init__(self, device=0) -> None:
self.segModel = fd.vision.segmentation.ppseg.PaddleSegModel(
model_file = 'inference/ppliteseg/model.pdmodel',
params_file = 'inference/ppliteseg/model.pdiparams',
config_file = 'inference/ppliteseg/deploy.yaml',
runtime_option=FastdeployOption(device)
)
def predict(self, img):
segResult = self.segModel.predict(img)
result = self.postprocess(segResult)
visImg = fd.vision.vis_segmentation(img, segResult)
return result, visImg
def postprocess(self, result):
resultShape = result.shape
labelmap = result.label_map
labelmapCount = dict(Counter(labelmap))
pixelTotal = int(resultShape[0] * resultShape[1])
# 统计建筑率和绿地率
buildingRate, greenRate = 0, 0
if 8 in labelmapCount:
buildingRate = round(labelmapCount[8] / pixelTotal* 100, 3)
if 9 in labelmapCount:
greenRate = round(labelmapCount[9] / pixelTotal * 100 , 3)
return {"building": buildingRate, "green": greenRate}
同理,直接调用 FastDeploy 的 PPYOLO()方法完成模型的推理,经过后处理格式化数据之后调用对应的可视化函数 vis_detection()进行渲染。
class DetModel(object):
def __init__(self, device=0) -> None:
self.detModel = fd.vision.detection.PPYOLO(
model_file = 'inference/ppyolo/model.pdmodel',
params_file = 'inference/ppyolo/model.pdiparams',
config_file = 'inference/ppyolo/infer_cfg.yml',
runtime_option=FastdeployOption(device)
)
# 阈值设置
self.threshold = 0.3
def predict(self, img):
detResult = self.detModel.predict(img.copy())
result = self.postprocess(detResult)
visImg = fd.vision.vis_detection(img, detResult, self.threshold, 2)
return result, visImg
def postprocess(self, result):
# 得到结果
detIds = result.label_ids
detScores = result.scores
# 统计数量
humanNum, CarNum = 0, 0
for i in range(len(detIds)):
if detIds[i] == 0 and detScores[i] >= self.threshold:
humanNum += 1
if detIds[i] == 2 and detScores[i] >= self.threshold:
CarNum += 1
return {"human": humanNum, "car": CarNum}
结合 PySide6
开发可视化 GUI 界面
前端开发使用的是 PySide6,界面源代码可在文章最后的 Github 项目链接中获取。整体而言开发难度不大,主要的难点在于三个视频播放的组件同时更新导致的程序卡死或者延时问题。
在本项目中应用的解决方法是用多线程,把三个视频播放组件的后端分开三个独立的线程,一个线程(displayThread)把实时视频流原画推送到前端更新,另外两个线程(segThread 和 detThread)同步完成语义分割和目标检测推理实时视频帧图像并将后处理之后的推理结果图像更新到前端组件上。具体代码如下所示(main.py)。
向下滑动查看所有内容
最后执行 python main.py 运行程序,查看推理效果。
总结
FastDeploy 是一个帮助开发者快速部署深度学习模型的推理部署工具箱,内置了包括 OpenVINO、TensorRT、ONNX Runtime、Paddle Inference 后端,正在集成 Paddle Lite、RKNN 等推理后端。并对各后端进行了针对性的优化,很好地兼容了英特尔 NUC 迷你主机的硬件,无需另外安装 OpenVINO 套件和配置环境,同时也免去了调优提速的烦恼,降低了开发者的学习成本和部署成本,提高了部署开发效率。目前已经支持包括飞桨等生态60+热门模型。更多 AI 模型的推理部署,可前往 FastDeploy 的 GitHub 了解。
🔗链接
https://github.com/PaddlePaddle/FastDeploy
● 往期精彩
火箭发动机喷流的“监察队长”:基于飞桨探索火箭发动机真空羽流流场的快速计算
FastDeploy秒解模型部署难题,助力智慧农业应用快速落地