「視頻結(jié)構(gòu)化」是一種 AI 落地的工程化實現(xiàn),目的是把 AI 模型推理流程能夠一般化。它輸入視頻,輸出結(jié)構(gòu)化數(shù)據(jù),將結(jié)果給到業(yè)務(wù)系統(tǒng)去形成某些行業(yè)的解決方案。
換個角度,如果你想用攝像頭來實現(xiàn)某些智能化監(jiān)控、預(yù)警等,那么「視頻結(jié)構(gòu)化」可能就是你要用到的技術(shù)方案。
不過,也不一定需要自己去實現(xiàn),因為各個芯片廠商可能都提供了類似的流程框架:
以上個人沒用過,簡單看了下,都受限于只能用廠商自家的芯片。個人經(jīng)驗來說,一般硬件還是需要多家可選的,自己實現(xiàn)一套「視頻結(jié)構(gòu)化」還是有必要的。
本文將介紹「視頻結(jié)構(gòu)化」的實現(xiàn)思路、技術(shù)架構(gòu),以及衍生的一些工作。
實現(xiàn)思路
有一個 AI 模型與一段視頻,如何進(jìn)行推理呢?
- 視頻流:OpenCV 打開視頻流,獲取圖像幀
- 前處理:圖像 Resize 成模型輸入的 Shape
- 模型推理:AI 框架進(jìn)行模型推理,得到輸出
- 后處理:將輸出處理成期望的信息
- 例如,目標(biāo)檢測:解析框的位置和類別,再 NMS 篩選
以上是最基礎(chǔ)的推理流程,完成得不錯??
簡單任務(wù),這樣滿足要求就行。但實際任務(wù),可能:
- 輸入
- 任務(wù)接收
- 視頻流
- 相機(jī)選型
- 視頻來源: 錄制視頻、RTSP 實時流
- 幀率控制: 一般 5 fps,減少計算
- 多路并發(fā): 多路視頻,并行分析
- 硬件解碼
- 推理
- 前處理
- 輸入調(diào)整: 縮放、轉(zhuǎn)置
- Batch 合并
- 硬件加速
- 模型推理
- 硬件選型: Nvidia、華為昇騰、或其他
- 模型處理: 裁剪、轉(zhuǎn)換、量化
- 模型編排: 多任務(wù)多模型,有先后關(guān)系
- 后處理
- 輸出解析: 推理結(jié)果,變?yōu)榻Y(jié)構(gòu)化數(shù)據(jù)
- 硬件加速
- 前處理
- 輸出
- 結(jié)果推送
- 其他
- 視頻存儲,License
- 鏈路追蹤,耗時分析
以上流程一般稱為「視頻結(jié)構(gòu)化」:輸入多路視頻,進(jìn)行實時分析,最后輸出結(jié)構(gòu)化數(shù)據(jù),給到業(yè)務(wù)系統(tǒng)。
該流程,這里把它分為了輸入、推理、輸出,都是一個個任務(wù)節(jié)點,整體采用 Pipeline 方式來編排 AI 推理任務(wù)。輸入輸出時,一般會用 RPC 或消息隊列來與業(yè)務(wù)系統(tǒng)通信。
整體架構(gòu)
「視頻結(jié)構(gòu)化」整體架構(gòu),如下:

管道節(jié)點
管道 Pipeline 這塊是主要部分,其實現(xiàn)都是一個個節(jié)點:
- IN
- 任務(wù)接收;視頻流解碼;幀率控制
- 推理
- 推理引擎做模型推理,結(jié)果進(jìn)結(jié)構(gòu)化數(shù)據(jù);依編排往后繼續(xù)
- 追蹤
- 追蹤依賴推理出的特征;業(yè)務(wù)不需要,就不編排
- OUT
- 結(jié)果推送;要預(yù)覽播放的話,進(jìn)行視頻流編碼
節(jié)點就是個生產(chǎn)消費者,用個阻塞隊列很快就能實現(xiàn)。節(jié)點間組成一個樹,也就是任務(wù)編排的結(jié)果。節(jié)點會有輸入輸出差異,要約定清楚或分幾個類型。
節(jié)點流程:消息隊列有任務(wù),取出執(zhí)行,結(jié)果進(jìn)結(jié)構(gòu)化數(shù)據(jù),最后發(fā)給下一節(jié)點的消息隊列。
節(jié)點的線程數(shù)、隊列上限,都可做配置。依據(jù)耗時分析,可以優(yōu)化調(diào)整。
GStreamer 的 pipeline + plugin 的技術(shù)架構(gòu)值得學(xué)習(xí)。個人沒深入了解,所以不好具體評價,倒見過在輸入做插件化解碼。NVIDIA DeepStream 直接就基于 GStreamer 開發(fā)的。
結(jié)構(gòu)數(shù)據(jù)
結(jié)構(gòu)化數(shù)據(jù),在整個 Pipeline 里是不斷追加完善的過程,最后輸出時一般 JSON 化推送。
它的內(nèi)容約定,是最主要的。會有:
- 基礎(chǔ)信息: task, frame 等信息
- 推理結(jié)果: 會以任務(wù)分類進(jìn)行標(biāo)簽
它會用作節(jié)點的輸入,例如獲取人臉特征,依賴前一目標(biāo)檢測節(jié)點的人臉 boxes 信息。
基礎(chǔ)模塊
- 全局配置
- 通用配置、節(jié)點配置與編排;可視化編排,實際就是編輯它
- 一般 JSON 格式,結(jié)構(gòu)化數(shù)據(jù)最后也 JSON 化
- 進(jìn)程?;?
- Supervisor 不錯,可以把終端日志配置進(jìn)文件
- 消息通信
- 與外部系統(tǒng),用 RPC 或 Redis,也可能推送 Kafka
- 內(nèi)部用自己的消息隊列
- 內(nèi)存共享
- 用在圖像幀,以免拷貝,幀 ID 標(biāo)識
- 顯存也預(yù)申請,隊列分配,減少 Host & Device 拷貝
技術(shù)選型
「視頻結(jié)構(gòu)化」用 C++ 實現(xiàn),主要以下幾點:
- FFmpeg 編解碼(CPU)
- OpenCV 前后處理(CPU)
- 芯片生態(tài)庫,硬件加速:編解碼與前后處理
- 如 Nvidia: video codec, npp, nvjpeg; 昇騰 dvpp 等
- 基礎(chǔ)庫,選擇主流的就好,如:
- Log:gabime/spdlog, google/glog
- JSON: nlohmann/json
- RPC: grpc/grpc, apache/incubator-brpc
更詳細(xì)的技術(shù)棧,可見該分享:https://zhuanlan.zhihu.com/p/362711954 ,思維導(dǎo)圖很詳細(xì)。
「視頻結(jié)構(gòu)化」實現(xiàn)有些要看自己的權(quán)衡:
- 一個項目怎么支持多個硬件?
- 編譯自動區(qū)分環(huán)境,編譯不同代碼,最終會產(chǎn)生多套部署
- 需要抽象推理、前后處理等硬件相關(guān)功能
- 也可以考慮插件實現(xiàn),管理好插件配置
- 編譯自動區(qū)分環(huán)境,編譯不同代碼,最終會產(chǎn)生多套部署
- 視頻流要不要用流媒體框架?
- 簡單點直接 FFmpeg,不引入 GStreamer
- 圖像與結(jié)果怎么優(yōu)化同步?
- 只是圖像顯示,存儲提供鏈接進(jìn)結(jié)果(注意 IO 瓶頸)
- 本身視頻顯示,直接繪制結(jié)果進(jìn)圖像,編碼進(jìn)流
- 或預(yù)覽端自己實現(xiàn),流數(shù)據(jù)包攜帶結(jié)果
衍生工作
「視頻結(jié)構(gòu)化」會有一些衍生的工作:庫、工具或系統(tǒng)。
首先,模型一般自定義格式,一是保護(hù),二是方便自己使用。所以,會把原模型及其配置封裝進(jìn)自定義格式,還會標(biāo)明推理方式、前后處理選擇等。
這里會有如下兩個部分:
- 模型轉(zhuǎn)換工具鏈: 不同硬件模型轉(zhuǎn)換后,再封裝進(jìn)自己格式
- 模型推理引擎: 模型解封裝,再依配置進(jìn)行推理,出結(jié)果
模型可能還要裁剪、量化,也是工作的一部分。
其次,任務(wù)情況、JSON 配置、日志等,成熟一點,還會提供管理后臺方便使用。
此外,還可能有:
- License: 生成、校驗相關(guān)工具,及管理記錄
- 除了有效期,還可以考慮限制路數(shù)、任務(wù)等
- 實時監(jiān)控: 硬件狀態(tài)監(jiān)控、預(yù)警
結(jié)語
「視頻結(jié)構(gòu)化」只是 AI 落地的一部分,實際做方案一是對接算法模型、二是對接業(yè)務(wù)系統(tǒng),還可能要去適配新的攝像頭或硬件平臺。
也就是會有兩種支持列表:硬件列表、模型列表。這就是積累的成果了。
「視頻結(jié)構(gòu)化」會部署成中心服務(wù)器,或邊緣計算。不過,只是簡單任務(wù),現(xiàn)在可能智能攝像頭就夠了,都帶邊緣計算識別人臉什么的。
GoCoding 個人實踐的經(jīng)驗分享,可關(guān)注公眾號!