自行编译使能cuda支持的opencv 4.1.1
需求
darknet的yolov3的算法模型在cpu版本的opencv下速度较慢,推理时间为400ms~500ms。要想用上cuda加速就要重新编译OpenCV。于是开始编译gpu版本的opencv,同时加上nonfree特性方便以后其他项目算法开发。
Environment
- CPU: Intel i7
- GPU: Nvidia GTX760
- Windows 10 Pro
Prerequisite
- CUDA 10.1 update 2 For Windows 10 x86_64
- cudnn-10.1-windows10-x64-v7.6.4.38
- opencv , opencv_contrib
- cmake 3.15+
Step
Prerequisite
- 安装CUDA 10.1(10.1开始才支持VS2019),安装完成后将cudnn的压缩包解压,内容根据相应文件夹名复制到cuda的安装目录下。
- opencv 和 opencv_contrib 的版本都有对应关系。 我这里opencv选择了4.1.1版本,opencv_contrib要checkout出跟4.1.1对应的branch
process with cmake
- 在opencv 源码目录下新建build目录。 打开cmake,source path选择opencv的目录,build path选择刚创建的build目录,勾选Grouped。
- 点击Configure按钮, 我选择了Visual Studio 16 2019 x64,platform我也指定x64, 点击Finish。
- 等待Configuring done,点开OPENCV分组,OPENCV_DNN_CUDA打勾,OPENCV_ENABLE_NONFREE打勾,OPENCV_PYTHON3_VERSION打勾。
- search栏搜索opencv_extra_modules_path,填入opencv_contrib模块的路径,应指向opencv_contrib/modules目录。搜索with_cuda,打勾。build_cuda_stubs确认不要勾上。
- 再次configure,提示ippicv下载失败,一般是墙的原因,点进去opencv/3rdparty/ippicv目录打开cmake文件,根据cmake的脚本,手动拼接出一个下载地址,可能不同版本的ippicv下载地址规则不一样,我这里就分析当前版本的(4.1.1)。首先会发现一个很显眼的URL:
1
https://raw.githubusercontent.com/opencv/opencv_3rdparty/${IPPICV_COMMIT}/ippicv/
接着找到IPPICV_COMMIT这个变量的设置代码,还有针对当前编译平台的源码包包名1
2
3
4
5set(IPPICV_COMMIT "32e315a5b106a7b89dbed51c28f8120a48b368b4")
···
if(X86_64)
set(OPENCV_ICV_NAME "ippicv_2019_win_intel64_20180723_general.zip")
set(OPENCV_ICV_HASH "1d222685246896fe089f88b8858e4b2f")
据此拼接出一个下载地址https://raw.githubusercontent.com/opencv/opencv_3rdparty/32e315a5b106a7b89dbed51c28f8120a48b368b4/ippicv/ippicv_2019_win_intel64_20180723_general.zip。这里的IPPICV_COMMIT应该每次opencv release都会变的。
- 提示没有找到VTK,VTK是一个用于3D可视化显示的库。去官网下载vtk源码包进行cmake,编译visual studio工程后。opencv cmake这边指定VTK_DIR到VTK的build目录。
- 这次configure时间较长,提示Configuring done后点击Generate。等待Generating done,open project。
Visual Studio 2019 build
- 在VS2019中,将工程配置成Release,然后build solution。等待编译结束,视PC性能而定时间,因为开了contrib、non-free等特性,会编译很久。
编译完成,38 succeeded, 一步步往上翻,发现最早的错误是ippicvmt.lib: fatal error LNK1127: library is corrupt,意思是库损坏,重新下载了ippicv覆盖掉原来的库。重新编译,不再报错。最后一行显示
1
========== Build: 178 succeeded, 0 failed, 8 up-to-date, 9 skipped ==========
在Solution Explorer中找到INSTALL项目,右键选择project only下的build only install。所有需要的东西都会被整理到build/install目录下。
install OpenCV(with cuda support) in python
想要安装opencv进python3的时候发现并没有装成功,没有提示报错。在cmake-gui里搜索了下发现python3 numpy include的路径为空,在configure的时候提示信息会显示不可用的模块包括python2和python3,手动填入numpy include路径后,再次configure就显示python3模块将要安装到的位置。重新generate,重新编译。这回install有install到anaconda的Lib/site-packages目录下。但在python环境中import cv2 却提示
1
2
3
4
5
6
7
8Traceback (most recent call last):
File "F:/src/tensorflow_yolov3_pretest/test_env.py", line 1, in <module>
import cv2
File "D:\Users\nephilim\Anaconda3\lib\site-packages\cv2\__init__.py", line 89, in <module>
bootstrap()
File "D:\Users\nephilim\Anaconda3\lib\site-packages\cv2\__init__.py", line 79, in bootstrap
import cv2
ImportError: DLL load failed: 找不到指定的模块。
应该不是opencv的路径问题,检查了自动生成的cv2的python脚本中都设置对了,可能是opencv的什么依赖库没找到,于是尝试运行opencv下的annotation工具看看有没依赖报错。结果提示找不到vtk的dll,于是先解决vtk的库。vtk install的时候提示Error MSB3073,以管理员权限运行VS2019可以解决,后来发现是因为VTK的install路径是C盘Program Files目录,不是很爽,给剪切了出来。然后将VTK/bin目录添加到环境变量Path中。顺便把opencv的x64/vc16/bin目录也放在Path中。而后重新打开pycharm,运行如下代码:1
2
3
4
5import cv2
print(cv2.__version__)
print(cv2)
detector1 = cv2.xfeatures2d.SIFT_create()
detector2 = cv2.xfeatures2d.SURF_create()
打印结果1
2
3
4
5D:\Users\nephilim\Anaconda3\python.exe F:/src/tensorflow_yolov3_pretest/test_env.py
4.1.1
<module 'cv2' from 'D:/Users/nephilim/Anaconda3/Lib/site-packages/cv2\\python-3.7\\cv2.cp37-win_amd64.pyd'>
Process finished with exit code 0
安装成功
重新跑一遍yolov3验证cuda加速是否可行
最后测试一下带cuda支持的opencv,发现仍没有调用到gpu,查下相关资料发现opencv的dnn模块目前还不支持cuda,至少官方针对这一部分是in progress。progress
pycharm中无法自动提示cv2相关代码
在python中安装自己编译的opencv,没有代码自动补全功能,这一部分目前还没找到办法解决。