平台与软件
Windows11系统
Visual Studio 2019:Visual Studio Community 2019
Cmake:cmake-3.25.1-windows-x86_64.msi
OpenCV 4.52:opencv-4.5.2.tar.gz
OpenCV_contrib 4.5.2:opencv_contrib-4.5.2.tar.gz
问题:
Python通过pip或conda安装的OpenCV库仅支持CPU;需要对opencv源码采用CMake和visual studio进行编译安装才能使用GPU。最终目标是既可以在Visual studio中开发支持CUDA的opencv C++项目,也可以在Python中使用GPU对opencv-python加速。这涉及到一系列较复杂的流程。
1.安装visual studio 2019
进入官方的下载页面,可能需要登录,登录后选取社区版下载。
注意,这里只是下载安装器,真正的安装会在后续执行文件,配置安装目录后,联网下载安装包文件。整个过程比较简单,这里不作详细叙述。仅提供一份备用的安装器下载链接。
链接: https://pan.baidu.com/s/1l7IZBIXw7qiGZC9upCylgg
提取码:62dn
2.安装CUDA和CUDNN
前往官网下载CUDA(CUDA toolkit各版本的官方下载地址)和对应的CUDNN(cuDNN Archive),切记一定要对应CUDNN和CUDA版本。进入驱动下载界面,根据自己的显卡型号,选择合适的显卡驱动。
查看驱动支持的cuda最高版本
进入官方网站查看不同的cuda版本所需要的最低的驱动版本。
成功安装英伟达驱动后,win+R,输入cmd,进入命令行界面,输入nvdia-smi,即可查看nvidia驱动版本,以及当前最高支持的cuda版本。
这里提醒一个问题,就是一些网友可能装了不同版本的CUDA,可以通过环境变量的设置进行切换。安装多版本的CUDA时,注意只安装CUDA库,驱动不要安装,否则安装失败。
过程中会检查是否安装visual studio 2019的配置选项,如果没有,则无法配置成功,所以一定要先安装visual studio 2019.
步骤安装成功,在命令行输入nvcc -V可以显示cuda的版本信息。这里显示的cuda版本是环境变量设置的当前版本,可以与nvidia-smi显示的不一样。
对于cudnn的安装配置则较为简单,将文件下载,解压,改名,复制替换C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v1x.x下的对应文件即可。
这里需要注意后续编译opencv的时候,对于cuda和cudnn的识别是可以在配置项中设置的,所以如果安装了多个cuda版本,需要将相应的cudnn版本分别对应安装。最终生成的环境如下:
对path进行设置如下:
3.测试 Visual Studio
打开Visual Studio ,选择创建新项目
2.在最下面找到CUDA
3.自定义项目工程的位置
4.打开示例文件
5.运行
4.OpenCV源码下载
进入OpenCV官网,选择自己需要的版本,例如OpenCV-4.5.3。
进入OpenCV GitHub官方仓库,通过tags选择对应的contrib版本
5.CMake安装与设置
进入CMake官网下载就行,我这里下载的CMake 3.25.1.在红框位置分别opencv源文件目录和编译后的输出目录,二者是平级目录。
CMake配置是编译成功的关键,这里面有很多坑。注意CMake的配置是需要至少2次。
build作为输出目录最好是空目录,这样第一次进入CMake中间配置区域为空白。点击Configure选择vs 2019和x64架构,点击finish,开始第一次编译生成配置项。
1.编译过程需要下载各种依赖,大概率会因为网络问题会卡住,可参考另一篇博文,直接下载到.cache文件夹,可省去此烦恼。
2.(此步选做) 创建虚拟环境,建议使用anaconda,并在虚拟环境中安装numpy(编译时需要),执行此步骤是为了将CUDA版本的opencv安装到虚拟环境中,只安装到宿主机环境不需要执行此步骤。
3. (此步骤选做,但执行此步骤的前提是必须执行上一个步骤) 更换一下几个变量,分别将路径指向虚拟环境的对应位置 : PYTHON3_EXECUTABLE、PYTHON3_INCLUDE_DIR、PYTHON3_LIBRARY、PYTHON3_NUMPY_INCLUDE_DIRS、PYTHON3_PACKAGES_PATH
这里有个坑:需要安装与虚拟环境python版本一致的原生python,我之前安装了python3.6,虚拟环境python是3.7,可以通过编译但始终无法在opencv-python中识别GPU。
4.configure完成后,在Search框内输入CUDA和fast,勾选三个配置 : WITH_CUDA 、OPENCV_DNN_CUDA、ENABLE_FAST_MATH,要按顺序进行
勾选 WITH CUDA,如果要应用opencv的sift算法,则还需要将OPENCV_ENABLE_NONFREE勾选上:
绿框是要特别注意勾选和修改。TOOLKIT_ROOT_DIR是本机当前配置环境下的cuda版本目录。
5.search框搜MODULES,在OPENCV_EXTRA_MODULES_RATH一项,添加opencv_contrib4.5.1中的modules目录
6.Search框搜world,将build_opencv_world打勾,将所有opencv的库都编译在一起不需要自己一一添加每个小模块。
7.Search框搜BUILD,勾选BUILD_opencv_python3。这一步很重要,决定了能否在python中使用GPU加速。
8. search框搜NON,把OPENCV_ENABLE_NONFREE 打勾
9. 勾选build_opencv_world
10.去掉python,test、java加快后面的编译
11.第二次点击configure,等待下方日志显示configure done
12.搜索框输入cuda,勾选CUDA_FAST_MATH ,CUDA_ARCH_BIN中将显卡的算力内容改成自己显卡的算力(算力查询)。 默认会从最低的3.0开始,不仅影响配置速度,而且由于最新cuda 11对 compute_30了不支持,会出现如下错误:
nvcc fatal : Unsupported gpu architecture ‘compute_30‘ 错误
解决方法就是重新回到cmake,找到CUDA_ARCH_BIN,需要把这里的3.0删掉之后再重新generate。
12. 再次点击configure,这次的Configuring done终于OK,然后点击Generate,稍等片刻出现Generating done!
点击Open Project,它会启动你的Visual Studio。
13.最后没有错误的情况下,点击Generate按钮,生成需要编译的文件。这里先不要关闭CMAKE软件
点击Open Project用VS编译。
6. VS编译
通过前面打开Project后,就会跳转到VS界面。这里首先要确定的一点是,首先将模式调整为Release版本。
同时必须保证bindings这个目录下有opencv_python3才进行下一步,否则即使编译成功仍然不能使用CUDA加速。
首先选择ALL_BUILD->生成,接下来就是漫长的等待过程。我的机器大概编译了1个小时,图就不贴了,总之没有错误编译就是成功的,类似如下界面。
编译完成后,在INSTALL->生成,这个编译要快一点。下面就是等待他们完成了,编译完成后结果如下:
7. 验证
编译完成后在opencv_cuda\build\lib\python3\Release文件夹下可以看到cv2.cp37-win_amd64.pyd文件(不同的python版本,名称会略有差异)
同时,在虚拟环境或者宿主机环境中,可以在路径Lib\site-packages下看到cv2文件夹
验证opencv环境
使用命令行进入python环境,执行一下代码即可验证:
c:\users\administrator> python
>>> import cv2
>>> cv2.cuda.getCudaEnabledDeviceCount()
>>>1
1 # 得到GPU设备数量,即表示opencv的GPU版本已经安装成功
最后测试能否使用cuda,代码如下:
#读取图片
import cv2
frame=cv2.imread('drip.png')
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
cv2.imshow('before',frame)
cv2.waitKey(0)
#上传到gpu进行处理
gpu_frame=cv2.cuda_GpuMat()
gpu_frame.upload(frame)
print(gpu_frame.cudaPtr())
#把图像从RGB转换成BGR(OpenCV格式),然后调整大小
screenshot = cv2.cuda.cvtColor(gpu_frame, cv2.COLOR_RGB2BGR)
screenshot = cv2.cuda.resize(screenshot, (400, 400))
#从GPU下载图像 (cv2.cuda_GpuMat -> numpy.ndarray)
screenshot = screenshot.download()
cv2.imshow('after',screenshot)
cv2.waitKey(0)
原图
调整后
感觉处理速度确实有所提升,后续有待进一步测试。
还有一种简单的方法,可以使用官方预构建源代码配置支持GPU模块的OpenCV,不使用Visual Studio编译,参考Python OpenCV配置CUDA以支持GPU加速。
其它参考