一. 概述
此篇文章为 eIQ 系列的延伸应用,相信各位已经对于 NXP 所开发的 eIQ 机器学习开发环境 与 GStreamer 快速使用介绍 有一定程度上的认识了!! 若尚未理解的伙伴,请点选上述连结温习一下 !! 所谓的 eIQ NNStreamer 是利用 GStreamer Pipeline 插件的方式,让用户可以快速实现机器学习的一种应用方式。更确切的说, NNStreamer 是 GStreamer 的机器学习的专属插件(Plugins),能够自由配合 GStreamer 的方式来作快速应用。
如下图所示,本系列是隶属于 机器学习开发环境 eIQ 之 应用层 (Application Layer) 中。而本篇将介绍 “eIQ NNStreamer 介绍”。
若新读者欲理解更多人工智能、机器学习以及深度学习的资讯,可点选查阅下方博文
大大通精彩博文 【ATU Book-i.MX8系列】博文索引
eIQ NNStreamer 系列博文-文章架构示意图
二. NNStreamer 介绍
NNStreamer 是一套高效且可靠的机器学习之多媒体框架。是由我们熟知的 GStreamer 框架配合神经网路的插件(Neural Network Plugins) 构成。故其用法一样使用 管道(Pipeline) 的方式来实现,可以适当加入 插件(Plugins) 进行串联应用 ; 如下图所示,为一般 NNStreamer 的应用方式或流程。从摄像头载入影像后,即可进行一系列的影像处理操作,依序为影像缩放(Scale)、影像格式转换(Video Converter)、张量格式转换(Tensor Converter) 、正规化(Nornailze) 、最后由 神经网路插件(Neural Network Plugins) 来解析模组,再将推理结果送至输出即可。
NNStrearmer Pipeline示意图
原始出处 : i.MX Machine Learning User's Guide
神经网路插件(Neural Network Plugins) 是由 张量滤波器(Tensor Filter) 与 张量装饰器(Tensor Decoder) 两个插件组成,前者主要作用为解析并推理模组,支援 TensorFlow Lite 推理引擎 ; 后者用途为呈现结果,此功能就像选择几种固定的呈现模式,比如说物件分类就依照 A 方式设置,物件识别就依照 B 方式设置等等,来实现相关应用。
NNStrearmer Pipeline示意图
原始出处 : i.MX Machine Learning User's Guide
三. 如何安装 NNStreamer ?
NNStreamer 提供数种作业系统的安装说明,分别有 Andriod / masOS / Ubuntu / Ubuntu-PPA 等方式。至于 i.MX8 平台则是内建置入 NNStreamer 多媒体框架,故使用者直接使用即可。
四. 如何使用 NNStreamer ?
在安装完成 NNStreamer 后,直接开启 终端机(Terminal) 并输入指令即可完成 !!
开启 终端机(Terminal) 并输入下列指令,即可实现范例。
(1) 设定环境变数 :
$ wget https://github.com/google-coral/test_data/raw/master/ssd_mobilenet_v2_coco_quant_postprocess.tflite
$ wget https://github.com/google-coral/test_data/raw/master/coco_labels.txt
$ export MODEL=$(pwd)/ssd_mobilenet_v2_coco_quant_postprocess.tflite
$ export LABELS=$(pwd)/coco_labels.txt
(2) 执行 NNStreamer Pipeple :
$ gst-launch-1.0 --no-position v4l2src device=/dev/video3 ! \
video/x-raw,width=640,height=480,framerate=30/1 ! \
tee name=t t. ! queue max-size-buffers=2 leaky=2 ! \
imxvideoconvert_g2d ! video/x-raw,width=300,height=300,format=RGBA ! videoconvert ! video/x-raw,format=RGB ! \
tensor_converter ! \
tensor_filter framework=tensorflow-lite model=${MODEL} custom=Delegate:External,ExtDelegateLib:libvx_delegate.so ! \ tensor_decoder mode=bounding_boxes option1=tf-ssd option2=${LABELS} \
option3=0:1:2:3,50 option4=640:480 option5=300:300 ! \
mix. t. ! queue max-size-buffers=2 ! \
imxcompositor_g2d name=mix sink_0::zorder=2 sink_1::zorder=1 ! waylandsink
NNStrearmer Pipeline - Object Detection流程示意图
如上图与指令所示,当撷取到摄像头影像后(v4l2 src),则会透过 tee 插件 来将串流分为二条路线 ; 第一条路线,则类似于上述所介绍的神经网路插件应用方式,这里会利用 imxvideoconvert_g2d(g2d_convert) 插件 来透过图形加速器将影像缩小至 300x300 的大小。接着,使用 Tensor Converter(T-convet) 插件 将数据转为张量的形式,并送至 张量滤波器(Tensor Filter) 即可透过 TensorFlow 推理引擎与启动 NPU 进行解析模组和推理。 然后就可以设定 张量装饰器(Tensor Decoder) 的展示模式,而这里选择的是 bounding_boxes 模式,来描述物件侦测的结果 !! 同时 option所设置参数用意分别为模组类别、标签、参数细节、原始影像大小、张量影像大小,至于详细用法请查看原始代码。最后用 imxcompositor_g2d(Video Compositor) 插件 来透过图形加速器将合并两条路线的结果并将其显示出来。此外,上图所显示的不同颜色是用来表示每个动作区块与硬体所对应关系,像是紫色部分是使用 GPU、黄色部分是使用到 NPU。
NNStrearmer Pipeline - Object Detection 结果展示
◎ 肢体识别范例(Pose Estimation)
开启 终端机(Terminal) 并输入下列指令,即可实现范例。
(1) 设定环境变数 :
$ wget https://github.com/nnsuite/testcases/raw/master/DeepLearningModels/tensorflow-lite/pose_estimation/posenet_mobilenet_v1_100_257x257_multi_kpt_stripped.tflite
$ wget https://github.com/nnsuite/testcases/raw/master/DeepLearningModels/tensorflow-lite/pose_estimation/point_labels.txt
$ export MODEL=$(pwd)/posenet_mobilenet_v1_100_257x257_multi_kpt_stripped.tflite
$ export LABELS=$(pwd)/point_labels.txt
(2) 执行 NNStreamer Pipeple :
$ gst-launch-1.0 --no-position v4l2src device=/dev/video3 ! \
video/x-raw,width=640,height=480,framerate=30/1 ! \
tee name=t t. ! queue max-size-buffers=2 leaky=2 ! \
imxvideoconvert_g2d ! \
video/x-raw,width=257,height=257,format=RGBA ! videoconvert ! \
video/x-raw,format=RGB ! tensor_converter ! \
tensor_transform mode=arithmetic option=typecast:float32,add:-127.5,div:127.5 ! \
tensor_filter framework=tensorflow-lite model=${MODEL} \
custom=Delegate:External,ExtDelegateLib:libvx_delegate.so ! \
tensor_decoder mode=pose_estimation \
option1=640:480 option2=257:257 option3=${LABELS} option4=heatmap-offset ! \
mix. t. ! queue max-size-buffers=2 ! imxcompositor_g2d name=mix sink_0::zorder=2 \
sink_1::zorder=1 ! fpsdisplaysink
NNStreamer 实现肢体识别的方式,相似于物件侦测范例,仅须替换模组所需的影像大小、肢体识别模组(Model) 以及调整 张量滤波器(Tensor Filter) 和 张量装饰器(Tensor Decoder) 的参数,即可完成。如同下图所呈现的结果,可以清楚找到人体的肢体位置。此外,指令可以配合下方流程示意图一同查看,但该范例目前未提供整数的模组,故无法使用 NPU 运算,系统将自动切换为 CPU 来实现。
NNStrearmer Pipeline - Pose Estimation流程示意图
NNStrearmer Pipeline - Pose Estimation 结果展示
五. 进阶应用
◎ NNStreamer 使用细节
NNStreamer 提供数种范例,可以至 NNStreamer Example Github 查看 ;
- Image Classification
- Object Detection
- Object Detection with 2 cameras
- Pose Estimation
- Text Classification
- Face Landmark
NNStreamer 插件代码,可以至 NNStreamer 查看原始代码
- tensor_converter : 主要用于张量数据的转换
- tensor_decoder : 主要用于模组推理后的数据呈现
- tensor_filter : 主要用于设置 Framework 与放置模组
- tensor_sink : 类似 waylandsink
- tensor_source : 从 Tizen Sensor Framework 撷取到资料流
举例( API 用法 ) :
若是想理解 tensor_decoder 插件的细节的话,查看至 nnstreamer >> tensor_decoder 的代码 ; 这里举先前 物件识别(Object Detection) 所用到的 boundingbox 模式,故可以点击至 tensordec-boundingbox.c 来查看程式段落的注解。如下图所示 ; 其内容清楚的说明 option1、option2、option3 参数该设定什么 ; 以 option1 来举例,若选择 yolov5 的模组,则就要设为 yolov5,同时也告诉使用者这个插件不支援 yolov3 与 yolov4。其他插件的用法也大同小义,仅须要依照官方文件去架设即可完成实作 !!
NNStreamer 提供数种的应用方式,如 Python / C++ / GStreamer 的方式。上述皆使用 GStreamer Pipleline 指令的方式呈现,而这里也介绍另一种 Python 的使用方式给读者。PS : 其他范例可至 nnstreamer-example/native/ 查看
举例 ( Python 代码 ) :
我们可以直接参考 nnstreamer_example_object_detection_tflite.py 代码,这里将透过 GST 与 GObject 套件来启用上述的 GStreamer 代码,如下图所示。
读者仅须要参考此范例,就可以透过 Python 来运行 NNStreamer 范例程式。因此这里提供专门用于 NXP i.MX8M Plus 平台的物件侦测范例与肢体范例,请点选连结。
此外,更进阶一点使用的话,可以结合 Tensor Sink 插件 ; 将资料传送至 Python 的代码中,能够更灵活地实现呈现结果,如下图所示。亦可参考 “nnstreamer_example_multi_model_tflite_float.py” 。
◎ i.MX8 平台使用细节
这里提供一些关于 i.MX8 的平台与 硬体加速器 NPU 的相关表格,供用户作参考。
NNStreamer 所支援的神经网路框架与程式语言 :
NNStreamer 所支援的硬体加速器 :
如何选择不同的硬体加速器的方式 ?
如下图所示。仅须要更换红框内的 custom 的资讯,即可选用 NPU(VX Delegate) 与 CPU(XNNPACK Delegate , Arm 加速) 的资源。
选择不同的硬体加速器的方式示意图
六. 结语
由上述介绍的概念与实作方式,就可以透过 NNStreamer 与 GStreamer 来实现物件侦测与肢体识别等范例。仅需要一行指令就能实现 DEMO,可说是相当方便的用法。但比较可惜的是,需要熟用 API 并修改才能创造更多的应用方式。若欲进阶探讨 NNStreamer 的用法的话,不访可以循着本篇文章所介绍的 NNStreamer 细节着手,能够让读者思路更清楚一些。下篇文章,将会介绍所谓的 NNShark,敬请期待!!
四. 参考文件
[1] 官方文件 - i.MX8 GStreamer User Guide pdf
[2] 第三方资源 - GStreamer 维基百科
[3] 第三方资源 - 什么是Gstreamer?
[4] 官方文件 - i.MX Machine Learning User's Guide pdf
[5] 官方文件 - NNStreamer Github
[6] 官方文件 - NNStreamer
如有任何相关 eIQ NNStreamer 技术问题,欢迎至博文底下留言提问 !!
接下来还会分享更多 eIQ NNStreamer 的技术文章 !!敬请期待 【ATU Book-i.MX8 系列 - eIQ NNStreamer】 !!