本文介紹使用OpenCV和OpenCV_Contrib源碼及Cuda進行編譯的過程,編譯過程中會用到OpenCV、OpenCV_Contrib、Toolkit、Cmake、VS2022等工具,最終編譯OpenCV的Cuda版本。
一、OpenCV下載地址
OpenCV官網下載地址:https://opencv.org/releases/#,選擇一個版本下載,下載之后解壓或者提取;
OpenCV Gihthub下載地址:https://github.com/opencv/opencv;也可以在Github選擇一個版本下載,下載之后解壓;
注:從官網使用下載器下載的OpenCV解壓后會多一個build文件夾,是已經編譯的opencv文件,直接從Github下載的沒有這個文件夾,因為需要自己編譯Cuda版本的opencv,所以不會用到這個build文件夾,有沒有都不影響;
圖中左側opencv4.11.0文件夾就是右側的sources文件夾(下圖)
二、OpenCV_contrib下載地址
OpenCV Gihthub下載地址:https://github.com/opencv/opencv_contrib,和下載OpenCV相同的方式進行下載,注意OpenCV_contrib的版本要與下載的OpenCV的版本一致。下載后解壓;
下圖中的cuda開頭的文件夾就是與cuda相關的文件,
三、Cmake下載
下載Cmake:https://cmake.org/download/,我使用的Cmake4.0.1;
四、Cuda Toolkit下載
1.查看CUDA最高支持版本
在命令窗口中使用nvidia-smi查看電腦的顯卡支持的CUDA Toolkit版本(如果nvidia-smi不可用,可能是命令行輸錯了或者沒安裝顯卡驅動,檢查命令行或者下載驅動:https://www.nvidia.cn/drivers/lookup/),下圖中CUDA Version12.6代表最高支持CUDA Toolkit12.6的版本;
2.下載CudaToolkit
下載地址:https://developer.nvidia.com/cuda-downloads,下載完成后,進行安裝,安裝后
在C:\Program Files會有NVIDIA GPU Computing Toolkit文件夾;
3.環境變量配置
安裝完成后,系統環境變量中會有以下兩個路徑;
在環境變量Path中,需要添加以下路徑(前兩個是安裝后自動添加的,所以只需要添加最后一個x64的路徑就行):
4.檢查CUDA Toolkit版本
在命令窗口輸入 nvcc -V(中間有空格)會顯示電腦安裝的CUDA Toolkit的版本號;
五、cuDNN下載
下載地址:https://developer.nvidia.com/cudnn,下載完成后,將其中的bin文件,lib文件夾,include文件夾,三個文件夾中的文件復制到對應的cuda文件夾中,即C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.2文件夾的對應目錄中(v12.2是CUDA的版本號,我下載的是12.2),如果不使用cuDNN可以跳過此步驟;
六、編譯
1.opencv編譯
1.打開Cmake,首先編譯opencv,選擇Opencv源碼文件夾,之后選擇新的build文件夾,如下圖新建一個build文件夾,我的build文件夾名字為cudaopencv1:
點擊左下角的Configure,會彈出以下界面,選擇generator,我的需要使用的VS2022,所以我選擇的是Visual Studio 17 2022(根據自己的需求選擇),之后點擊Finish:
2.Configure完成后會有以下界面,Configure過程中會顯示warning,提示你版本cmake版本要求或者文件未找到,可以一個一個查看,不是自己需編譯的文件就不用管(也可以直接取消勾選,不進行編譯);
3.點擊Generate,下方會顯示Generating done.
4.至此build文件夾(我的build文件夾名為cudaopencv1)中會出現以下文件:
2.OpenCV生成
1.雙擊打開生成的OpenCV.sln,
2.在VS中設置編譯環境Debug或者Release,之后在解決方案管理器中找打CmakeTargerts,右鍵點擊其中的ALL_BUILD,點擊生成;
3.在自己的build文件夾中會生成lib文件夾,如下所示
lib文件夾中的內容是剛剛生成的文件,如果是在Debug模式下生成就會有Debug文件夾,如果是Release模式就會有Release文件夾,兩種模式都生成,兩個文件夾都有;
文件夾中是生成的庫文件:
3.編譯contrib及CUDA
1.在Cmake中找到OPENCV_EXTRA_MODULES_PATH,設置文件夾為opencv_contrib文件中的modules文件夾路徑,我的opencv_contrib路徑為:D:/OpenCV4.11/opencv_contrib-4.11.0/modules,如下圖:
2.在cmake的search中輸入cuda,設置BUILD中的BUILD_CUDA_STUBS為勾選狀態,設置WITH中的WITH_CUDA為勾選狀態;
3.設置完成后,點擊下方的Configure,最下方顯示Configuring done.
4.完成Generate之后設置顯卡算力參數,在Cmake的Search中搜索ARCH,設置CUDA_ARCH_BIN參數為自己的顯卡算力,我的顯卡算力為8.6,具體自己的顯卡算力可以在Nvidia網站查詢:https://developer.nvidia.com/cuda-gpus;
注意:在未點擊Generate時搜索不到這個參數,完成一次Generate后才可以搜到這個參數,如果不設置這個參數會導致后邊的cudaopencv編譯失敗;
5.設置CUDA_FAST_MATH為勾選狀態:
點擊Configure,顯示Configuring done后,點擊Generate,Generating done
6.檢查是否編譯成功
a.在Camke的白色區域中,Build中會顯示以下目錄:
b.在自己的build文件夾中的modules文件夾中(我的build文件夾名字為cudaopencv1),會有以下文件,
至此opencv cuda版本的build完成。
4.使用VS進行生成
打開build文件夾(cudaopencv1),找到OpenCV.sln,雙擊打開;
在CmakeTargets中找到ALL_BUILD,右鍵點擊生成(此過程比較長,我用了18分鐘),
生成完成后,查看自己的build文件夾的lib文件夾,發現與之前相比會多出contrib中的內容
之后點擊INSTALL中的僅用于項目的僅生成INSTALL,點擊后會在build文件夾中生成一個install文件夾,文件夾中的內容就是編譯的全部內容。
install文件夾中的內容:
這里邊都是debug模式下編譯的庫文件,如果需要release模式,在ALL_BUILD生成時,在VS中選擇Release,然后再生成INSTALL。
至此,opencv +contrib+cuda編譯全部完成。
七、配置及使用
1.配置環境變量
在此電腦->屬性->高級系統設置->環境變量->系統變量->Path中增加編譯的bin文件夾;
2.配置項目屬性
首先配置項目包含目錄,在包含目錄中添加:D:\OpenCV4.11\cudaopencv1\install\include 和 D:\OpenCV4.11\cudaopencv1\install\include\opencv2;
在庫目錄中,配置D:\OpenCV4.11\cudaopencv1\install\x64\vc17\lib
在鏈接器->輸入->附加依賴項中,加入build文件夾中所有lib文件名稱,文件名很多,所以可以使用命令行一次性全部轉換為文本,然后直接復制(詳見3.獲取所有lib文件名稱)
3.獲取所有lib文件名稱
在命令窗口中輸入:dir /b “文件路徑”>生成的文本路徑;
例如以下截圖,會將lib文件夾中的所有文件名字存放到C盤的name文本中;
4.驗證是否可用
使用以下代碼可以獲取編譯信息及電腦的GPU數量,則可以正常使用;
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/cudafilters.hpp>
#include <opencv2/cudaimgproc.hpp>
int main()
{std::cout << "OpenCV built with CUDA: " << cv::getBuildInformation() << std::endl;//獲取編譯信息,如下圖int num_devices = cv::cuda::getCudaEnabledDeviceCount();std::cout << "Number of CUDA devices: " << num_devices << std::endl;return 0;
}
如果編譯正常,使用getBuildInformation()函數可以看到NVIDIA CDUA的狀態為YES,而且可以看到顯卡的計算能力;
使用cuda::getCudaEnabledDeviceCount()可以獲取到電腦的顯卡數量(如下圖,電腦只有一個顯卡,獲取的結果也是1);
八、匯總
使用的編譯工具及版本如下,如果有需要編譯完成的文件,可以在評論區留下郵箱;
九、編譯過程中可能遇到的問題
1.所有步驟均按照以上過程操作,但是在VS生成過程中,顯示:
27>D:\OpenCV4.5.5\opencv\sources\modules\core\include\opencv2/core/cuda/common.hpp(99,27): error C4430: 缺少類型說明符 - 假定為 int。注意: C++ 不支持默認 int (編譯源文件D:\OpenCV4.5.5\opencv\cudaopencv\modules\core\arithm.sse4_1.cpp)
產生這個問題大概率是由于cuda版本與opencv版本的兼容問題,我最開始使用OpenCV4.5.5和CUDA 12.2版本,出現這個問題,后來換成OpenCV4.11和CUDA12.2,編譯成功
2.在Cmake過程中出現以下錯誤,顯示:
CMake Error at cmake/OpenCVDetectCUDAUtils.cmake:297 (list):
list GET given empty list
Call Stack (most recent call first):
cmake/OpenCVDetectCUDA.cmake:76 (ocv_set_cuda_arch_bin_and_ptx)
cmake/OpenCVFindLibsPerf.cmake:46 (include)
CMakeLists.txt:800 (include)
cmake檢測CUDA架構時未能正確識別電腦GPU的計算能力,如果出現這個問題,在cmake中設置CUDA_ARCH_BIN的值,GPU計算能力查詢https://developer.nvidia.com/cuda-gpus