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> void draw (void ) { glClearColor (0 ,1 ,0 ,1 ); glClear (GL_COLOR_BUFFER_BIT ); glFlush (); } int main (int argc, char **argv) { glutInit (&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB ); glutInitWindowPosition (50 ,25 ); glutInitWindowSize (500 ,250 ); glutCreateWindow ("Green window" ); 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性能的例子:
执行之后首先它会显示出来你的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