[AI開發]基於DeepStream的視訊結構化解決方案

周見智發表於2019-05-08

 

視訊結構化的定義

利用深度學習技術實時分析視訊中有價值的內容,並輸出結構化資料。相比資料庫中每條結構化資料記錄,視訊、圖片、音訊等屬於非結構化資料,計算機程式不能直接識別非結構化資料,因此需要先將這些資料轉換成有結構格式,用於後續計算機程式分析。視訊結構化最常見的流程為:目標檢測、目標分類(屬性識別)、目標跟蹤、目標行為分析。最後的目標行為分析嚴格來講不屬於視訊結構化的範疇,可以算作前面每個環節結果的應用。由於現實生產過程中,一個完整的應用系統總會存在“目標行為分析”這個過程(否則光得到基礎資料不能加以利用),所以本篇文章將其包含進來。

 

目標檢測

對單張圖片中感興趣的目標進行識別、定位,注意兩點,一個是檢測的物件是靜態圖片,二是不但需要識別目標的類別,還需要給出目標在原圖片中的座標值,通常以(left, top, width, height)的形式給出。注意目標檢測僅僅給出目標大概位置座標(一個矩形區域),它跟影像分割不同,後者定位更加具體,能夠給出圖片中單個目標的輪廓邊界。

 

目標分類(屬性識別)

通常目標被檢測出來之後,會進行二次(多次)推理,識別出目標更加具體的屬性,比如小轎車的顏色、車牌子奧迪還是賓士等等。對於人來講,可以二次推理出人的性別、年齡、穿著、髮型等等外貌屬性。這個環節主要對檢測出來的目標進行更加具體的屬性識別。

 

目標跟蹤

前面兩個環節操作的物件是靜態單張圖片,而視訊有時序性,前後兩幀中的目標有關聯關係。目標跟蹤就是為了將視訊第N幀中的目標和第N+1幀中的同一目標關聯起來,通常做法是給它們賦予同一個ID。經過目標跟蹤環節後,理論情況下,一個目標從進入視訊檢測範圍到離開,演算法賦予該目標的ID固定不變。但是現實生產過程中,由於各種原因,比如目標被遮擋、目標漏檢(第N幀檢測到,第N+1幀沒檢測到)、跟蹤演算法自身準確性等等原因,系統並不能鎖定視訊中同一個目標的ID。目標ID不能鎖定,會造成目標行為分析不準的問題,後面會提到。

 

目標行為分析

視訊中目標被跟蹤到,賦予唯一ID之後,我們可以記錄目標在視訊檢測範內的運動軌跡(二維座標點集合),通過分析目標軌跡點資料,我們可以做很多應用。比如目標是否跨域指定區域、目標運動方向、目標運動速度、目標是否逗留(逗留時長)、目標是否密集等等。該應用多存在於安防、交通視訊分析領域。

 

目標檢測演算法

常見基於深度學習神經網路的目標檢測演算法有3種,SSD、YOLO以及Faster-RCNN,具體請搜尋網路,介紹文章非常多了。三者各有優劣,遵循一個原則:速度快的準確性不好,很多目標檢測不準,很多小目標檢測不到、容易漏檢等;準確性好的速度不快,可能達不到實時檢測的要求,或者需要更高的硬體條件。魚和熊掌不可兼得,犧牲速度可以換來準確性。這三種常見目標檢測演算法,綜合性比較好的是YOLO(現在已經是YOLO V3版本),準確性、小目標檢測、檢測速度上都可以接受。SSD速度快,我在RTX 2080 的GPU上,能夠檢測32路1080P高清實時流,但是YOLO V3勉強可以跑到16路。Faster-RCNN準確性更好,但是速度太慢,如果你有很好的GPU硬體支援,或者單臺伺服器要求檢測視訊路數比較少,可以採用Faster-RCNN。下圖第一張是SSD演算法效果,第二張是YOLO V3的演算法效果,兩者模型都是採用同樣的資料集訓練而成,可以很明顯看到,後者比前者效果好很多(忽略圖中速度值)。

需要注意的是,不管是何種演算法,它們的檢測效果受資料集質量影響非常大,資料集數量不夠、標註質量不高,都會嚴重影響最終檢測結果。做深度學習應用型系統,資料集的重要性非常明顯。

 

視訊結構化處理流程框架

前面說到過,視訊結構化包含多個環節,各個環節相連而成,形成一個Pipeline的結構。在實際生產過程中,我們還需要有視訊流接入的環節,它負責接收視訊流資料,由於網路接收到的視訊資料是編碼過後的格式,我們還需要解碼的環節,將原始視訊資料解碼成一張張RGB格式的圖片(這之前可能還需要顏色空間轉換,將YUV格式轉換成RGB),之後將單幀圖片送給推理模型進行推理,返回推理結果。

很明顯,視訊結構化是一個資料流式的處理過程,如果對GStreamer框架比較熟悉的人可能或想到,GStreamer非常適合做這件事情。這裡是GStreamer的官網:https://gstreamer.freedesktop.org/,跟FFmpeg類似,它主要用於音視訊多媒體程式開發,但是兩個側重點不同,GStreamer中將多媒體處理流程中的每個環節都封裝成單個的外掛,每個外掛負責不同的任務,比如有接收視訊流的、有負責編解碼的、有顏色空間轉換的等等,這些常用外掛都已經有現成非常成熟的,不需要自己開發。外掛和外掛之間通過某個協議進行連線,最終形成一個完整的Pipeline。目前來看,使用FFmpeg的人明顯多餘GStreamer。在我們這個應用場景中,GStreamer非常適合我們,Nvidia官方推出的智慧視訊分析SDK DeepStream也是基於GStreamer開發而成,Nvidia為我們準備好了現成的外掛,有負責推理的,有負責目標跟蹤的,還有負責圖片疊加和顯示的。我們在使用DeepStream的同時,也可以使用GStreamer中已有的其他外掛,他們可以無縫整合,非常方便。

這裡必須要提一下,GStreamer是C語言開發的,而我們知道C語言並非物件導向,如果要用到物件導向的特性必須採取其他措施,GStreamer就是使用了GObject那一套東西,GObject又是什麼呢?它是一套在C中使用物件導向程式設計的規範。如果已經非常熟悉主流面嚮物件語言的人,再去接收GObject這種程式設計風格,會要瘋掉,反人類(我這樣覺得)。下圖是採用DeepStream SDK開發視訊結構化的Pipeline,簡單示意,並非真實生產中的結構:

 

使用DeepStream 做視訊結構化應用的好處

如果你用的推理硬體是Nvidia出的,比如Tesla系列顯示卡、Geforce系列顯示卡等等,那麼使用DeepStream SDK的好處有:

(1)內建推理加速外掛nvinfer,注意普通深度學習模型(caffe、tensorflow等)在沒有經過tensorRT加速之前,速度是上不來的。而DeepStream內建的nvinfer推理外掛不斷支援各種目標檢測演算法(SSD、YOLO、Faster-RCNN)以及各種深度學習框架模型(自由切換),內部還自帶tensorRT INT8/FP16加速功能,不需要你做額外操作;

(2)內建目標跟蹤外掛nvtracker,目前DeepStream 3.0提供兩種跟蹤演算法,一種基於IOU的,這種演算法簡單,但是快;另外一種KLT演算法,準確但是相對來講慢一些,而且由於這個演算法是跑在CPU上,基於KLT的跟蹤演算法對CPU佔用相對大一些;

(3)內建其他比較有用的外掛,比如用於視訊疊加(目標方框疊加到視訊中)的nvosd、硬體加速解碼外掛nvdec_h264,專門採用GPU加速的解碼外掛,還有其他顏色轉換的外掛。

(4)提供跟視訊處理有關的各種後設資料型別以及API,方便你擴充套件自己的後設資料型別,後設資料在GStreamer中是一個很重要的概念。

使用DeepStream SDK的前提是要先掌握GStreamer的基本用法,否則就是抓瞎,前者其實就是後者的一堆外掛集合,方便供你構建視訊推理Pipeline。當然,你還需要一些CUDA程式設計的基礎知識。

 

下面提供一個基於YOLO V3 16路1080P高清視訊實時目標檢測、跟蹤、疊加、目標行為判斷、結構化資料上報 應用系統截圖(擷取其中4路影像),由於某些原因,不再做過多的技術細節介紹了。

 

相關文章