一.? ?概述
此篇文章為 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】?!!
參考來源