- 操作系統:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 編程語言:C++11
G-API背后的動機
G-API模塊為OpenCV帶來了基于圖的執行模型。本章簡要描述了這種新模型如何在兩個方面幫助軟件開發者:優化和移植圖像處理算法。
使用Graph API進行優化
傳統上,OpenCV提供了大量的獨立圖像處理函數(參見core和imgproc模塊)。許多函數都經過了良好的優化(例如,針對特定CPU進行了向量化、并行化等),但是開箱即用的優化范圍僅限于單個函數——構建在這些函數之上的整個算法的優化是程序員的責任。
OpenCV 3.0引入了透明API(或T-API),它允許透明地將OpenCV函數調用卸載到OpenCL設備,并通過cv::UMat減少主機/設備數據傳輸——這是向前邁出的一大步。然而,T-API是一個動態API——用戶代碼仍然不受約束,OpenCL內核以任意順序排隊,因此消除了進一步的流水線級別優化潛力。
G-API為OpenCV 4.0帶來了隱式的圖模型。圖模型捕獲流水線中的所有操作及其數據依賴關系,從而為G-API框架提供了額外的信息來進行流水線級別的優化。
基于圖的優化的核心是分塊(Tiling)。分塊允許將處理分解為較小的部分并重新組織操作以啟用數據并行性、改善數據局部性并節省內存占用。由于現代計算機架構中內存訪問的不同成本,數據局部性是軟件優化的一個特別重要的方面——在第一級緩存中重用的數據越多,流水線就越高效。
當然,上述技術可以手動應用——但這需要額外的技能和對目標平臺的了解,且算法實現會變得不可逆地更加具體、靈活性降低、更難擴展和維護。
G-API從用戶那里接手了這一責任和復雜性,并自行完成了大部分工作,保持算法代碼免受設備或優化細節的影響。然而,這種方法也有其自身的局限性,因為圖模型是一種受限模型,并非每個算法都可以表示為圖,所以G-API的范圍僅限于常規圖像處理——各種濾鏡、算術運算、二進制操作以及定義明確的幾何變換。
使用Graph API進行移植
G-API的本質在于聲明一系列要運行的操作,然后執行該序列。G-API是一個受限的API,因此它對哪些操作可以形成一個流水線以及這些操作之間可以交換哪些數據施加了一些限制。
實際上,這種形式化有助于使算法具有可移植性。G-API清晰地分離了操作接口與其實現。
一個操作(內核)可能有多個實現,甚至在同一設備上(例如,基于OpenCV的“參考”實現和分塊優化的實現,兩者都在CPU上運行)。在G-API術語中,圖(或計算)僅使用操作接口構建,而不是使用實現——因此相同的圖可以在不同的設備上執行(當然,也可以使用不同的優化技術),而幾乎不需要改變圖本身。
G-API支持插件(后端),這些插件聚集了關于在特定平臺上最佳執行方式的邏輯和智能。一旦使用G-API構建了一個流水線,就可以參數化以使用其中任何一種后端(或它們的組合),從而使圖能夠輕松移植到新平臺。