blueyi's notes

Follow Excellence,Success will chase you!

0%

Ubuntu 16.04下编译OpenCV 3.2.0支持Java、FFmpeg以及CUDA8

Ubuntu 16.04下手动编译OpenCV 3.2.0,并提供对FFmpeg以及CUDA 8的支持来使用GPU加速视频图像处理。
考虑到大数据处理系统spark的需要,这里也同时加入opencv对java的支持。

系统为ubuntu 16.04.1 x64服务器版的最小化系统,具体参数如下:

1
2
3
4
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS"

假定已经安装好了CUDA 8,如果还没有安装CUDA 8环境可以参考这里安装Ubuntu 16.04下CUDA8环境配置的2种方法
也需要提前安装好FFmpeg并将其二进制放到环境变量中,如果还没有编译安装好FFmpeg对GPU解码的支持,可以参考这里Ubuntu 16.04下编译ffmpeg支持CUDA下的cuvid vnenc和NPP

还有Java环境也需要提前安装好,如果还没有安装,可以参考ubuntu下2种配置oracle jdk的方法

安装OpenCV依赖包

官方要求的必装包:

1
sudo apt-get install build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev

上面的git如果采用zip方式安装可以不需要,但如果是通过zip方式安装则需要安装上unzip用于解压

官方推荐的可选包:

1
sudo apt-get install  python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev

添加对OpenGL的支持所需要的包:

1
sudo apt-get install freeglut3-dev mesa-common-dev  libgtkglext1 libgtkglext1-dev

添加对Java的支持需要ant:

1
sudo apt-get install ant

其他一些推荐包,包括视频编解码所需要的开发包等:

1
sudo apt-get install checkinstall yasm libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev libv4l-dev libtbb-dev libqt4-dev libgtk2.0-dev libmp3lame-dev libtheora-dev libvorbis-dev libxvidcore-dev x264 v4l-utils

我这里把这些包全部安装上

验证OpenGL的配置

如果不需要OpenGL可以跳过此步
保存如下代码,并命名为testgl.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <GL/glut.h>

//Drawing funciton
void draw(void)
{
//Background color
glClearColor(0,1,0,1);
glClear(GL_COLOR_BUFFER_BIT );
//Draw order
glFlush();
}

//Main program
int main(int argc, char **argv)
{
glutInit(&argc, argv);
//Simple buffer
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB );
glutInitWindowPosition(50,25);
glutInitWindowSize(500,250);
glutCreateWindow("Green window");
//Call to the drawing function
glutDisplayFunc(draw);
glutMainLoop();
return 0;
}

编译:

1
gcc testgl.c -o testgl -lGL -lGLU -lglut

如果编译通过,则表示OpenGl安装成功,运行的话需要有桌面环境,可以通过如下代码为服务器系统安装桌面环境用于测试:

1
sudo apt install ubuntu-desktop

如果需要远程通过VNC在windows上连接ubuntu,可以打开ubuntu上的vino,也就是那个desktop sharing,设置允许远程连接,再在命令行中执行以下语句即可(这些操作要求ubuntu有桌面环境):

1
gsettings set org.gnome.Vino require-encryption false

实际测试代码性能时,为了避免由于桌面占用GPU/CPU影响系统性能,可能使用以下命令禁用桌面

1
2
sudo systemctl disable lightdm
sudo systemctl stop lightdm

第一条命令会让你重启后依然无法进入桌面

需要启用桌面时使用以下命令:

1
2
sudo systemctl enable lightdm
sudo systemctl start lightdm

编译OpenCV

下载OpenCV,可以通过git获取官方最新的版本,然后切换到自己所需要的3.2.0进行编译:

1
2
3
git clone https://github.com/opencv/opencv.git 
cd opencv
git checkout 3.2.0

这里同时安装OpenCV's extra modules

1
2
3
git clone https://github.com/opencv/opencv_contrib.git
cd opencv_contrib
git checkout 3.2.0

为了方便后面验证时的测试,安装OpenCV官方提供的附加测试代码(extra data for the OpenCV library):

1
2
3
git clone https://github.com/opencv/opencv_extra.git
cd opencv_extra
git checkout 3.2.0

进入opencv根目录,创建一个build文件夹,然后进入build文件后执行以下编译代码,注意编译选项上包含了CUDA的支持,NVCUVID的支持,OpenGL的支持,以及对ffmpeg和java的支持,这些内容都需要提前配置好。

由于编译时的第三方库需要在线下载,而且服务器貌似是AWS,所以如果不配置代理,可能会cmake失败。设置代理可以参见:http://notes.maxwi.com/2017/04/01/linux-proxy-ss

cmake选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cmake \
-D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \
-D OPENCV_TEST_DATA_PATH=../../opencv_extra \
-D WITH_CUDA=ON \
-D WITH_CUBLAS=ON \
-D CUDA_FAST_MATH=ON \
-D WITH_CUFFT=ON \
-D WITH_NVCUVID=ON \
-D WITH_V4L=ON \
-D WITH_LIBV4L=ON \
-D WITH_OPENGL=ON \
-D WITH_FFMPEG=ON \
-D INSTALL_C_EXAMPLES=ON \
-D BUILD_EXAMPLES=ON \
-D BUILD_SHARED_LIBS=OFF \
..

更多cmake选项可以查看OpenCV源码目录下的CMakeLists.txt文件内容。
默认你的opencv_contrib目录与opencv根目录同级,指定的OpenCV安装路径为/usr/local/share/OpenCV/
如果你之前的CUDA、支持CUDA, NVCUVID, NVENC的FFmpeg、JAVA以及opengl编译安装的都没有问题的话,cmake输出的最后一部分内容应该如下,注意java显示在OpenCV modules中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
--   OpenCV modules:
-- To be built: cudev core cudaarithm flann imgproc ml reg surface_matching video cudabgsegm cudafilters cudaimgproc cudawarping dnn freetype fuzzy imgcodecs photo shape videoio cudacodec highgui objdetect plot ts xobjdetect xphoto bgsegm bioinspired dpm face features2d line_descriptor saliency text calib3d ccalib cudafeatures2d cudalegacy cudaobjdetect cudaoptflow cudastereo datasets rgbd stereo superres tracking videostab xfeatures2d ximgproc aruco optflow phase_unwrapping stitching structured_light java python2
-- Disabled: world contrib_world
-- Disabled by dependency: -
-- Unavailable: python3 viz cnn_3dobj cvv hdf matlab sfm
--
-- GUI:
-- QT: NO
-- GTK+ 2.x: YES (ver 2.24.30)
-- GThread : YES (ver 2.48.2)
-- GtkGlExt: YES (ver 1.2.0)
-- OpenGL support: YES (/usr/lib/x86_64-linux-gnu/libGLU.so /usr/lib/x86_64-linux-gnu/libGL.so)
-- VTK support: NO
--
-- Media I/O:
-- ZLib: /usr/lib/x86_64-linux-gnu/libz.so (ver 1.2.8)
-- JPEG: /usr/lib/x86_64-linux-gnu/libjpeg.so (ver )
-- WEBP: build (ver 0.3.1)
-- PNG: /usr/lib/x86_64-linux-gnu/libpng.so (ver 1.2.54)
-- TIFF: /usr/lib/x86_64-linux-gnu/libtiff.so (ver 42 - 4.0.6)
-- JPEG 2000: /usr/lib/x86_64-linux-gnu/libjasper.so (ver 1.900.1)
-- OpenEXR: build (ver 1.7.1)
-- GDAL: NO
-- GDCM: NO
--
-- Video I/O:
-- DC1394 1.x: NO
-- DC1394 2.x: YES (ver 2.2.4)
-- FFMPEG: YES
-- avcodec: YES (ver 56.60.100)
-- avformat: YES (ver 56.40.101)
-- avutil: YES (ver 54.31.100)
-- swscale: YES (ver 3.1.101)
-- avresample: NO
-- GStreamer:
-- base: YES (ver 0.10.36)
-- video: YES (ver 0.10.36)
-- app: YES (ver 0.10.36)
-- riff: YES (ver 0.10.36)
-- pbutils: YES (ver 0.10.36)
-- OpenNI: NO
-- OpenNI PrimeSensor Modules: NO
-- OpenNI2: NO
-- PvAPI: NO
-- GigEVisionSDK: NO
-- Aravis SDK: NO
-- UniCap: NO
-- UniCap ucil: NO
-- V4L/V4L2: Using libv4l1 (ver 1.10.0) / libv4l2 (ver 1.10.0)
-- XIMEA: NO
-- Xine: NO
-- gPhoto2: NO
--
-- Parallel framework: pthreads
--
-- Other third-party libraries:
-- Use IPP: 9.0.1 [9.0.1]
-- at: /home/dutoeserver/OpenCV/opencv/build/3rdparty/ippicv/ippicv_lnx
-- Use IPP Async: NO
-- Use VA: NO
-- Use Intel VA-API/OpenCL: NO
-- Use Lapack: NO
-- Use Eigen: YES (ver 3.2.92)
-- Use Cuda: YES (ver 8.0)
-- Use OpenCL: YES
-- Use OpenVX: NO
-- Use custom HAL: NO
--
-- NVIDIA CUDA
-- Use CUFFT: YES
-- Use CUBLAS: YES
-- USE NVCUVID: YES
-- NVIDIA GPU arch: 20 30 35 37 50 52 60 61
-- NVIDIA PTX archs:
-- Use fast math: YES
--
-- OpenCL: <Dynamic loading of OpenCL library>
-- Include path: /home/dutoeserver/OpenCV/opencv/3rdparty/include/opencl/1.2
-- Use AMDFFT: NO
-- Use AMDBLAS: NO
--
-- Python 2:
-- Interpreter: /usr/bin/python2.7 (ver 2.7.12)
-- Libraries: /usr/lib/x86_64-linux-gnu/libpython2.7.so (ver 2.7.12)
-- numpy: /usr/lib/python2.7/dist-packages/numpy/core/include (ver 1.11.0)
-- packages path: lib/python2.7/dist-packages
--
-- Python 3:
-- Interpreter: /usr/bin/python3 (ver 3.5.2)
--
-- Python (for build): /usr/bin/python2.7
--
-- Java:
-- ant: /usr/bin/ant (ver 1.9.6)
-- JNI: /usr/lib/jvm/java-8-oracle/include /usr/lib/jvm/java-8-oracle/include/linux /usr/lib/jvm/java-8-oracle/include
-- Java wrappers: YES
-- Java tests: YES
--
-- Matlab: Matlab not found or implicitly disabled
--
-- Documentation:
-- Doxygen: NO
--
-- Tests and samples:
-- Tests: YES
-- Performance tests: YES
-- C/C++ Examples: YES
--
-- Install path: /usr/local
--
-- cvconfig.h is in: /home/dutoeserver/OpenCV/opencv/build
-- -----------------------------------------------------------------
--
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dutoeserver/OpenCV/opencv/build

从中可以看到我们所添加的编译选项后面都有YES
下面使用make进行编译:

1
make -j $(($(nproc) + 1))

然后便是漫长的编译过程,具体时间根据你的电脑配置而不同,如果没有问题的话,编译会顺利进行。
然后使用make进行安装并配置环境:

1
2
3
sudo make -j $(($(nproc) + 1)) install
sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig

建议上述安装完成之后重启一次系统

可以将上面sudo make install部分换成sudo checkinstall,这样安装完成之后checkinstall会在当前目录生成一个相应的deb,可以二次安装,也可以用sudo dpkg -r xx.deb来卸载
更多checkinstall的用法可以参见IBM的一篇文章:http://www.ibm.com/developerworks/cn/linux/l-cn-checkinstall/

验证

编译完成之后,会在build/bin目录下创建很多例子的二进制文件,可以进行测试。如果该文件夹下没有任何文件,检查你的编译选项是否选择了例子,以及上面的编译是否都已经正确完成。
这里我测试一个gpu性能的例子:

1
bin/performance_gpu

执行之后首先它会显示出来你的GPU信息,然后会经过一段时间的测试,如果你没有提前把opencv_extra下面的测试视频拷贝过来,还会提示一个文件丢失的错误,不过不影响测试。输出内容的最后部分如下:

1
average GPU speedup: x33.717

下面手动编译一个例子
找到OpenCV源代码文件夹下的samples/gpu
里面有很多gpu的示例代码,这里以其中的hog.cpp为例,它的功能就是利用方向梯度直方图(Histogram of oriented gradient)进行目标检测
将该代码单独拷贝到一个文件中,并在该文件夹下创建CMakeLists.txt,内容如下:

1
2
3
4
5
6
7
cmake_minimum_required(VERSION 2.8)
project(HOG)
find_package(OpenCV REQUIRED)
find_package(CUDA REQUIRED)
include_directories("${CUDA_INCLUDE_DIRS}")
add_executable(hog hog.cpp)
target_link_libraries(hog ${OpenCV_LIBS})

然后执行编译:

1
2
3
4
mkdir build
cd build
cmake -D CUDA_USE_STATIC_CUDA_RUNTIME=OFF ..
make

如果环境配置没有问题的话,build文件下就会生成可执行的程序hog,可以通过hog --help查看帮助,下面使用hog来播放视频,或者也可以直接接摄像头:

1
./hog --video ~/input.mp4

输出结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Device 0:  "GeForce GTX 1080"  8112Mb, sm_61, Driver/Runtime ver.8.0/8.0

Controls:
ESC - exit
m - change mode GPU <-> CPU
g - convert image to gray or not
1/q - increase/decrease HOG scale
2/w - increase/decrease levels count
3/e - increase/decrease HOG group threshold
4/r - increase/decrease hit threshold

Scale: 1.05
Group threshold: 8
Levels number: 13
Win width: 48
Win stride: (8, 8)
Hit threshold: 1.4
Gamma correction: 1

可以通过m键来切换使用CPU mode或者CUDA mode。
可以打开nvidia-setting来查看CUDA mode下GPU的占用情况

可能出现的错误

如果出现NVCUVID后面是NO,而CUDA后面是YES

这种情况下将无法使用CUDA编解码功能,这是由于cmake在查找库的时候采用的路径是/usr/lib以及/usr/lib/nvidia-current路径,而实际上我的nvidia显卡驱动安装路径为/usr/lib/nvidia-378,所以导致无法找到这个路径。
PS:为了解决这个问题,查看了opencv的cmake中的相关代码后才发现,但在些之前搜索了很久,也乱试了很久都无果,所以一定要有根据的解决问题,还不是盲目地去试。
解决:

1
2
sudo ln -s /usr/lib/nvidia-378/libnvcuvid.so /usr/lib/libnvcuvid.so
sudo ln -s /usr/lib/nvidia-378/libnvcuvid.so.1 /usr/lib/libnvcuvid.so.1

记得修改成你自己的nvidia驱动安装路径

如果FFmpeg没有YES

可能是你的FFmpeg编译后没有将其添加到环境变量中。

编译OpenCV程序出现cannot find -lopencv_dep_cudart

错误详情:

1
2
3
4
5
6
7
8
/usr/bin/ld: cannot find -lopencv_dep_cudart
collect2: error: ld returned 1 exit status
CMakeFiles/hog.dir/build.make:120: recipe for target 'hog' failed
make[2]: *** [hog] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/hog.dir/all' failed
make[1]: *** [CMakeFiles/hog.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

添加cmake编译选项来解决:

1
cmake -D CUDA_USE_STATIC_CUDA_RUNTIME=OFF ..

编译java版本的OpenCV程序出现NoClassDefFoundError

Exception in thread “main” java.lang.NoClassDefFoundError: org/opencv/core/Core
如果需要配置java调用opencv,需要修改如下配置文件:

1
2
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:/usr/local/share/OpenCV/java/opencv-2413.jar
export LD_LIBRARY_PATH=/usr/local/lib/:/usr/lib/:/usr/local/share/OpenCV/java:$LD_LIBRARY_PATH

编译选项后面显示Unavaialbe里面有Java

需要安装包ant

Welcome to my other publishing channels