想要使用opencv的dnn模块来进行深度学习的模型推理,需要安装opencv的扩展库(opencv_contrib),本文记录如何在ubuntu18.4上安装opencv和opencv_contrib,生成python和C++可调用的opencv,并能够在GPU上运行。
环境
- ubuntu18.04
- opencv4.2.0
- opencv_contrib4.2.0
- cuda10.0
- cudnn7.6.4(cudnn版本大于7.5才能在使用dnn时启用GPU)
安装过程
1.安装相关依赖库
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install build-essential cmake unzip pkg-config
sudo apt-get install libjpeg-dev libpng-dev libtiff-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install libv4l-dev libxvidcore-dev libx264-dev
sudo apt-get install libgtk-3-dev
sudo apt-get install libatlas-base-dev gfortran
sudo apt-get install python3-dev
2.下载opencv源码
cd ~
wget -O opencv.zip https://github.com/opencv/opencv/archive/4.2.0.zip
wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.2.0.zip
unzip opencv.zip
unzip opencv_contrib.zip
mv opencv-4.2.0 opencv
mv opencv_contrib-4.2.0 opencv_contrib
3.Determine CUDA architecture version
进到链接https://developer.nvidia.com/cuda-gpus,找到对应NVIDIA GPU的Compute Capability 版本,等下配置安装的时候有用。
比如,我的GPU是GeForce GTX 1060,对应的Compute Capability是:6.1
可以在终端输入命令查看GPU类型
nvidia-smi
显示
$ nvidia-smi
Thu Mar 12 13:36:44 2020
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 410.78 Driver Version: 410.78 CUDA Version: 10.0 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GTX 106... Off | 00000000:01:00.0 On | N/A |
| 27% 42C P8 10W / 120W | 652MiB / 6075MiB | 1% Default |
+-------------------------------+----------------------+----------------------+
4.配置安装
cd ~/opencv
mkdir build
cd build
sudo cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D INSTALL_PYTHON_EXAMPLES=ON -D INSTALL_C_EXAMPLES=ON -D OPENCV_ENABLE_NONFREE=ON -D WITH_CUDA=ON -D WITH_CUDNN=ON -D OPENCV_GENERATE_PKGCONFIG=ON -D OPENCV_DNN_CUDA=ON -D ENABLE_FAST_MATH=1 -D CUDA_FAST_MATH=1 -D CUDA_ARCH_BIN=6.1 -D WITH_CUBLAS=1 -D OPENCV_EXTRA_MODULES_PATH=~/Desktop/opencv_contrib/modules -D HAVE_opencv_python3=ON -D PYTHON_EXECUTABLE=~/.virtualenvs/opencv_cuda/bin/python -D BUILD_EXAMPLES=ON -D CUDA_CUDA_LIBRARY=/usr/local/cuda-10.0/lib64/stubs/libcuda.so ..
cmake配置说明:
1)修改OPENCV_EXTRA_MODULES_PATH和CUDA_CUDA_LIBRARY到对应的路径
2)opencv4以上默认不生成opencv.pc,所以需要指定OPENCV_GENERATE_PKGCONFIG=ON才能生成对应版本的opencv4.pc,才能通过g++链接编译,opencv安装完成后,可以到/usr/local/lib/pkgconfig/
路径下查看,如果装了多个版本的opencv,在使用g++编译时可以指定版本:
g++ xxxx.cpp -o xxxx `pkg-config --cflags --libs opencv4`
如果安装的是opencv4以下,默认生成的应该是opencv.pc,则g++编译时改为:
g++ xxxx.cpp -o xxxx `pkg-config --cflags --libs opencv`
3)CUDA_ARCH_BIN=6.1 这里的版本必须要指定对,否则就算安装成功了,也无法调用GPU,而6.1就是上面第3点介绍的Compute Capability 版本。
5.cmake成功后开始编译安装
sudo make -j8
sudo make install
sudo ldconfig
6.将opencv的库添加到路径
参考https://blog.csdn.net/broliao/article/details/104718030
sudo gedit /etc/ld.so.conf.d/opencv.conf
执行此命令后打开的可能是一个空白的文件,不用管,只需要在文件末尾添加:
/usr/local/lib
保存后更新
sudo ldconfig
7.配置bash
sudo gedit /etc/bash.bashrc
在最末尾添加
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH
保存,执行如下命令使得配置生效
source /etc/bash.bashrc
更新
sudo updatedb
8.为python创建opencv 的 link
如果不需要使用python的接口,这部可以省略,上面关于opencv-python的配置也可以不要,如果要使用python接口的话,需要将编译好的opencv的so文件链接起来,链接过程如下:
1)查看so文件:
进到目录/usr/local/lib/python3.6/dist-packages/cv2/python-3.6/
下,应该会有类似cv2.cpython-36m-x86_64-linux-gnu.so
的文件,该文件就是我们要找的so文件。
2)创建链接
cd /usr/local/lib/python3.6/dist-packages
sudo ln -s /usr/local/lib/python3.6/dist-packages/cv2/python-3.6/cv2.cpython-36m-x86_64-linux-gnu.so cv2.so
9.测试
python:
broliao@ljx:~$ python3
Python 3.6.9 (default, Nov 7 2019, 10:44:02)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'4.2.0'
>>>
c++:
参考https://blog.csdn.net/broliao/article/details/104718030
10.在使用时,通过设置如下参数来选择使用GPU还是CPU
GPU:
Net net = readNet(modelPath, configPath, framework);
net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
CPU:
Net net = readNet(modelPath, configPath, framework);
net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
文章相关参考:
https://www.pyimagesearch.com/2020/02/03/how-to-use-opencvs-dnn-module-with-nvidia-gpus-cuda-and-cudnn/
https://blog.csdn.net/broliao/article/details/104718030