NVIDIA 圖靈架構引入了一種新的硬件功能,用于以非常高的性能計算一對圖像之間的光流。 NVIDIA 光流 SDK 公開了使用這種光流硬件(也稱為 NVOFA )加速應用程序的 API 。我們很高興地宣布光流 SDK 3 . 0 的可用性具有以下新功能:
- DirectX 12 光流 API
- 通過單個 API 的前后向光流
- 全球流動矢量
DirectX 12 光流 API
DirectX 12 是一個來自 Microsoft 的低級編程 API ,與它的前身 DirectX 11 相比,它減少了驅動程序開銷。 DirectX 12 為開發人員提供了更大的靈活性和細粒度的控制。開發人員現在可以利用 DirectX 12 中的低級編程 API 并優化其應用程序,以提供比早期 DirectX 版本更好的性能—同時,客戶端應用程序本身必須負責資源管理、同步, DirectX 12 在游戲和其他圖形應用程序中迅速發展。
光流 SDK 3 . 0 支持 DirectX 12 應用程序使用 NVIDIA 光流引擎。計算出的光流可用于提高游戲和視頻中的幀速率,以獲得更平滑的體驗或用于目標跟蹤。為了提高幀速率, F rame R ate U p C onversion ( FRUC )技術通過在原始幀之間插入插值幀來使用。插值算法使用幀對之間的流來生成中間幀。
光流硬件的所有代支持 DirectX 12 光流接口。光流 SDK 包包含頭( S )、演示使用的示例應用程序、可根據需要重新使用或修改的 C ++包裝類和文檔。用于訪問光流硬件的所有其他組件都包含在 NVIDIA 顯示驅動程序中。 Windows 20H1 或更高版本的操作系統支持 DirectX 12 光流 API 。
除了顯式同步之外, directx12 光流 API 的設計與 SDK 中已有的其他接口( CUDA 和 DirectX 11 )非常接近, DirectX 12 光流 API 由初始化、流量估計和銷毀三個核心功能組成。
typedef NV_OF_STATUS(NVOFAPI* PFNNVOFINIT) (NvOFHandle hOf, const NV_OF_INIT_PARAMS* initParams); typedef NV_OF_STATUS(NVOFAPI* PFNNVOFEXECUTED3D12) (NvOFHandle hOf, const NV_OF_EXECUTE_INPUT_PARAMS_D3D12* executeInParams, NV_OF_EXECUTE_OUTPUT_PARAMS_D3D12* executeOutParams); typedef NV_OF_STATUS(NVOFAPI* PFNNVOFDESTROY) (NvOFHandle hOf);
初始化和銷毀 API 在所有接口上都是相同的,但在 DirectX 12 和其他接口(即 DirectX 11 和 CUDA )之間執行 API 是不同的。盡管在 DirectX 12 中傳遞給 executeapi 的大多數參數與其他兩個接口中的參數相同,但在功能上還是存在一些差異。 DirectX 11 和 CUDA 接口中的同步由操作系統運行時和驅動程序自動處理。但是,在 DirectX 12 中,需要有關圍欄和圍欄值的附加信息作為執行 API 的輸入參數。這些圍欄對象將用于同步 CPU ? GPU 和 GPU ? GPU 操作。有關詳細信息,請參閱光流 SDK 附帶的編程指南。
DirectX 12 中的緩沖區管理 API 接口也需要 fence 對象來進行同步。
所有接口的光流輸出質量相同。與其他兩個接口相比, DirectX 12 的性能應該非常接近。
正反向光流
沒有一種光流算法能給出 100% 的準確流量。在閉塞區域,流動通常是扭曲的。有時, NVOA 提供的成本也可能不代表流動的真實可信度。通常采用的一個簡單檢查是比較向前和向后流動。如果正向流和反向流之間的歐氏距離超過閾值,則該流可以標記為無效。
為了估計兩個方向上的流,客戶機必須調用 Execute API 兩次:一次調用輸入和引用圖像,第二次調用在反轉輸入和引用圖像之后。像這樣兩次調用 Optical Flow Execute API 可能會由于上下文切換、線程切換等開銷而導致性能不佳。 Optical Flow sdk3 . 0 公開了一個新的 API ,以便在單個 Execute 調用中生成雙向流。可以通過在初始化中設置 NV_OF_INIT_PARAMS::predDirection to NV_OF_PRED_DIRECTION_BOTH
并在 NV_OF_EXECUTE_OUTPUT_PARAMS/NV_OF_EXECUTE_OUTPUT_PARAMS_D3D12::bwdOutputBuffer, NV_OF_EXECUTE_OUTPUT_PARAMS/NV_OF_EXECUTE_OUTPUT_PARAMS_D3D12::bwdOutputCostBuffer
.
? 中提供接收反向流和/或開銷所需的緩沖區來啟用此功能


一旦在兩個方向上生成流,客戶端應用程序就可以比較兩個方向的流向量,根據適當的標準(例如,向前和向后流向量之間的歐幾里德距離)丟棄不準確的流向量,并使用孔填充算法來填充這些丟棄的流向量。
注意,由于一些優化, FB 流的輸出質量可能不同于單向流。
演示 FB flow API 編程和一致性檢查的示例代碼:
// Initialization of API NV_OF_INIT_PARAMS initParams = { 0 }; ... initParams.predDirection = NV_OF_PRED_DIRECTION_BOTH; ... NvOFAPI->nvOFInit(hNvOF, &initParams); // Estimation of forward and backward flow NV_OF_EXECUTE_INPUT_PARAMS executeInParams = { 0 }; ... NV_OF_EXECUTE_OUTPUT_PARAMS executeOutParams = { 0 }; ... executeOutParams.outputBuffer = forwardFlowBuffer; executeOutParams.outputCostBuffer = forwardFlowCostBuffer; executeOutParams.bwdOutputBuffer = backwardFlowBuffer; executeOutParams.bwdOutputCostBuffer = backwardFlowCostBuffer; NvOFAPI->nvOFExecute(hNvOF, &executeInparams, &executeOutParams) // Invalidating flow vectors for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { // read forward flow vector float mvx = GetFlowX(forwardFlowBuffer, x, y); float mvy = GetFlowY(forwardFlowBuffer, x, y); // derive the corresponding position in the backward flow (assuming 1x1 grid size) // and read the backward flow vector int x2 = x + mvx; int y2 = y + mvy; if (x2 < 0 || x2 > width - 1 || y2 < 0 || y2 < height - 1) { SetFlowInvalid(forwardFlowBuffer, x, y); continue; } float mvx2 = -1 * GetFlowX(backwardFlowBuffer, x2, y2); float mvy2 = -1 * GetFlowY(backwardFlowBuffer, x2, y2); // mark flow vector as invalid if the distance is greater than a threshold if (((mvx - mvx2) * (mvx - mvx2) + (mvy - mvy2) * (mvy - mvy2)) > thresh) { SetFlowInvalid(forwardFlowBuffer, x, y); } } }
全球流量估算
視頻序列或游戲中的全局流是由攝影機平移運動引起的。全局流估計是一個重要的工具,廣泛應用于圖像分割、視頻拼接或基于運動的視頻分析應用中。
全局流矢量也可以啟發式地用于計算背景運動。一旦估計出背景運動,它就可以用來填充遮擋區域中的流矢量,也可以用來處理插值幀中扭曲像素的碰撞。
全局流量是基于發生頻率和其他一些啟發式算法,在前向流矢量上計算的。
為了能夠生成全局流,初始化 API 需要設置標志 初始化參數的 NV \ u :: enableGlobalFlow ,并在 executeapi 中提供額外的緩沖區 NV _ OF _ EXECUTE _ OUTPUT _ PARAMS / NV _ OF _ EXECUTE _ OUTPUT _ PARAMS _ D3D12 ::全局流緩沖區 。
參考
- NVIDIA 光流 SDK
- 開發者博客: NVIDIA 光流 SDK 簡介
- 開發者博客: 用 NVIDIA 圖靈 GPU s 加速 OpenCV :光流算法
?