VideoPipe可視化視頻結構化框架開源了!

完成多路視頻並行接入、解碼、多級推理、結構化數據分析、上報、編碼推流等過程,插件式/pipe式編程風格,功能上類似英偉達的deepstream和華爲的mxvision,但底層核心不依賴複雜難懂的gstreamer框架(少部分地方需要),框架主幹部分主要使用原生C++ STL實現,目標是平臺高可移植性。框架可用於:視頻結構化、以圖搜圖、目標行爲分析等應用領域。

 

源碼地址:https://github.com/sherlockchou86/video_pipe_c

主要功能

  • 視頻接入,支持file/rtsp/udp/rtmp等主流視頻流協議;
  • 多級推理,自帶檢測/分類/特徵提取等推理插件。默認使用opencv.dnn實現,可基於其他類似tensorrt、甚至原生的pytorch/tensorflow擴展新的推理插件;
  • 目標跟蹤,自帶基於iou的跟蹤插件,可基於其他算法擴展新的跟蹤插件;
  • 行爲分析,自帶若干行爲分析插件,比如目標跨線、擁堵/目標聚集判斷;
  • 圖像疊加,結構化數據和視頻融合顯示;
  • 消息推送,自帶基於kafka的消息推送插件,可基於其他消息中間件擴展新的插件;
  • 錄像/截圖,自帶截圖/錄像插件;
  • 編碼輸出,支持file/screen/rtmp/rtsp等主流方式輸出編碼結果;

主要特點

  • 可視化調試,自帶pipe可視化功能,可在界面實時顯示pipe的運行狀態,如pipe中各個環節的fps/緩存隊列大小,以及計算pipe起/止插件之間的時間延時,幫助程序員快速定位性能瓶頸位置;
  • 插件與插件之間默認採用“smart pointer”傳遞數據,數據從頭到尾,只需創建一次,不存在拷貝操作。當然,可根據需要設置“深拷貝”方式在插件之間傳遞數據;
  • pipe中各通道視頻的fps、分辨率、編碼方式、來源均可不同,並且可單獨暫停某一通道;
  • pipe中可傳遞的數據只有兩種,一種frame_meta數據、一種control_meta數據,結構清晰明瞭;
  • 插件組合方式自由,在滿足客觀邏輯的前提下,可合併、可拆分,根據需要設計不同的pipe結構。同時自帶pipe結構檢查功能,識別出不合規的pipe結構;
  • pipe支持各種hook,外部通過hook可以實時獲取pipe的運行情況(第1點就是基於該特性實現);
  • 支持一個Pipe處理多路視頻(多路共用一個推理模型,Pipe分支涉及到merge和split操作),批處理提速;也支持一個Pipe只處理一路視頻(各路使用自己的推理模型,Pipe呈直線狀、多個Pipe並存),基於不同視頻做不同的推理任務;
  • 基於指定基類,所有自帶插件全部可自定義重新實現;
  • 框架主幹代碼完全基於原生C++ STL實現,跨平臺編譯部署簡單。

目前進度

開發環境:vs code/ubuntu 18.04/C++17/opencv 4.6/ffmpeg 3.4.8/gstreamer 1.20。之前使用wsl1/2+ubuntu22.04,但是wsl坑太多,後放棄。

  • 2022/9/30:完成基於tensorrt的檢測插件(一級推理和二級推理),非默認的opencv::dnn。源碼上線
  • 2022/9/15:完成基於paddle的ocr文字識別相關插件,基於paddle推理庫(非默認的opencv::dnn)
  • 2022/9/1:完成基於yunet/sface的人臉檢測、識別以及顯示相關插件開發,實現多pipe並行運行的機制,多個pipe可加載不同模型、基於不同視頻完成不同的推理任務。(單個pipe接入多路視頻、共用相同的模型之前已實現)
  • 2022/8/15:完成openpose肢體檢測器相關插件開發,完成圖像二級分類插件開發。
  • 2022/8/5:完成infer相關基類、yolo檢測器派生類的實現,走通整個一級推理流程,rtmp/screen 2種輸出。
  • 2022/7/22:已完成主幹框架開發,預估佔總體進度的1/3。等基本完成後開源,有興趣的朋友可以關注。

 

如何使用

#include "VP.h"

#include "../nodes/vp_file_src_node.h"
#include "../nodes/infers/vp_trt_vehicle_detector.h"
#include "../nodes/infers/vp_trt_vehicle_plate_detector.h"
#include "../nodes/osd/vp_osd_node_v2.h"
#include "../nodes/vp_screen_des_node.h"
#include "../nodes/vp_rtmp_des_node.h"
#include "../utils/analysis_board/vp_analysis_board.h"

#if MAIN
int main() {
    // create nodes
    auto file_src_0 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, "./test_video/13.mp4");
    auto trt_vehicle_detector = std::make_shared<vp_nodes::vp_trt_vehicle_detector>("vehicle_detector", "./vehicle.trt");
    auto trt_vehicle_plate_detector = std::make_shared<vp_nodes::vp_trt_vehicle_plate_detector>("vehicle_plate_detector", "./det.trt", "./rec.trt");
    auto osd_0 = std::make_shared<vp_nodes::vp_osd_node_v2>("osd_0", "./font/NotoSansCJKsc-Medium.otf");
    auto screen_des_0 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_0", 0, true, vp_objects::vp_size{640, 360});
    auto rtmp_des_0 = std::make_shared<vp_nodes::vp_rtmp_des_node>("rtmp_des_0", 0, "rtmp://192.168.77.105/live/10000", vp_objects::vp_size{1280, 720});

    // construct pipeline
    trt_vehicle_detector->attach_to({file_src_0});
    trt_vehicle_plate_detector->attach_to({trt_vehicle_detector});
    osd_0->attach_to({trt_vehicle_plate_detector});

    // split into 2 sub branches automatically
    screen_des_0->attach_to({osd_0});
    rtmp_des_0->attach_to({osd_0});

    // start pipeline
    file_src_0->start();

    // visualize pipeline for debug
    vp_utils::vp_analysis_board board({file_src_0});
    board.display();
}
#endif

 

上面代碼可以生成3個畫面:

  • pipeline運行圖(window顯示)
  • 屏幕顯示結果(window顯示)
  • rtmp顯示結果(video player播放)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章