你觉得这篇文章怎么样? 帮助我们为您提供更好的内容。
Thank you! Your feedback has been received.
There was a problem submitting your feedback, please try again later.
你觉得这篇文章怎么样?
作者 |
張嘉鈞 |
難度 |
普通 |
材料表 |
Webcam X1 NVIDIA JetsonNano X1 |
DeepStream
現在是一個AI大世代,NVIDIA開發出DeepStream SDK讓任何人都能輕鬆快速地建立以 AI 為基礎的 GPU 加速應用程式,以進行影像分析。上述取自於NVIDIA原廠文章,除此之外我有專門寫一篇來講解比較細部的技術與特色:https://www.rs-online.com/designspark/nvidia-deepstream-cn。
Jetson Nano 上安裝 DeepStream
首先,我們需要先安裝依賴套件:
$ sudo apt install \
libssl1.0.0 \
libgstreamer1.0-0 \
gstreamer1.0-tools \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly \
gstreamer1.0-libav \
libgstrtspserver-1.0-0 \
libjansson4=2.11-1 -y
安裝 librdkafka
下載函式庫
$ git clone https://github.com/edenhill/librdkafka.git
配置與建構 函式庫
$ cd librdkafka
$ git reset --hard 7101c2310341ab3f4675fc565f64f0967e135a6a
$ ./configure
$ make
$ sudo make install
複製 librdkafka 建置完的函式庫到DeepStream的資料夾中
$ sudo mkdir -p /opt/nvidia/deepstream/deepstream-5.0/lib
$ sudo cp /usr/local/lib/librdkafka* /opt/nvidia/deepstream/deepstream-5.0/lib
安裝完相依套件之後就可以安裝DeepStream SDK了,在這之前需要先確認一下自己的 JetPack 版本,因為DeepStream的版本也需要對應才能使用:
$ sudo apt-cache show nvidia-jetpack
或者也可以只用 jetson_stats來查看 ( 需要額外安裝 )
$ jetson_release
總之,只要確認自己使用的Jetpack版本之後,就可以找出對應使用的DeepStream版本,從Deep Stream的介紹文件中可以找到下方這張表格,我們的JetPack版本是4.4 對應到的是 DS 5.0, 5.0.1,如果是要使用 DS 5.1的話則需要升級成JetPack 32.5.1。
接著可以從下列的網址找到各版本的封存,如果你直接Google搜尋舊版本,NVIDIA都會導到最新的,所以一定要加上「Archived」,這邊我們選擇 DeepStream 5.0 的版本,並且下載壓縮檔:
下載下來之後就可以將其解壓縮到根目錄
$ cd ~/Downloads
$ sudo tar -xvf deepstream_sdk_5.0_jetson.tbz2 -C /
進行安裝
$ cd /opt/nvidia/deepstream/deepstream-5.0/
$ sudo ./install.sh
$ sudo ldconfig
接著輸入下列指令確認是否安裝成功
$ deepstream-app --version-all
只要有看到版本資訊就代表安裝成功了。
卸載DeepStream ( 補充 )
$ cd /opt/nvidia/deepstream/deepstream/
$ sudo vi uninstall.sh
set PREV_DS_VER=5.0
$ sudo chmod +x uninstall.sh
$ sudo ./uninstall.sh
DeepStream App推論用的範例程式 (deepstream-app)
我們可以到下列路徑查看所有可以使用範例,基本上DeepStream的運行方式都會跟配置檔一起搭配使用,所以我們要稍微理解並分析一下配置檔的內容才行。
$ cd samples/configs/deepstream-app
$ ls
第一個範例程式 ( source1_usb_dec_infer_resnet_int8 )
運行第一個範例程式,從檔名就可以知道它是只有一個來源,是usb的device,進行的是inference並且執行的模型是resnet,資料型態是int8,不過這邊要提醒大家int8只能在Xavier上運作,Nano系列只能跑fp16,所以都需要rebuild 會耗費一些時間;要執行這些配置檔都需要透過deepstream-app這個指令來運行,在輸入檔名之前還需給予 -c 告訴程式這是配置檔。
$ deepstream-app -c source1_usb_dec_infer_resnet_int8.txt
這系列提供的範例模型僅能辨識「Car」、「Bicycle」、「Person」、「RoadSign」,所以我拿了手機提供台灣街景的畫面讓它進行分析,執行效果如下。
接著來分析一下它的配置檔吧!一開始會先遇到的是 App的基本設定 ( application ),enable-perf-measurement是評估性能;perf-measurement-interval-sec採樣和顯示性能評估的時間間隔(以秒為單位);。
[application]
enable-perf-measurement=1
perf-measurement-interval-sec=5
#gie-kitti-output-dir=streamscl
接著是平行顯示 ( tiled-display ) 的設定,平行顯示這裡不確定翻譯的正不正確,你們可以想像是監視器畫面的概念,可以同時顯示多個畫面。
首先enable就是要不要開啟顯示的功能,rows跟columns用來控制顯示畫面的數量,width跟height則是整個畫面的大小。
[tiled-display]
enable=1
rows=1
columns=1
width=1280
height=720
再來是顯示畫面的來源 ( source ),type用來控制我們的來源:
1: Camera (V4L2)
2: URI
3: MultiURI
4: RTSP
5: Camera (CSI) (Jetson only)
我們這裡設定為USB攝影機所以選擇1,接下來就是一些基本的設定 fps-n是最大的fps數值d則是最小的,再來使用USB攝影機很重要的點就是dev-node要設定好,可以從輸入 ls /dev 去確認,通常名稱為 video*,*從0開始。
[source0]
enable=1
#Type - 1=CameraV4L2, 2=URI, 3=MultiURI, 4=RTSP, 5=CSI
type=1
camera-width=640
camera-height=480
camera-fps-n=30
camera-fps-d=1
camera-v4l2-dev-node=0
搞定了輸入就要來搞定輸出 ( sink ) ,Type有很多種可以選擇:
1: Fakesink 不進行輸出
2: EGL based windowed sink (nveglglessink) 使用一般的Ubuntu 視窗開起
3: Encode + File Save (encoder + muxer + filesink) 儲存成影片
4: Encode + RTSP streaming 使用RTSP串流方式輸出
5: Overlay (Jetson only) 強制覆蓋在畫面上
6: Message converter + Message broker
這邊可以看到我們使用的是Overlay,它會直接覆蓋在該螢幕最上層,所以如果你只有一個螢幕不建議這樣做。
sync則是輸出影片的是否要同步( 0:越快越好 1: 同步 )。
display-id跟overlay-id是只有在Overlay的時候才需要特別宣告的,display是顯示的螢幕;overlay-id是編號,一定要大於1才行。
source-id則是緩存區域的編號,會包在source的名稱當中,如果你有N個source* 跟sink*,你的source-id則要去搭配 * 的編號才行。
[sink0]
enable=1
#Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming 5=Overlay
type=5
sync=0
display-id=0
offset-x=0
offset-y=0
width=0
height=0
overlay-id=1
source-id=0
在介紹一下配置檔提供的另外兩種配置,第一個是輸出成檔案,這邊預設是先關閉的(enable=0),這邊註解的部分都有告訴使用者格是怎麼樣去選擇。
[sink1]
enable=0
type=3
#1=mp4 2=mkv
container=1
#1=h264 2=h265 3=mpeg4
codec=1
#encoder type 0=Hardware 1=Software
enc-type=0
sync=0
bitrate=2000000
#H264 Profile - 0=Baseline 2=Main 4=High
#H265 Profile - 0=Main 1=Main10
profile=0
output-file=out.mp4
source-id=0
而另一種配置則是輸出成網路串流 (RTSP),這是大部分業界會想要做到的功能,最主要需要設定的地方在rtsp-port端口,Windows上擷取rtsp的方法等等會再補充介紹。
[sink2]
enable=0
#Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming 5=Overlay
type=4
#1=h264 2=h265
codec=1
#encoder type 0=Hardware 1=Software
enc-type=0
sync=0
bitrate=4000000
#H264 Profile - 0=Baseline 2=Main 4=High
#H265 Profile - 0=Main 1=Main10
profile=0
# set below properties in case of RTSPStreaming
rtsp-port=8554
udp-port=5400
接著是處理我們在畫面中看到物件的邊界框以及標籤
[osd]
enable=1
border-width=2
text-size=15
text-color=1;1;1;1;
text-bg-color=0.3;0.3;0.3;1
font=Serif
show-clock=0
clock-x-offset=800
clock-y-offset=820
clock-text-size=12
clock-color=1;0;0;0
接下來是設定串流,live-source是宣告是否為即時影像,最後註解掉的attach-sys-ts-as-ntp則是決定時間的顯示是要顯示網路串流的時間還是DeepStream分析完的時間。
[streammux]
##Boolean property to inform muxer that sources are live
live-source=1
batch-size=1
##time out in usec, to wait after the first buffer is available
##to push the batch even if the complete batch is not formed
batched-push-timeout=40000
## Set muxer output width and height
width=1280
height=720
## If set to TRUE, system timestamp will be attached as ntp timestamp
## If set to FALSE, ntp timestamp from rtspsrc, if available, will be attached
# attach-sys-ts-as-ntp=1
最後是設定TensorRT引擎,快速講解TensorRT引擎是由NVIDIA提出的一個AI推論加速引擎,現有的NVIDIA相關工具都是把模型轉換成TensorRT以獲得更快的體驗,而DeepStream又有一個更好玩的功能,就是它會有主要運行的模型(primary-gie)以及多個次級模型(secondary-gie%d),不過在我們這個範例當中它只有運行主要的GIE,首先要先宣告引擎的路徑 (model-engine-file);接著是要宣告bbox的顏色;接著是interval這個參數代表的是每一次會有幾個批次的資料不被推論,或許是要降低負擔才有這個參數,不過這邊只有一個引擎所以設定0全部的幀都進行推論;gie-unique-id則是GIE的編號;config-file是模型的配置檔,如果有客製化模型的需求也需要去修改這個檔案。
# config-file property is mandatory for any gie section.
# Other properties are optional and if set will override the properties set in
# the infer config file.
[primary-gie]
enable=1
model-engine-file=../../models/Primary_Detector/resnet10.caffemodel_b30_gpu0_int8.engine
#Required to display the PGIE labels, should be added even when using config-file
#property
batch-size=1
#Required by the app for OSD, not a plugin property
bbox-border-color0=1;0;0;1
bbox-border-color1=0;1;1;1
bbox-border-color2=0;0;1;1
bbox-border-color3=0;1;0;1
interval=0
#Required by the app for SGIE, when used along with config-file property
gie-unique-id=1
config-file=config_infer_primary.txt
到這邊,第一個範例程式的配置檔終於結束了。
第二個範例程式 (source8_1080p_dec_infer-resnet_tracker_tiled_display_fp16_nano.txt)
這個範例主要在示範8個來源怎麼設定平行顯示,並且添加了tracker的功能,可以追蹤辨識到的物件,那這邊我們介紹配置檔的同時也會稍微修改內容。
平行顯示最主要要設定的就在 tiled-display,我們需要把rows跟columns設定成4跟2代表著有4列2行,總共可以放8個畫面。
[tiled-display]
enable=1
rows=4
columns=2
width=1280
height=720
再來不同的地方就是來源 ( source ),這邊選擇的是MultiURI,可以讓多個顯示器都輸出同一個影片,這個型態需要宣告的是 num-sources 告訴DS總共要同時輸入幾個來源,gpu-id如果有多個GPU的話可以額外設定,cudadec-memtype則是分配CUDA內存的儲存類型。
[source0]
enable=1
#Type - 1=CameraV4L2 2=URI 3=MultiURI 4=RTSP
type=3
uri=file://../../streams/sample_1080p_h264.mp4
num-sources=8
#drop-frame-interval=2
gpu-id=0
# (0): memtype_device - Memory type Device
# (1): memtype_pinned - Memory type Host Pinned
# (2): memtype_unified - Memory type Unified
cudadec-memtype=0 cudadec-memtype=0
處理好來源接著就是輸出了,這邊要補充下列這段,並且把原本的sink0的enable改為0。
[sink3]
enable=1
#Type - 1=FakeSink 2=EglSink 3=File
type=2
sync=1
source-id=0
gpu-id=0
nvbuf-memory-type=0
原本是使用Overlay,但是我實測過使用Overlay,就無法做到點擊單一來源顯示的效果,建議這邊先改成EglSink,只要是EglSink就可以偵測你滑鼠點擊的位置知道你現在要著重觀看哪一個source,並且原本平行輸出的畫面是沒有標籤等文字訊息的,點進去那些文字訊息就會跑出來。
接著就要講到tracker的部分了,這邊比較特別的地方是如果要使用tracker需要把寬高設定成32的倍數;ll-lib-file函式庫的路徑;ll-config-file配置檔的路徑;enable-batch-process開啟批次處理。
[tracker]
enable=1
# For the case of NvDCF tracker, tracker-width and tracker-height must be a multiple of 32, respectively
tracker-width=640
tracker-height=384
#ll-lib-file=/opt/nvidia/deepstream/deepstream-5.0/lib/libnvds_mot_iou.so
#ll-lib-file=/opt/nvidia/deepstream/deepstream-5.0/lib/libnvds_nvdcf.so
ll-lib-file=/opt/nvidia/deepstream/deepstream-5.0/lib/libnvds_mot_klt.so
#ll-config-file required for DCF/IOU only
#ll-config-file=tracker_config.yml
#ll-config-file=iou_config.txt
gpu-id=0
#enable-batch-process and enable-past-frame applicable to DCF only
enable-batch-process=1
enable-past-frame=0
display-tracking-id=1
關於tracker的選擇,在原廠網站的文件中可以找到相關資訊,圖片如下
圖片來源: https://docs.nvidia.com/metropolis/deepstream/5.0DP/plugin-manual/
第三個範例程式 (source4_1080p_dec_infer-resnet_tracker_sgie_tiled_display_int8.txt)
這個範例從檔名來分析的話是具有tracker以及sgie的額外功能,這也是唯一一個有使用到second gie的範例,我們就直接來看看配置檔的部分吧!
其實設置的方法很簡單,只需要增加 [secondary-gie%d] 這個項目,這邊導入了 VehicleTypes的引擎可以用來辨識車子的種類;gie-unique-id這邊則是從3開始,其實不要跟Primary的id衝突到應該就可以了;operate-on-gie-id表示將這個gie應用在哪一個gie上面;operate-on-class-ids可以特別選擇應用在第幾個類別的項目上,secondary可以自動進行IOU的分割並進行二次的辨識,針對這個部分我們可以設定成辨識到車子再開啟secondary辨識。
[secondary-gie0]
enable=1
model-engine-file=../../models/Secondary_VehicleTypes/resnet18.caffemodel_b16_gpu0_int8.engine
gpu-id=0
batch-size=16
gie-unique-id=4
operate-on-gie-id=1
operate-on-class-ids=0;
config-file=config_infer_secondary_vehicletypes.txt
第二個則是辨識車子的顏色
[secondary-gie1]
enable=1
model-engine-file=../../models/Secondary_CarColor/resnet18.caffemodel_b16_gpu0_int8.engine
batch-size=16
gpu-id=0
gie-unique-id=5
operate-on-gie-id=1
operate-on-class-ids=0;
config-file=config_infer_secondary_carcolor.txt
最後試辨識車子的廠牌。
[secondary-gie2]
enable=1
model-engine-file=../../models/Secondary_CarMake/resnet18.caffemodel_b16_gpu0_int8.engine
batch-size=16
gpu-id=0
gie-unique-id=6
operate-on-gie-id=1
operate-on-class-ids=0;
config-file=config_infer_secondary_carmake.txt
結論
看了三個範例之後應該大部分的參數都了解了吧!接著就可以按照自己的需求去更動了,不過目前都只是在使用他提供的模型,如果要使用自己的模型怎麼辦?在下一篇文章中我會帶大家操作使用DeepStream運行YOLOv4的方法,接著再教大家怎麼透過YOLOv4進行Transfer Learning訓練自己的數據集,最後整合在一起就完成在DeepStream上辨識自己想要辨識的東西了。最後補充怎麼在DeepStream輸出RTSP並且在Windows電腦上接收畫面。
(補充) DS輸出RTSP並在Win10上顯示
步驟如下:
1.安裝VLC : https://www.videolan.org/vlc/index.zh_TW.html
2.開啟網路串流,可以輸入快速鍵 Ctrl+N。
3.輸入網址,在DeepStream程式開起來的前幾行會提示應該怎麼輸入,基本上沒動到的話,埠號是8554,後面加上資料名稱 ds-test,按下播放即可。
4.大功告成