由於嘗試使用OpenCV dnn modules實作Object Detection時,發現使用pip install opencv-python的opencv只有cpu版本,如果想要使用gpu功能必須自己編譯。
Step1
安裝Visual Studio Code https://visualstudio.microsoft.com/zh-hant/downloads/
Step2
安裝CMake,之後做編譯時,可以選擇使用有GUI或是直接在terminal下指令,兩個都有嘗試過,個人比較偏好使用GUI。
Step3
下載CUDA及cuDNN
- CUDA https://developer.nvidia.com/cuda-downloads
- cuDNN https://developer.nvidia.com/cudnn-download-survey
Step4
將opencv及opencv_contrib下載到你的資料夾。
- opencv https://github.com/opencv/opencv
- opencv_contrib https://github.com/opencv/opencv_contrib.git
Step5
打開Cmake進行編譯(如果要使用terminal,記得要把Cmake(C:\Program Files\CMake\bin),這是我自己電腦的路徑)加到環境變數。
進行編譯之前,先在opencv底下建立一個build資料夾,這是最後的output資料夾(你也可以選擇放在別的地方)
打開Cmake後,首先先選擇你剛剛下載的opencv,然後再選剛剛新增的build資料夾,然後點擊左下角的configure,並選擇x64,點finish,然後進行Configure。
結束後會產生如下的圖片,
然後WITH_CUDA,OPENCV_DNN_CUDA,ENABLE_FAST_MATH這幾項要打勾。PYTHON_EXECUTABLE及PYTHON3_LIBRARY必須選擇你所建的anaconda environment(因為除了base,你可能有其他的environment),OPENCV_EXTRA_MODULES_PATH必須指定剛剛下載的opencv_contrib/modules(因為pip install opencv-python裡面的modules都是使用CPU,如果要使用OpenCV dnn modules並且使用到GPU,必須要自己build,因為有CUDA功能的在opencv_contrib/modules),然後再重新Configure一次,
完成後你會看到如下圖的結果,然後把CUDA_ARCH_BIN其他版本號的都刪掉,留下與你cuDNN相符的,然後Configure,Generate,如下圖所示。
接下來點旁邊的Open Project,進入到Visual Studio Code,將Debug模式改成Release,然後再ALL_BUILD點右鍵,再點建置,接下來就慢慢等吧(時間有點久)。
接下來在INSTALL按右鍵->僅限專案->建置
完成後應該會在你一開始所見的build資料夾看到裡面一堆東西,重點就是在build裡面的install資料夾,必須將build\install\x64\vc16\bin加入環境變數(E:\opencv\build\install\x64\vc16\bin)
Step6
測試你的environment OpenCV是不是有GPU版本,可以使用下面程式碼測試,如果count=1代表有GPU,0就是沒有。如果你編譯都沒有錯誤,但是測試的時候卻沒有GPU,可能原因有下列幾個,這也是我自己遇到的問題。
- 你可能編譯時設定的python envirenment與測試程式碼的environment不一樣
- 你可能沒把E:\opencv\build\install\x64\vc16\bin加入環境變數
import cv2
count = cv2.cuda.getCudaEnabledDeviceCount()
print(count)
結論
我自己在測試的時候,如果建置完成後,把包含build的opencv放在C槽底下(C:opencv…),即使不用設定環境變數也還是吃的到GPU,我覺得應該是當import cv2時,會主動到C槽找opencv底下的\opencv\build\install\x64\vc16\bin裡的modules,所以如果不想在額外加入環境變數,這個路徑名稱就不要亂改啦。
在windows環境底下編譯真的會遇到很多問題,或是遇到即使編譯完,opencv還是吃不到GPU,繞了非常遠最後才成功,所以做個紀錄以免之後忘記。