用FFmpeg搭建基于CNN的视频分析方案
Photo by?Lukas?from?Pexels
FFmpeg作為一個集錄制、轉換、音/視頻編碼解碼功能為一體的開源框架,自然也需要考慮怎樣去和當下流行的視頻分析技術融合。本文來自英特爾網絡平臺部軟件工程師謝林在LiveVideoStack線上分享中的演講,詳細解析了如何用FFmpeg搭建基于CNN的視頻分析方案。?
文 / 謝林
整理 / LiveVideoStack
回放鏈接?
https://www2.tutormeetplus.com/v2/render/playback?mode=playback&token=279cb665e4ac4cacb95ccf5afcf00ce2
大家好,我是來自英特爾網絡平臺部VEI組的謝林。本次分享希望與大家一起探索如何用FFmpeg搭建視頻分析方案,內容主要分為以下幾個方面。
1. 自我介紹與團隊介紹
我從事軟件開發超過十一年,在嵌入式系統、多媒體等領域有豐富的開發經驗,現在也開始嘗試一些與深度學習相關的工作,主要是開發與視頻分析相關的解決方案。
?
我所在的團隊也基本專注于視頻相關的業務,主要涵蓋以上四個部分:第一部分是多媒體的使能與分發,主要就是傳統的轉碼業務;第二部分是云游戲,目前我們在Android和 Windows平臺上都有相應的解決方案;第三部分是沉浸式虛擬現實,包括360°全景攝影、VR/AR等端到端的解決方案;第四部分就是視頻分析。我們在這四大板塊都有商用化的解決方案與成熟完整的技術儲備。
?
2. OpenVINO 深度學習開發工具套件介紹
?
OpenVINO是英特爾近幾年推出的一個重要軟件產品,主要用于深度學習的開發,由Model Optimizer與Inference Engine兩個主要模塊組成。Model Optimizer的主要功能是模型的優化,包括轉換一些現有成熟的AI框架下的模型成為中間格式,再通過推理引擎把模型部署到英特爾的各種設備之上。
?
最新的OpenVINO版本又引入了Nervana的N-Graph,可以說在模型的支持方面又有了新的突破。你可以在Github上找到oepn model zoo,里面包含了許多訓練好的模型與代碼,能夠幫助快速上手,OpenVINO基于此開發了多種應用。
?
除此之外,OpenVINO也可以用來開發許多與深度學習相關的工具,例如我們現在經常用到的是將精度FP32的模型轉換成int-8,使得性能大大提升。OpenVINO中也包含許多已經成熟的視覺相關的開發套件,包括OpenCV、OpenVX,同樣也支持英特爾的MediaSDK與主要用于GPU加速的OpenCL,當然也支持FPGA開發環境。
?
OpenVINO最成功的一點就是將英特爾所有的與AI相關的軟硬件進行了整體的封裝,通過OpenVINO的推理引擎將各個設備都利用起來,從而進一步提升開發效率。
?
一個典型的音視頻處理流程,首先在流程開始時對輸入碼流解碼,然后解出來的視頻幀進行前處理,處理完畢后的數據會被傳輸至推理引擎當中進行推理,從引擎輸出的結果會再經過后處理,在此之后如果需要編碼成其它格式則進行encode工作。
?
圖中展示的是OpenVINO實際工作流程。首先,我們需要有一個訓練好的模型,可能來自TensorFlow、Caffe或者mxnet等。訓練完畢的數據通過Model Optimizer被轉換成IR格式,此時一部分文件格式為.xml,另一部分文件格式則為.bin。其中.xml文件主要包括一些網絡拓撲結構,.bin文件則包含那些參數的權重。將這兩種格式的文件同時放入推理引擎當中,文件加載后再根據用戶的設置,采用CPU、GPU、VPU等設備進行推理。
?
通過OpenVINO開發套件我們可以實現很多基于深度學習的案例,比較常見的如圖形分類、分割,物體的檢測、追蹤,人臉識別,也有一些與交通安全相關的用例,如行人、車牌識別,另外,還可以用它做一些語音識別相關的應用。但是這里存在一個問題,如果使用OpenVINO開發,需要根據特定需求寫具體的應用,沒有一個可以完全復用的框架從而高效便捷地搭建一個完整方案。由此我們產生一個想法:將FFmpeg與深度學習有機結合,讓大家使用簡單的FFmpeg命令行就能夠搭建高質量的深度學習用例。
?
3. FFmpeg與DNN模型
圖中展示的是當前FFmpeg 與DNN模型結構框架,FFmpeg包含一個DNN Interface,它由兩部分組成:DNNModel與DNNModule,可以看到,基于DNNInterface已經實現了一個超分的SR Filter,以及一個用于去雨滴功能的Derain Filter。在后端則支持TensorFlow Backend與NativeBackend。
?
舉一個實際的例子來說,其命令行如下所示:
?
ffmpeg -i derain_input.mp4 -vfderain=model=derain_RESCAN.pb:dnn_backend=1 derain_output.mp4其中.mp4文件作為輸入被解碼,解碼出的視頻幀首先會被送到Derain Filter,對于Derain Filter指定了參數dnn_backend,如果dnn_backend=1則會選用TensorFlow來做Backend,另外一個參數model對應的是指定模型文件的路徑。輸出后的數據被編碼打包成.mp4文件,整個流程邏輯清晰,使用起來與其它濾鏡相比也沒有太大差別。但就功能來說還較為單一,要想實現復雜應用如人臉識別、物體跟蹤與檢測等則較為困難。我們曾嘗試在當前框架下進一步擴展,但是我們發現現有的DNN Interface還不夠完整,目前還在繼續完善與更新中,而且如果完全按照現有結構去實現一些較為復雜的用例,其性能表現并不出色。
?
4. FFmpeg與OpenVINO IE Integration
?
因此我們自主研發了一套全新的架構,如上圖所示:我們定義了一個Image Inference Backend模塊,其與DNNInterface相互獨立。這里我們利用了英特爾的OpenVINO推理引擎并將其作為一個Backend。通過推理引擎的CAPI,利用各種硬件設備實現推理加速。
?
上圖列出了比較重要的兩個Filter:檢測與分類,可以通過ffmpeg命令行直接使用這些filter。相較于之前的DNN Interface,該架構擁有諸多新特性:首先該模型可部署到多種硬件設備平臺,支持異步工作模式以及多個推理請求并行處理。其次,該模型支持Batch mode,可以一次送多個frame進行inference。此外,該模型也支持隔幀處理,支持不需要每一幀都去inference的情形。
?
5. FFmpeg Video Analytics PluginsList
圖中展示的是具體實現中的plugin,在FFmpegFilter方面我們實現了Detection、Classification與identification也就是檢測、分類與識別。除此之外,還實現了Metadata Conversion,也就是將推理以后一些數據存儲到FFmpeg的AVFrame SideData當中。
?
另外我們也實現了兩個muxer,一個是可將這些Metadata進行發布,或者存儲成一些文件。同時也支持Kafka協議進行分發,創建一個Kafka的Broker并發送到Kafka的遠端服務器上。
?
6. FFmpeg視頻分析案例
?
由上圖所示,我們可以看到其中采用了我們實現的一些Filter以及Muxer:解碼后系統獲得視頻幀,隨后進入第一個Filter:Detect Filter,Detect Filter中第一項流程是預處理(包含顏色空間的轉換與縮放)。大家知道深度學習的模型,其輸入的數據與frame的layout不一樣,因此這里的格式轉換十分必要。目前大多只能接受RGB作為輸入,同時模型對輸入的尺寸也有固定要求,因此這里需要一個尺寸重新調整的過程。
?
預處理后的流程是Inference,利用OpenVINO推理引擎。在此之后,由于我們需要明確Detect Filter輸出數據的含義,數據經過Detect Filter后還要進行后處理。后處理將輸出結果轉換成一些預先定義好的數據結構,這些結果與原始的Video幀一起,被存儲在 Detect Side Data當中,送至下一個Classify Filter(分類濾鏡)。其工作流程與之前的Filter差不多,唯一的差別是Classify Filter會根據前面檢測出的結果獲取一些ROI,并對這些ROI進行crop處理,取出所需一塊之后再去做Scale與CSC。ClassifyFilter處理完成的數據會被存儲在Classify Side Data里,并與原始視頻一起送往下一個單元,在這里可以選擇分發,也可以用overlay的方式呈現原始圖像。
?
如果使用ffmpeg命令行加上我們新實現的component,該怎么去做呢?
?
?
具體實踐如上圖所示,其中的高亮表示關鍵元素。前面的部分主要是指定一個輸入,而后面對于Filter的描述則非常多,大致可以看到其中包含了4個Filter。經過detect的數據會被送至下一步classify,這里有可能做另外的分類。分類過后則是metadata的轉換,最后通過metapublish分發出去。
?
我們再來看看其中的一些參數,例如有參數用來指定檢測模型的檢測路徑,還有一個參數被稱為model_proc,主要用于告知模型前處理與后處理的一些基本信息,這是一個Json格式的script。nireq參數可以告訴我們同時有多少推理請求正在工作,device參數可以告訴我們這個模型需要部署到哪一個硬件設備上,其他的classify參數與detect的基本一致。
?
metapublish參數則是告訴我們數據需要被轉化成什么輸出格式,現在我們支持用json格式來輸出,最后通過一個kafka協議的url發送至kafka的遠程服務器。
?
?
上圖就是我們在GitHub上的主頁(https://github.com/VCDP/FFmpeg-patch),包括具體的實現和一些教程,wiki里有教大家如何一步步搭建這樣一個視頻分析方案,歡迎大家前訪問并提寶貴建議。這個repo并不是一個完整的FFmpeg source code。因為FFmpeg的架構無法將一個完全獨立的工程作為一個插件。我們只是把現有的實現按照patch的方式來發布,而這些patch都是以FFmpeg 4.2 release作為基礎。在實際過程中,首先需要下載FFmpeg4.2源代碼,再安裝一些可能需要依賴的三方庫,然后編譯整個FFmpeg工程,就可以通過ffmpeg命令行使用我們設計的這些Filter與Muxer。
?
?
在開發的過程之中,我們發現FFmpeg可能存在一些不足。例如每個Filter不能單獨運行在一個線程上,并且不能實現多個frame分發到不同線程,這對效率有比較嚴重的制約。另外目前的Filter chain是串行工作的模式,不能夠做并行處理,這也會降低整體效率。
?
深度學習當中輸入輸出的格式與傳統音視頻輸入輸出的格式不同,目前FFmpeg當中也沒有合適的數據結構或者一些預置定義好的接口用于支持DL Tensor,為此我們自定義了一些數據結構。Libavfilter當初設計的目標主要是針對一些輕量級的處理,并未考慮引入像深度學習這樣復雜繁重的功能。如果我們不想被限制在Libavfilter這個框架下,也可以考慮重新設計一套框架來更好地支持深度學習。
點擊【閱讀原文】訪問購票頁面
總結
以上是生活随笔為你收集整理的用FFmpeg搭建基于CNN的视频分析方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 金山“云”上音乐节 —— 一文带你看懂如
- 下一篇: SVT-AV1:开源编解码最新进展