OpenCV加速與優化,讓程式碼執行速度飛起來

  • 2019 年 11 月 11 日
  • 筆記

引子

做OpenCV開發這些年以來,很多人對OpenCV經常說的抱怨有如下兩點:

1.OpenCV模組很多,是一個很重量級的視覺框架!

2.OpenCV速度有點問題,不夠快!

針對對一個問題,OpenCV開發包包含的東西太多了,大而全,而它們的項目可能需要只是一點點,需要的是小而精,其實這個很容易解決,這個就是要求做好OpenCV的模組裁剪與移植,通過CMake自己編譯,關於這個問題,我也寫過一篇文章來介紹,感興趣可以點擊這裡:

OpenCV實戰應用必備技能 | 模組裁剪

第二個問題,我們可以分為幾個部分來說明。

CPU加速

今天我們重點說說第二個問題,OpenCV速度沒有達到項目要求怎麼辦,其實OpenCV發展到今天在不同的架構平台上都有一些底層的指令集支援的加速方法,在Windows系統下,OpenCV編譯默認支援加速SSE3 指令集,同時還額外支援SSE4.2、AVX、AVX2等加速指令集,在編譯時候CMake配置文件提供了下面選項支援:

CPU_BASELINE=SSE2 CPU_BASELINE=AVX 需要C++編譯器支援 CPU_DISPATCH=SSE4_2,AVX CPU_DISPATCH=AVX CPU_DISPATCH=AVX,AVX2 額外的加速支援,同樣需要編譯器支援。

早期通過ENABLE的方式已經在OpenCV3.x之後被拋棄,下面這個幾個選項是無效選項:

ENABLE_AVX ENABLE_AVX2 ENABLE_POPCNT

ARMv7架構系統下支援

NEON

這些方法的加速效果如何,答案是通過編譯支援的SSE/AVX加速,基本上可以獲得1.3~3.0之間的加速執行。這個也就是為什麼有時候我們直接無感的原因,就是加速不夠明顯!

一般情況下,自己重新編譯OpenCV源碼,CMake的時候都會生成如下的一些資訊:

其實這個時候,還有幾個比較有用的Flag可以勾選上,會起到明顯的加速效果:

WITH_TBB

默認情況下是OFF、勾選可以獲得並行處理支援

在TBB開啟支援的情況下,可以通過下面的兩個API設置執行緒數目,嘗試獲得並行執行能力。

setNumThreads() // 設置執行緒數目  getNumThreads() // 查詢執行緒數目,為0表示順序執行

CV_ENABLE_IPP

默認情況下是OFF、早期的OpenCV版本可以這麼干,現在的OpenCV版本不支援

GPU加速

OpenCV CUDA支援下面的模組的加速運行

這個OpenCV默認是不支援,需要自己重新編譯OpenCV源碼,如何編譯,參考我在B站的影片教程:

https://www.bilibili.com/video/av71643385

OpenCV中深度神經網路模組之前一直不支援CUDA作為計算後台的加速運行,就在前幾天,OpenCV社區剛剛完成此項支援,所以OpenCV DNN模組在後續下個版本中將可以使用CUDA加速。簡單點說,OpenCV DNN模組將會獲得更大的速度優勢。OpenCV也必將在更多邊緣設備上得到應有。

OpenVINO加速

英特爾從去年推出視覺加速框架,對OpenCV所有的模組都有加速,特別是對深度神經網路模組,支援CPU/GPU(HD顯示卡)/加速棒等硬體加速,特別值得一提的是其CPU基本的加速,對人臉檢測、對象檢測等深度神經網路均可以達到實時運行級別,本人也寫過一系列的OpenVINO SDK開發的相關技術文章。OpenVINO的安裝與配置,程式碼演示,可以觀看我在B站的影片教程:

https://www.bilibili.com/video/av71979782

相關技術文章匯總在這裡:

英特爾 OpenVINO深度學習推理框架 開發技術系列文章匯總

總結與後記

上述各種加速手段,都有一定的限制,只有選擇適合應用場景的加速方法才是正確的解決問題之道。另外OpenCV在開發階段,不同程式碼寫法與實現效率有時候會有雲泥之別!這個更加體現開發者本身的技術水準。最後放兩張圖,看一下,OpenCV加速效果,分別是傳統的影像處理方式與深度學習模型加速影片演示,幀率分別超過 199與90 FPS 以上!

Tags: