1. 程式人生 > 其它 >FFmpeg(GPU)-CUDA11.1-CUDNN8-OpenCV4.2(GPU)-Ubuntu18.04構建docker映象

FFmpeg(GPU)-CUDA11.1-CUDNN8-OpenCV4.2(GPU)-Ubuntu18.04構建docker映象

FFmpeg(GPU)-CUDA11.1-CUDNN8-OpenCV4.2(GPU)-Ubuntu18.04構建docker映象

apt-get update -y
# apt-get remove -y x264 libx264-dev
apt-get install -y build-essential checkinstall cmake pkg-config yasm
apt-get install -y git gfortran
add-apt-repository -y "deb http://security.ubuntu.com/ubuntu xenial-security main"
apt-get install -y libjpeg8-dev libjasper-dev libpng12-dev
apt-get install -y libtiff5-dev
apt-get install -y libavcodec-dev libavformat-dev libswscale-dev libdc1394-22-dev
apt-get install -y libxine2-dev libv4l-dev
apt-get install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
apt-get install -y qt5-default libgtk2.0-dev libtbb-dev

apt-get install -y libatlas-base-dev
apt-get install -y libfaac-dev libmp3lame-dev libtheora-dev
apt-get install -y libvorbis-dev libxvidcore-dev
apt-get install -y libopencore-amrnb-dev libopencore-amrwb-dev
apt-get install -y x264 v4l-utils
  • 如x264安裝失敗,可編譯安裝,x264編譯安裝
git clone https://code.videolan.org/videolan/x264.git
cd x264
sudo ./configure --enable-shared --disable-asm
make && make install
  • 其他依賴
apt-get install -y libprotobuf-dev protobuf-compiler
apt-get install -y libgoogle-glog-dev libgflags-dev
apt-get install -y libgphoto2-dev libeigen3-dev libhdf5-dev doxygen
  • OPENGL 支援依賴庫
apt-get install mesa-common-dev libgtkglext1 libgtkglext1-dev freeglut3-dev

注意:可能出現freeglut3-dev無法安裝這裡我有安裝包直接:freeglut3-dev_2.8.1-3_amd64.deb,freeglut3_2.8.1-3_amd64.deb

dpkg -i <安裝包名稱即可.deb>
  • 以下相關下載依賴包可以通過這裡連結下載, 提取碼:ip1a

  • Opencv和OpencvContrib下載

git clone https://github.com/opencv/opencv.git --branch=4.2.0
git clone https://github.com/opencv/opencv_contrib.git --branch=4.2.0
  • 編譯安裝
cd opencv
mkdir build
cd build

cmake -D CMAKE_INSTALL_PREFIX=/usr/local/opencv-4.2.0 \
-D CMAKE_BUILD_TYPE=Debug \
-D OPENCV_EXTRA_MODULES_PATH=/opt/opencv_base/opencv_contrib/modules \
-D BUILD_opencv_python3=ON \
-D PYTHON_DEFAULT_EXECUTABLE=$(python3 -c "import sys; print(sys.executable)") \
-D BUILD_opencv_python2=OFF \
-D PYTHON3_EXECUTABLE=$(python -c "import sys; print(sys.executable)") \
-D PYTHON3_NUMPY_INCLUDE_DIRS=$(python3 -c "import numpy; print(numpy.get_include())") \
-D PYTHON3_PACKAGES_PATH=$(python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())") \
-D BUILD_opencv_hdf=OFF \
-D WITH_CUDA=ON \
-D WITH_OPENGL=ON \
-D WITH_OPENMP=ON \
-D WITH_GTK=ON \
-D WITH_VTK=ON -D WITH_TBB=ON \
-D WITH_GSTREAMER=ON \
-D WITH_CUDNN=ON \
-D WITH_CUBLAS=ON \
-D WITH_GTK_2_X=ON \
-D BUILD_EXAMPLES=ON \
-D OPENCV_ENABLE_NONFREE=ON \
-D WITH_FFMPEG=ON \
-D OPENCV_GENERATE_PKGCONFIG=ON \
-D WITH_NVCUVID=ON \
-D CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-11.1 \
-D CUDA_ARCH_BIN=5.3,6.0,6.1,7.0,7.5 \
-D CUDA_ARCH_PTX=7.5 \
-D CUDA_nppicom_LIBRARY=stdc++ \
..
  • 編譯註意事項:

1.cmake選項注意:

-D WITH_OPENGL=ON #開啟OPENGL,必須

-D WITH_GTK_2_X=ON #必須,否則OPENGL無法開啟

-D BUILD_EXAMPLES=ON #用於後續驗證GPU編解碼

-D WITH_NVCUVID=ON #用於安裝顯示卡編解碼相關庫 必須

2.docker中配置問題 無NVCUVID解決辦法: 需要將host(主機)中的libnvcuvid.so與libnvcuvid.so.1 libnvcuvid.so.4XX.XX.X(庫的實體)放入到docker的/usr/lib/x86_64-linux-gnu/路徑下,並在docker中建立軟連線,具體操作

ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so.450.80.02 /usr/lib/x86_64-linux-gnu/libnvcuvid.so.1
ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so.1 /usr/lib/x86_64-linux-gnu/libnvcuvid.so
sudo ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so /usr/lib/libnvcuvid.so
sudo ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so.1 /usr/lib/libnvcuvid.so.1

# 將宿主機libnvcuvid.so.470.103.01 拷貝到 容器的 /usr/lib/x86_64-linux-gnu 下
docker cp /usr/lib/x86_64-linux-gnu/libnvcuvid.so.470.103.01 5d74c5af2bc8:/usr/lib/x86_64-linux-gnu
# 建立軟連線
ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so.470.103.01 /usr/lib/x86_64-linux-gnu/libnvcuvid.so.1
ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so.1 /usr/lib/x86_64-linux-gnu/libnvcuvid.so
ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so /usr/lib/libnvcuvid.so
ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so.1 /usr/lib/libnvcuvid.so.1

3.boostdesc_bgm.i相關下載:,將資源下載解壓拷貝到opencv_contrib/modules/xfeatures2d/src/目錄下,然後更改opencv_contrib/modules/xfeatures2d/cmake/下路徑

$ cd opencv_contrib/modules/xfeatures2d/src/
# 將 download_boostdesc.cmake 更換 https://raw.githubusercontent.com/opencv/opencv_3rdparty/${OPENCV_3RDPARTY_COMMIT}/ 為 file:///opt/opencv_base/opencv_contrib/modules/xfeatures2d/src/boostdesc_bgm 
#  download_vgg.cmake 也同理

4.face_landmark_model.dat提前下載好face_landmark_model.dat,並放入映象中

vi opencv_contrib/modules/face/CMakeLists.txt
將https://raw.githubusercontent.com 替換為  file:///opt/opencv_base/face_landmark_model/

5.ippicv下載, 提期下載好ippicv_2019_lnx_intel64_general_20180723.tgz,並放入映象中

vi opencv/3rdparty/ippicv/ippicv.cmake 
https://raw.githubusercontent.com/opencv/opencv_3rdparty/${IPPICV_COMMIT}/ippicv/ 修改為
/opt/opencv_base/ippicv/
  • 參考
cmake -D CMAKE_BUILD_TYPE=RELEASE \
	-D PYTHON_DEFAULT_EXECUTABLE=$(python3 -c "import sys; print(sys.executable)") \
	-D PYTHON3_EXECUTABLE=$(python -c "import sys; print(sys.executable)") \
	-D PYTHON3_NUMPY_INCLUDE_DIRS=$(python -c "import numpy; print(numpy.get_include())") \
	-D PYTHON3_PACKAGES_PATH=$(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())") \
	-D CMAKE_INSTALL_PREFIX=/usr/local \
	-D WITH_TBB=ON \
	-D WITH_V4L=ON \
	-D WITH_OPENGL=ON \
	-D WITH_CUDA=ON \
	-D WITH_CUDNN=ON \
	-D ENABLE_FAST_MATH=1 \
	-D CUDA_FAST_MATH=1 \
	-D CUDA_NVCC_FLAGS="-D_FORCE_INLINES" \
	-D CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-11.1 \
	-D WITH_NVCUVID=ON \
	-D CUDA_ARCH_BIN=5.3,6.0,6.1,7.0,7.5 \
	-D CUDA_ARCH_PTX=7.5 \
	-D WITH_CUBLAS=1 \
	-D OPENCV_EXTRA_MODULES_PATH=/opt/opencv_base/opencv_contrib/modules \
	-D CUDA_nppicom_LIBRARY=stdc++ \
	-D WITH_OPENMP=ON \
	-D CUDA_nppicom_LIBRARY=stdc++ \
	..
  • cmake結果
--     Disabled:                    hdf world
--     Disabled by dependency:      -
--     Unavailable:                 cnn_3dobj cvv java js matlab ovis python2 viz xfeatures2d
--     Applications:                tests perf_tests examples apps
--     Documentation:               NO
--     Non-free algorithms:         YES
-- 
--   GUI: 
--     GTK+:                        YES (ver 2.24.32)
--       GThread :                  YES (ver 2.56.4)
--       GtkGlExt:                  YES (ver 1.2.0)
--     OpenGL support:              YES (/usr/lib/x86_64-linux-gnu/libGL.so /usr/lib/x86_64-linux-gnu/libGLU.so)
--     VTK support:                 NO
-- 
--   Media I/O: 
--     ZLib:                        /usr/lib/x86_64-linux-gnu/libz.so (ver 1.2.11)
--     JPEG:                        /usr/lib/x86_64-linux-gnu/libjpeg.so (ver 80)
--     WEBP:                        build (ver encoder: 0x020e)
--     PNG:                         /usr/lib/x86_64-linux-gnu/libpng.so (ver 1.6.34)
--     TIFF:                        /usr/lib/x86_64-linux-gnu/libtiff.so (ver 42 / 4.0.9)
--     JPEG 2000:                   /usr/lib/x86_64-linux-gnu/libjasper.so (ver 1.900.1)
--     OpenEXR:                     build (ver 2.3.0)
--     HDR:                         YES
--     SUNRASTER:                   YES
--     PXM:                         YES
--     PFM:                         YES
-- 
--   Video I/O:
--     DC1394:                      YES (2.2.5)
--     FFMPEG:                      YES
--       avcodec:                   YES (57.107.100)
--       avformat:                  YES (57.83.100)
--       avutil:                    YES (55.78.100)
--       swscale:                   YES (4.8.100)
--       avresample:                NO
--     GStreamer:                   YES (1.14.5)
--     v4l/v4l2:                    YES (linux/videodev2.h)
-- 
--   Parallel framework:            TBB (ver 2017.0 interface 9107)
-- 
--   Trace:                         YES (with Intel ITT)
-- 
--   Other third-party libraries:
--     Intel IPP:                   2019.0.0 Gold [2019.0.0]
--            at:                   /opt/opencv_base/opencv/build/3rdparty/ippicv/ippicv_lnx/icv
--     Intel IPP IW:                sources (2019.0.0)
--               at:                /opt/opencv_base/opencv/build/3rdparty/ippicv/ippicv_lnx/iw
--     Lapack:                      NO
--     Eigen:                       YES (ver 3.3.4)
--     Custom HAL:                  NO
--     Protobuf:                    build (3.5.1)
-- 
--   NVIDIA CUDA:                   YES (ver 11.1, CUFFT CUBLAS NVCUVID)
--     NVIDIA GPU arch:             53 60 61 70 75
--     NVIDIA PTX archs:            75
-- 
--   cuDNN:                         NO
-- 
--   OpenCL:                        YES (no extra features)
--     Include path:                /opt/opencv_base/opencv/3rdparty/include/opencl/1.2
--     Link libraries:              Dynamic load
-- 
--   Python 3:
--     Interpreter:                 /usr/bin/python (ver 3.6.9)
--     Libraries:                   /usr/lib/x86_64-linux-gnu/libpython3.6m.so (ver 3.6.9)
--     numpy:                       /usr/local/lib/python3.6/dist-packages/numpy/core/include (ver 1.16.1)
--     install path:                /usr/lib/python3/dist-packages/cv2/python-3.6
-- 
--   Python (for build):            /usr/bin/python3
-- 
--   Java:                          
--     ant:                         NO
--     JNI:                         NO
--     Java wrappers:               NO
--     Java tests:                  NO
-- 
--   Install to:                    /usr/local/opencv-4.2.0
-- -----------------------------------------------------------------
-- 
-- Configuring done
-- Generating done
-- Build files have been written to: /opt/opencv_base/opencv/build
  • make
make -j8

編譯報錯:feature2d/test/test_detectors_regression.impl.hpp

# 報錯feature2d/test/test_detectors_regression.impl.hpp
# 操作:將opencv/modules/features2d拷貝到,build下
# cd目錄下/opt/opencv_base/opencv/build
cp -r ../../opencv/modules/features2d/ .

編譯報錯:/opt/opencv_base/opencv/samples/gpu/surf_keypoint_matcher.cpp fatal error: opencv2/xfeatures2d/cuda.hpp: No such file or directory include "opencv2/xfeatures2d/cuda.hpp"

vi /opt/opencv_base/opencv/samples/gpu/surf_keypoint_matcher.cpp

將#include "opencv2/xfeatures2d/cuda.hpp" 改為  #include "/opt/opencv_base/opencv_contrib/modules/xfeatures2d/include/opencv2/xfeatures2d/cuda.hpp"

編譯報錯SURF_CUDA::SURF_CUDA解決方法1:/opt/opencv_base/opencv/samples/gpu/surf_keypoint_matcher.cpp:53: undefined reference to cv::cuda::SURF_CUDA::SURF_CUDA()參考 親測有效

vi /opt/opencv_base/opencv/build/samples/gpu/CMakeFiles/example_gpu_surf_keypoint_matcher.dir/link.txt 

# 將 CMakeFiles/example_gpu_surf_keypoint_matcher.dir/surf_keypoint_matcher.cpp.o 替換成如下
--as-needed CMakeFiles/example_gpu_surf_keypoint_matcher.dir/surf_keypoint_matcher.cpp.o ../../modules/xfeatures2d/CMakeFiles/opencv_xfeatures2d.dir/src/surf.cuda.cpp.o ../../modules/xfeatures2d/CMakeFiles/cuda_compile_1.dir/src/cuda/cuda_compile_1_generated_surf.cu.o

編譯報錯SURF_CUDA::SURF_CUDA解決方法2:/opt/opencv_base/opencv/samples/gpu/surf_keypoint_matcher.cpp:53: undefined reference to cv::cuda::SURF_CUDA::SURF_CUDA()參考 沒有親測

# 找到opencv下CMAKELists.txt更改
OCV_OPTION(OPENCV_ENABLE_NONFREE "Enable non-free algorithms" OFF)
# OFF 改為 ON
OCV_OPTION(OPENCV_ENABLE_NONFREE "Enable non-free algorithms" ON)
# 清理
make clean
# 重新cmake 
  • 安裝
make install
  • OpenCV環境變數新增 (到這裡了)
vi /etc/ld.so.conf.d/opencv.conf
	/usr/local/opencv-4.2.0/lib
# 更新
ldconfig
  • 配置bash
vi /etc/bash.bashrc
	//在末尾新增
    PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/opencv-4.2.0/lib/pkgconfig 
    export PKG_CONFIG_PATH

# 儲存退出,然後執行如下命令使得配置生效
source /etc/bash.bashrc
sudo updatedb 
  • 配置本地bash
vi ~/.bashrc
# 在檔案末尾增加以下內容
	export PKG_CONFIG_PATH=/usr/local/opencv-4.2.0/lib/pkgconfig
	export LD_LIBRARY_PATH=/usr/local/opencv-4.2.0/lib
# 更新~/.bashrc
source ~/.bashrc 
  • 檢視openCV版本
pkg-config opencv4 --modversion 
  • 建立opencv4.pc
vi /usr/local/lib/pkgconfig/opencv4.pc

# Package Information for pkg-config
prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir_old=${prefix}/include/opencv4/opencv
includedir_new=${prefix}/include/opencv4

Name: OpenCV
Description: Open Source Computer Vision Library
Version: 4.2.0
Libs: -L${exec_prefix}/lib -lopencv_gapi -lopencv_stitching -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dpm -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hfs -lopencv_img_hash -lopencv_line_descriptor -lopencv_quality -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_superres -lopencv_optflow -lopencv_surface_matching -lopencv_tracking -lopencv_datasets -lopencv_text -lopencv_dnn -lopencv_plot -lopencv_videostab -lopencv_video -lopencv_xfeatures2d -lopencv_shape -lopencv_ml -lopencv_ximgproc -lopencv_xobjdetect -lopencv_objdetect -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_flann -lopencv_xphoto -lopencv_photo -lopencv_imgproc -lopencv_core
Libs.private: -ldl -lm -lpthread -lrt
Cflags: -I${includedir_old} -I${includedir_new}
  • pkg-config測試
pkg-config --cflags --libs opencv4
  • C++指令碼測試

    opencv_cuda.cpp

#include <iostream>

#include "opencv2/opencv_modules.hpp"

#if defined(HAVE_OPENCV_CUDACODEC)

#include <string>
#include <vector>
#include <algorithm>
#include <numeric>

#include <opencv2/core.hpp>
#include <opencv2/core/opengl.hpp>
#include <opencv2/cudacodec.hpp>
#include <opencv2/highgui.hpp>

int main(int argc, const char* argv[])
{
    if (argc != 2)
        return -1;
    std::cout << "1. parse script query" << std::endl;
    
    const std::string fname(argv[1]);

    // cv::namedWindow("CPU", cv::WINDOW_NORMAL);
    
    // cv::namedWindow("GPU", cv::WINDOW_OPENGL);
    // http://cn.voidcc.com/question/p-ehnwpjbe-wb.html
    // cv::cuda::setGlDevice();
    std::cout << "2. set gl device" << std::endl;
    //cv::Mat frame;
    //cv::VideoCapture reader(fname);
    
    cv::cuda::GpuMat d_frame;
    cv::Ptr<cv::cudacodec::VideoReader> d_reader = cv::cudacodec::createVideoReader(fname);
    std::cout << "3.create video" << std::endl;
    cv::TickMeter tm;
    std::vector<double> cpu_times;
    std::vector<double> gpu_times;

    int gpu_frame_count=0, cpu_frame_count=0;

/*
    for (;;)
    {
        tm.reset(); tm.start();
        if (!reader.read(frame))
            break;
        tm.stop();
        cpu_times.push_back(tm.getTimeMilli());
        cpu_frame_count++;

        cv::imshow("CPU", frame);

        if (cv::waitKey(3) > 0)
            break;
    }
*/
    for (;;)
    {
        tm.reset(); tm.start();
        if (!d_reader->nextFrame(d_frame))
            break;
        tm.stop();
        gpu_times.push_back(tm.getTimeMilli());
        gpu_frame_count++;

        // cv::imshow("GPU", d_frame);

        if (cv::waitKey(3) > 0)
            break;
    }

    if (!cpu_times.empty() || !gpu_times.empty())
    {
        std::cout << std::endl << "Results:" << std::endl;

        //std::sort(cpu_times.begin(), cpu_times.end());
        std::sort(gpu_times.begin(), gpu_times.end());

        //double cpu_avg = std::accumulate(cpu_times.begin(), cpu_times.end(), 0.0) / cpu_times.size();
        double gpu_avg = std::accumulate(gpu_times.begin(), gpu_times.end(), 0.0) / gpu_times.size();

        //std::cout << "CPU : Avg : " << cpu_avg << " ms FPS : " << 1000.0 / cpu_avg << " Frames " << cpu_frame_count << std::endl;
        std::cout << "GPU : Avg : " << gpu_avg << " ms FPS : " << 1000.0 / gpu_avg << " Frames " << gpu_frame_count << std::endl;
    }

    return 0;
}

#else

int main()
{
    std::cout << "OpenCV was built without CUDA Video decoding support\n" << std::endl;
    return 0;
}

#endif

註釋掉cv::namedWindowcv::imshow部分 因為是在docker映象執行

註釋掉cv::cuda::setGlDevice 可在這裡找到解釋說明

Makefile編寫

opencv_cuda.o:opencv_cuda.cpp
        g++ -std=c++14 -g -o main.out opencv_cuda.cpp `pkg-config opencv4 --cflags --libs` \
                -I/usr/local/opencv-4.2.0/include/opencv4/opencv2 \
                -I/usr/local/cuda/include \
                -L/usr/local/cuda/lib64 \
                -I/usr/include/eigen3 \
                -L/usr/lib/x86_64-linux-gnu -lcuda -ldl -lnvcuvid
clean:
        rm *.o main.out
  • 執行make

  • 測試

./main.out  rtsp://admin:[email protected]:554