一、前言

      最近想撸一下基于OpenCV的机器学习算法,突然间发现官方带的OpenCV是基于CPU版的,且支持CUDA的版本只能支撑Python 2.7。同时,尽管最新的OpenCV官方版宣称支持CUDA,但是我测试了下还是没有启用。因此想要一个能支持CUDA+Python 3.7的OpenCV。注意,如果你想要的是在Python中操作CUDA,则不应该使用高于3.0版本的OpenCV或直接考虑使用PyCuda,因为最新版的OpenCV已经移除了cv.cuda等一系列和cuda操作有关的类。

二、准备工作

      必须的软件环境:Windows 10 1903、Cmake 最新版、VS 2017 社区版(建议在“MSDN我告诉你”官网下载)、nVidia CUDA 10.1、对应版本的nVidia CUDnn、Python 3.7(尽量不要使用Anaconda的虚拟环境,也尽量不要同时存在多个Python环境)、OpenCV完整包(解压后包含预编译好的DLL和Source源代码文件夹)。

      必须的硬件:支持CUDA的nVidia的显卡,需要查明自己显卡对应的计算能力。

三、安装顺序

      3.1 安装Python 3.7 

        在官网上下载Python 3.7后安装,一路Next然后要勾选“把Python加入系统路径”的选项。安装完Python后要安装numpy。

      3.2 安装VS2017

        安装VS2017。安装过程中以下几个包必须勾选。其他的随意。

Centos8 python怎么使用cuda加速opencv cuda opencv python_CMake

Centos8 python怎么使用cuda加速opencv cuda opencv python_OpenCV_02

     3.3 安装CUDA和CUdnn

      先装CUDA,一路Next。可以更新驱动。然后注意勾选“Intergrated with Visual Studio”。安装完成后把CUdnn解压缩后的文件放到“C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1”下对应目录。在“C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\extras\demo_suite”下用命令行模式运行bandWidthTest.exe和deviceQuery.exe。结果应该都是PASS,表示CUDA和CUDNN安装成功。

     3.4 安装CMAKE

      安装过程中注意以下几个勾上:

     

Centos8 python怎么使用cuda加速opencv cuda opencv python_Python_03

    3.5 安装OpenCV

    解压从官网下载的OpenCV 4.2的包。

四、配置CMAKE

   右键以管理员身份运行CMAKE。首先选定即将存放生成编译文件的目标目录和OpenCV的Source目录,具体如下图步骤1-4:

Centos8 python怎么使用cuda加速opencv cuda opencv python_CUDA_04

  然后点下“Configure”后会第一次蹦出很多红色的错误提示,注意要把以下几个地方勾选上:其中如果勾选了“BUILD_opencv-world”选项就会把所有编译的结果打包成一个xxx_world.dll文件。如果不勾选就会打包成若干个散的dll文件。

Centos8 python怎么使用cuda加速opencv cuda opencv python_教程_05

注意一定要勾选“With_CUDA”和“OPENCV_CNN_CUDA”选项:

Centos8 python怎么使用cuda加速opencv cuda opencv python_OpenCV_06

并在“OPENCV_EXTRA_MODULES_PATH”里指定你从OpenCV安装包里解压出来的Source/opencv_contrib-4.2.0/modules文件夹(一定要指定到modules文件夹!!!):

Centos8 python怎么使用cuda加速opencv cuda opencv python_Python_07

第二次点“Configure”按钮,会再次提示出错。仔细看下面的白色错误信息,一般是ffmpeg.dll等几个文件丢失。没关系,打开报错目录下的Log文件,找到对应的报错信息下载路径。翻墙把对应的文件下载后,根据你编译的源目标文件(在这个示例里是D:\opence_master)下有个.cache。你点进去看会发现一堆文件名形如MD5+ffmpeg.dll这样的文件,但是文件大小为0。把所有为0的文件逐一替换成你翻墙下载的文件。文件名要保持格式一致,就是形如MD5+ffmpeg.dll这样的格式。也可以直接从本篇教程文末的下载链接里下载我打包好的cache包,解压到你的源目录下。由于缺的文件因人而异,我只列出常见的缺的文件有:ade、ffmpeg、ippicv、ippiw、xfeatures2d下的一堆.i文件。

第三次点“Configure”按钮,会提示“CUDA_ARCH_BIN”的数值错误。这里会给出一大堆CUDA_ARCH_BIN。默认会有2.0 /2.1(2.0)/3.0/3.5一直到8。根据你最终要部署的机器上的显卡数值选定。这个值从nVidia官网可以查到。我的显卡是GTX1080,因此就选6.1,删掉其他的数值。

Centos8 python怎么使用cuda加速opencv cuda opencv python_Python_08

Centos8 python怎么使用cuda加速opencv cuda opencv python_Python_09

然后指定你的Python 3.7目录。注意,这里有个坑,“PYTHON3_LIBRARY”的路径下一般会有很多个.lib文件。一定要选带版本号的,例如python37.lib文件。“PYTHON3_LIBRARY_DEBUG”可以留空。

Centos8 python怎么使用cuda加速opencv cuda opencv python_CUDA_10

设置完成后第三次点“Configure”,还会提示错误,那么检查下面几个地方勾选状态。尽量和我下面列出的勾选状态一致,有不明白的留言讨论:

Centos8 python怎么使用cuda加速opencv cuda opencv python_CUDA_11

Centos8 python怎么使用cuda加速opencv cuda opencv python_教程_12

Centos8 python怎么使用cuda加速opencv cuda opencv python_CUDA_13

 

Centos8 python怎么使用cuda加速opencv cuda opencv python_Python_14

Centos8 python怎么使用cuda加速opencv cuda opencv python_教程_15

 上面这些都配置完了,第四次点"Configure",必须做到没有红色的报错,并且下面的提示栏里的“OPENCV Module: To be Build”里有Python3和CUDA,并且有如下截图红框处的字样:

Centos8 python怎么使用cuda加速opencv cuda opencv python_CMake_16

 最后,没有提示错误的情况下,点“Generate”按钮。大概3分钟左右就在目标文件夹下生成了需要编译的文件。先不要关闭CMAKE。

Centos8 python怎么使用cuda加速opencv cuda opencv python_OpenCV_17

五、用VS2017编译

 点击CMAKE里的“Open Project”按钮会自动启动VS 2017。将VS 2017的模式改成“Release”和“X64”。注意,这里有个坑,要把VC++目录加上OpenCV目标文件夹路径。否则会在编译过程中报出 一大堆形如“LINK : fatal error LNK1181: 无法打开输入文件“opencv_world341.lib””的错误!添加方法为右键打开ALL_BUILD的属性页,向“包含目录”和“库目录”里添加你解压OpenCV预编译好的dll文件目录。注意,一定是形如“...\X64\VC15”的路径,不是VC14!VC14是VS 2015用的!!如下图:

Centos8 python怎么使用cuda加速opencv cuda opencv python_Python_18

 

Centos8 python怎么使用cuda加速opencv cuda opencv python_OpenCV_19

如果你前面没有调整为“Release”模式,那么这里就要选opencv_wordl345d.lib这样的文件!一般可以不指定链接器目录!

Centos8 python怎么使用cuda加速opencv cuda opencv python_CUDA_20

 再次右键点“ALL_BUILD”里的生成按钮,然后你就可以去干其他事情了。整个编译过程非常漫长,大概要1小时。编译后成功的结果如下图(但不一定是81个,也可能是100多个):

Centos8 python怎么使用cuda加速opencv cuda opencv python_CMake_21

在“INSTALL”上点右键生成,然后就生成了一个INSTALL文件夹:

Centos8 python怎么使用cuda加速opencv cuda opencv python_CMake_22

恭喜你!完成了编译工作!编译完成后在你的输出目录下应该有这么个结构的文件夹:

Centos8 python怎么使用cuda加速opencv cuda opencv python_CUDA_23

六、使用

Python调用:在你的输出目录下找到一个叫“cv2.cp37-win_amd64.pyd”和“opencv_world420.dll”的文件,拷贝到你的Python安装目录下的“\Lib\site-packages”目录中。进入Python中,执行如下代码应该有结果返回:

import cv2
import time

if __name__ == '__main__':
    s = time.time()
    img = cv2.imread("b1.png")
    print("imread:", time.time() - s)

    s2 = time.time()
    img2 = cv2.resize(img, (300, 400))
    print("resize:", time.time() - s2)

    s3 = time.time()
    img3 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    print("cvtColor:", time.time() - s3)

    print(cv2.getBuildInformation())
    print(cv2.__version__)
    cv2.imwrite("test4.png", img3)

Centos8 python怎么使用cuda加速opencv cuda opencv python_教程_24

同时如果你换一个不带CUDA的opencv的python(官方版本),那么执行上述代码的时间要比较长。图片越大,时间越长。

C#调用:新建工程后直接按dll的方式调用。如果你前面没有选择world选项,那么你可以在INSTALL目录下选择你要的dll导入。

Centos8 python怎么使用cuda加速opencv cuda opencv python_OpenCV_25

七、附件下载地址

打包的Cache文件下载链接: https://pan.baidu.com/s/1IqVmv3eytdTrEhUSPtJZTA 提取码: qfg7