Qt編寫安防視訊監控系統39-onvif圖片引數

語言: CN / TW / HK

一、前言

通過onvif來調整圖片的Brightness(亮度)、ColorSaturation(色彩飽和度)、Contrast(飽和度)這三個引數,可以實時觀測到監控畫面對應的變化,比如講亮度Brightness拉到最低,可以看到這個畫面一片漆黑。通過onvif來調節圖片的顏色光線,就無須通過廠家私有SDK去調節,當然廠家SDK能夠去調節的引數肯定更多更全更好速度更快,這個功能用到的地方不多,大部分的時候其實還是安裝除錯期間,直接在前端攝像機的網頁配置介面或者客戶端介面上調整好,一般調整好以後基本上不會再去改動,尤其是經過驗收的專案,經過專家的建議調整後固定在那個引數就行。

通過協議去調整圖片引數後,相當於在前端就更改了視訊源的圖片引數,有時候的一種場景是不希望修改掉前端的影象引數,而是拿到視訊圖片後本地處理掉,按照自己的規則本地調整好展示,因為前端攝像機可能好幾個地方在拉流,你這邊修改了,其他地方也看到,但是未必就是其他地方希望的效果,可能不同軟體或者不同的使用者有自己特定的需求,還有一種情況是有些攝像機廠家的裝置不支援onvif調節。終極萬能辦法就是拿到圖片後本地自己通過程式碼來去調整顏色值等,這個目前沒有實現,如果直接拿到QImage那很方便通過調整RGB顏色值做演算法運算來改變,效率低一些就是,如果是通過ffmpeg直接拿到的yuv資料給opengl繪製,這就需要用濾鏡AVFilter裡面的玩意去處理,這塊有空了再詳細研究。

onvif主要的功能

  1. 搜尋裝置,獲取裝置的資訊比如廠家、型號等。
  2. 獲取裝置的多個配置檔案資訊profile。
  3. 獲取對應配置檔案的視訊流地址rtsp,以及解析度等引數。
  4. 雲臺控制,上下左右移動,焦距放大縮小,相對和絕對移動。
  5. 獲取預置位資訊,觸發預置位。
  6. 訂閱事件,接收裝置的各種訊息尤其是報警事件比如IO口的報警。
  7. 抓圖,獲取裝置當前的圖片。
  8. 獲取、建立、刪除使用者資訊。
  9. 獲取和裝置網路配置資訊比如IP地址等。
  10. 獲取和設定NTP時間同步。
  11. 獲取和設定裝置時間。
  12. 重啟裝置。

onvif的處理流程

  1. 繫結組播IP(239.255.255.250)和埠(3702),傳送固定的xml格式的資料搜尋裝置。
  2. 接收到的xml格式的資料解析,得到裝置的Onvif地址。
  3. 對Onvif地址傳送對應的資料,收到資料取出對應的節點資料。
  4. 請求Onvif地址獲取Media地址和Ptz地址,Media地址用來獲取詳細的配置檔案,Ptz地址用來雲臺控制。
  5. ptz控制是對Ptz地址傳送對應的資料即可。
  6. 設定了使用者認證的需要組織使用者token資訊一塊傳送,每次都需要作鑑權處理。
  7. 接收到的資料不是標準的xml資料,沒法按照正常的節點解析來處理,只能用QXmlQuery來做。
  8. 每個廠家裝置返回的資料未必完全一致,基本上都不一致,需要進行模糊查詢節點值。
  9. 特意採用底層協議解析,因為soap太臃腫函式名稱太另類,特意做的輕量級的。
  10. 兩個必備工具,Onvif Device Manager 和 Onvif Device Test Tool。

二、功能特點

(一)軟體模組

  1. 視訊監控模組,各種停靠小窗體子模組,包括裝置列表、圖文警情、視窗資訊、雲臺控制、預置位、巡航設定、裝置控制、懸浮地圖、網頁瀏覽等。
  2. 視訊回放模組,包括本地回放、遠端回放、裝置播放、圖片回放、視訊上傳等。
  3. 電子地圖模組,包括圖片地圖、線上地圖、離線地圖、路徑規劃等。
  4. 日誌查詢模組,包括本地日誌、裝置日誌等。
  5. 系統設定模組,包括系統設定(基本設定、視訊引數、資料庫設定、地圖配置、串列埠配置等)、錄影機管理、攝像機管理、輪詢配置、使用者管理等。

(二)基礎功能

  1. 支援各種視訊流(rtsp、rtmp、http等)、視訊檔案(mp4、rmvb、avi等)、本地USB攝像機播放。
  2. 支援多畫面切換,包括1、4、6、8、9、13、16、25、36、64畫面切換。
  3. 支援全屏切換,多種切換方式包括滑鼠右鍵選單、工具欄按鈕、快捷鍵(alt+enter全屏,esc退出全屏)。
  4. 支援視訊輪詢,包括1、4、9、16畫面輪詢,可設定輪詢分組(輪詢預案)、輪詢間隔、碼流型別等。
  5. 支援onvif協議,包括裝置搜尋、雲臺控制、裝置控制(圖片引數、校對時間、系統重啟,抓拍圖片等)。
  6. 支援許可權管理,不同的使用者可以對應不同的模組許可權,比如刪除日誌、關閉系統等。
  7. 資料庫支援多種,包括sqlite、mysql、sqlserver、postgresql、oracle、人大金倉等。
  8. 本地USB攝像機支援設定解析度、幀率等引數。
  9. 所有停靠模組都自動生成對應的選單用來控制顯示和隱藏,在標題欄右鍵可以彈出。
  10. 支援顯示所有模組、隱藏所有模組、復位普通佈局、復位全屏佈局。
  11. 雙擊裝置彈出實時預覽視訊,支援圖片地圖、線上地圖、離線地圖等。
  12. 攝像機節點拖曳到對應窗體播放視訊,同時支援拖曳本地檔案直接播放。
  13. 刪除視訊支援滑鼠右鍵刪除、懸浮條關閉刪除、拖曳到視訊監控面板外刪除等多種方式。
  14. 圖片地圖上裝置按鈕可自由拖動,自動儲存位置資訊。百度地圖上可以滑鼠單擊獲取經緯度資訊,用來更新裝置位置。
  15. 視訊監控面板窗體中任意通道支援拖曳交換,瞬間響應。
  16. 封裝了百度地圖,檢視切換,運動軌跡,裝置點位,滑鼠按下獲取經緯度等。
  17. 雙擊節點、拖曳節點、拖曳窗體交換位置等操作,均自動更新儲存最後的播放地址,下次軟體開啟自動應用。
  18. 右下角音量條控制元件,失去焦點自動隱藏,音量條帶靜音圖示。
  19. 支援視訊截圖,可指定單個或者對所有通道截圖,底部小工具欄也有截圖按鈕。
  20. 支援超時自動隱藏滑鼠指標、自動全屏機制。
  21. 支援onvif雲臺控制,可上下左右移動雲臺攝像機,包括復位和焦距調整等。
  22. 支援任意onvif攝像機,包括但不限於海康、大華、宇視、天地偉業、華為等。
  23. 可儲存視訊,可選定時儲存或者單檔案儲存,可選儲存間隔時間。
  24. 可設定視訊流通訊方式tcp+udp,可設定視訊解碼是速度優先、質量優先、均衡等。
  25. 可設定軟體中文名稱、英文名稱、LOGO圖示等。
  26. 儲存的視訊檔案支援匯出到指定目錄,支援批量上傳到伺服器。

(三)特色功能

  1. 主介面採用停靠窗體模式,各種元件以小模組的形式加入,可自定義任意模組加入。
  2. 停靠模組可拖動任意位置嵌入和懸浮,支援最大化全屏,支援多螢幕。
  3. 雙重佈局檔案儲存機制,正常模式、全屏模式都對應不同的佈局方案,自動切換和儲存,比如全屏模式可以突出幾個模組透明顯示在指定位置,更具科幻感現代化。
  4. 原創onvif協議機制,採用底層協議解析(udp廣播搜尋+http請求執行命令)更輕量易懂易學習拓展,不依賴任何第三方元件比如gsoap。
  5. 原創資料匯入匯出機制,跨平臺不依賴任何元件,瞬間匯出資料。
  6. 內建多個原創元件,宇宙超值超級牛逼,包括資料匯入匯出元件(匯出到xls、pdf、列印)、資料庫元件(資料庫管理執行緒、自動清理資料執行緒、萬能分頁、資料請求等)、地圖元件、視訊監控元件、檔案多執行緒收發元件、onvif通訊元件、通用瀏覽器核心元件等。
  7. 自定義資訊框+錯誤框+詢問框+右下角提示框(包含多種格式)等。
  8. 精美換膚,高達17套面板樣式隨意更換,所有樣式全部統一,包括選單等。
  9. 視訊控制元件懸浮條可以自行增加多個按鈕,監控介面底部小工具欄也可自行增加按鈕。
  10. 雙擊攝像機節點自動播放視訊,雙擊節點自動依次新增視訊,會自動跳到下一個,雙擊父節點自動新增該節點下的所有視訊。可選主碼流、子碼流。
  11. 錄影機管理、攝像機管理,可新增刪除修改匯入匯出列印資訊,立即應用新的裝置資訊生成樹狀列表,不需重啟。
  12. 可選多種核心自由切換,ffmpeg、vlc、mpv等,均可在pro中設定。推薦用ffmpeg,跨平臺最多,預設提供好了linux和mac平臺上編譯好的庫。
  13. 支援硬解碼,可設定硬解碼型別(qsv、dxva2、d3d11va等)。
  14. 預設採用opengl繪製視訊,超低的CPU資源佔用,支援yuyv和nv12兩種格式繪製,很牛逼。
  15. 高度可定製化,使用者可以很方便的在此基礎上衍生自己的功能,比如增加自定義模組,增加執行模式、機器人監控、無人機監控、挖掘機監控等。
  16. 支援xp、win7、win10、linux、mac、各種國產系統(UOS、中標麒麟、銀河麒麟等)、嵌入式linux等系統。
  17. 註釋完整,專案結構清晰,超級詳細完整的使用開發手冊,精確到每個程式碼檔案的功能說明,不斷持續迭代版本。

三、體驗地址

  1. 體驗地址:https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g 提取碼:01jf 檔名:bin_video_system.zip。
  2. 國內站點:https://gitee.com/feiyangqingyun
  3. 國際站點:https://github.com/feiyangqingyun
  4. 個人主頁:https://blog.csdn.net/feiyangqingyun
  5. 知乎主頁:https://www.zhihu.com/people/feiyangqingyun/
  6. 線上文件:https://feiyangqingyun.gitee.io/qwidgetdemo/video_system.html

四、效果圖

五、核心程式碼

QString OnvifOther::getVideoSource()
{
    QString result = writeData("    <trt:GetVideoSources/>", "", "獲取視訊引數", false, false, 1);
    QStringList list = result.split(OnvifResultSplit);
    QString videosource = list.first().split(":").last();
    device->videoSource = videosource;
    return result;
}

QString OnvifOther::getImageSetting(int &brightness, int &colorSaturation, int &contrast)
{
    brightness = colorSaturation = contrast = 0;
    QString wsdl = "http://www.onvif.org/ver20/imaging/wsdl";

    QStringList list;
    list << QString("    <GetImagingSettings xmlns=\"%1\">").arg(wsdl);
    list << QString("      <VideoSourceToken>%1</VideoSourceToken>").arg(device->videoSource);
    list << QString("    </GetImagingSettings>");

    QString result = writeData(list.join("\r\n"), "Brightness|ColorSaturation|Contrast", "獲取圖片引數", false);
    list = result.split(OnvifResultSplit);
    if (list.count() != 3) {
        return result;
    }

    brightness = list.at(0).split(":").last().toInt();
    colorSaturation = list.at(1).split(":").last().toInt();
    contrast = list.at(2).split(":").last().toInt();
    return result;
}

bool OnvifOther::setImageSetting(int brightness, int colorSaturation, int contrast)
{
    QString wsdl = "http://www.onvif.org/ver20/imaging/wsdl";
    QString schema = "http://www.onvif.org/ver10/schema";

    QStringList list;
    list << QString("    <SetImagingSettings xmlns=\"%1\">").arg(wsdl);
    list << QString("      <VideoSourceToken>%1</VideoSourceToken>").arg(device->videoSource);
    list << QString("      <ImagingSettings>");
    list << QString("        <Brightness  xmlns=\"%1\">%2</Brightness>").arg(schema).arg(brightness);
    list << QString("        <ColorSaturation  xmlns=\"%1\">%2</ColorSaturation>").arg(schema).arg(colorSaturation);
    list << QString("        <Contrast  xmlns=\"%1\">%2</Contrast>").arg(schema).arg(contrast);
    list << QString("      </ImagingSettings>");
    list << QString("      <ForcePersistence>true</ForcePersistence>");
    list << QString("    </SetImagingSettings>");

    QString result = writeData(list.join("\r\n"), "SetImagingSettingsResponse", "設定圖片引數", false);
    return result.contains("SetImagingSettingsResponse");
}