![]() |
OpenCV 4.12.0
開源計算機視覺
|
G-API 是一個異構框架,提供了一個統一的 API 來程式設計具有多個支援後端的影像處理流水線。
關鍵的設計思想是保持流水線程式碼本身與平臺無關,同時在圖編譯(配置)時使用額外的引數指定要使用的核心以及要使用的裝置。 這個要求導致了以下架構
此架構中有三層
API 層是使用者在定義和使用流水線(G-API 術語中的計算)時與之互動的層。 API 層定義了一組 G-API 動態物件,這些物件可以用作圖中的輸入、輸出和中間資料物件
API 層指定了一組對這些資料物件定義的操作 – 稱為核心。 有關 G-API 預設提供的操作的詳細資訊,請參見 G-API core 和 imgproc 名稱空間。
G-API 不僅限於這些操作 – 使用者可以使用特殊宏 G_TYPED_KERNEL() 輕鬆定義自己的核心。
API 層還負責在流水線建立時編組和儲存操作引數。 除了上述 G-API 動態物件外,操作還可以接受任意引數(有關此內容的更多資訊請參見 此處),因此 API 層會在執行時捕獲其值並在內部儲存。
最後,cv::GComputation 和 cv::GCompiled 是 API 層的其餘重要元件。 前者將一系列 G-API 表示式包裝到一個物件(圖)中,後者是圖編譯的產物(有關詳細資訊,請參見 本章)。
每個 G-API 計算在執行之前都會被編譯。 編譯過程以兩種方式觸發
對於預先不知道輸入資料格式的情況,建議使用第一種方法 – 例如,當它來自任意輸入檔案時。 對於輸入資料特徵通常是預定義的部署(生產)場景,建議使用第二種方法。
圖編譯過程建立在 ADE 框架之上。 最初,從 API 層捕獲的表示式生成二分圖。 該圖包含兩種型別的節點:Data 和 Operations。 圖始終以 Data 節點開始和結束,Operations 節點位於兩者之間。 每個 Operation 節點都有輸入和輸出,兩者都是 Data 節點。
生成初始圖後,實際上會透過多個圖變換(稱為passes)進行處理。 ADE 框架充當編譯器傳遞管理引擎,傳遞是專門為 G-API 編寫的。
有不同的傳遞,它們檢查圖的有效性,細化操作和資料的細節,根據親和力或使用者指定的區域[TBD]將節點組織成叢集(“Islands”),等等。 後端也能夠將後端特定的傳遞注入到編譯過程中,有關此內容的更多資訊,請參見 專用章節。
圖編譯的結果是一個已編譯的物件,由類 cv::GCompiled 表示。 無論是否存在顯式或隱式編譯請求(請參見上文),始終會建立一個新的 cv::GCompiled 物件。 實際的圖執行發生在 cv::GCompiled 中,並由參與圖編譯的後端確定。
上圖列出了兩個後端,OpenCV 和 Fluid。 OpenCV 是所謂的“引用後端”,它使用普通的舊 OpenCV 函式來實現 G-API 操作。 此後端對於在熟悉的開發系統上進行原型設計很有用。 Fluid 是一個用於在 CPU 上進行快取高效執行的外掛 – 它實現了不同的執行策略,並使用其自己的特殊核心進行操作。 Fluid 後端允許在 CPU 上執行時實現更少的記憶體佔用和更好的記憶體區域性性。
可能還有更多後端可用,例如 Halide、OpenCL 等 – G-API 提供了一個統一的內部 API 來開發後端,因此任何愛好者或公司都可以自由地在新平臺或加速器上擴充套件 G-API。 就 OpenCV 基礎設施而言,每個新後端都是一個新的獨立的 OpenCV 模組,當作為 OpenCV 的一部分構建時,它會擴充套件 G-API。
圖的執行方式由為編譯選擇的後端定義。 實際上,每個後端都在圖編譯過程的最後階段構建自己的執行指令碼,此時會生成一個可執行(已編譯)物件。 例如,在 OpenCV 後端中,此指令碼只是要呼叫的 OpenCV 函式的拓撲排序序列; 對於 Fluid 後端,類似 – 在每次迭代中處理輸入線的代理的拓撲排序列表。
圖執行以兩種方式觸發
兩種方法都是多型的,並採用可變數量的引數,並在執行時執行有效性檢查。 如果傳遞的資料物件的數量、形狀和格式與預期不同,則會引發執行時異常。 G-API 還提供了型別化包裝器,以將這些檢查移動到編譯時 – 請參見 cv::GComputationT<>。
G-API 圖執行被宣告為無狀態的 – 這意味著已編譯的函子 (cv::GCompiled) 的行為類似於純 C++ 函式,併為同一組輸入引數提供相同的結果。
兩種執行方法都採用 \(N+M\) 個引數,其中 \(N\) 是輸入數,\(M\) 是定義 cv::GComputation 的輸出數。 請注意,雖然 G-API 型別(cv::GMat 等)在定義中使用,但執行方法接受 OpenCV 的傳統資料型別(例如 cv::Mat),這些型別儲存實際資料 – 請參見 引數編組中的表。