Opencv with ffmpeg and cuda support

Opencv with ffmpeg and cuda support

our goal is make opencv cuda support python2, python3 and C++

env:

  1. Ubuntu 14.04
  2. OpenCV 3.0.0
  3. ffmpeg version N-80901-gfebc862
  4. CUDA tookit 7.5

requirement:

  1. NVIDIA graphic card(capable with cuda)
  2. webcam(if you want to develop with opencv)

install dependency

  1. cuda tookit
sudo dpkg -i cuda-repo-ubuntu1404_7.5-18_amd64.deb
sudo apt-get update
sudo apt-get install cuda

add path to system env variables, and nvidia-352 may not the same as you it depend on what your graphic card is.

echo '\nexport PATH=/usr/local/cuda-7.5/bin:$PATH\nLD_LIBRARY_PATH="/usr/local/cuda/lib64"\n' >> ~/.bashrc
su -c 'ln -s /usr/lib/nvidia-352/libnvcuvid.so /usr/lib/libnvcuvid.so && ln -s /usr/lib/nvidia-352/libnvcuvid.so.1 /usr/lib/libnvcuvid.so.1'

add to path, that make system can find and use it

add in ``~/.bashrc`

PATH="...:/usr/local/cuda/bin"
LD_LIBRARY_PATH="/usr/local/cuda/lib64"

and reload it

source ~/.bashrc
  1. install dependency packages
sudo apt-get install build-essential git pkg-config libopencv-dev build-essential checkinstall cmake yasm libtiff4-dev libjpeg-dev libjasper-dev libavcodec-dev libavformat-dev libswscale-dev libdc1394-22-dev libxine-dev libv4l-dev python-dev python-numpy libtbb-dev libqt4-dev libgtk2.0-dev libfaac-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev x264 v4l-utils  libjpeg8-dev libpng12-dev

opengl

sudo apt-get install freeglut3 freeglut3-dev libglew1.5 libglew1.5-dev libglu1-mesa libglu1-mesa-dev libgl1-mesa-glx libgl1-mesa-dev -y

FFMPEG

sudo add-apt-repository ppa:mc3man/trusty-media
sudo apt-get update
sudo sudo apt-get install libatlas-base-dev ffmpeg -y

QT5

wget http://download.qt.io/official_releases/qt/5.7/5.7.0/qt-opensource-linux-x64-5.7.0.run
chmod +x qt-opensource-linux-x64-5.7.0.run
./qt-opensource-linux-x64-5.7.0.run
sudo apt-get install build-essential
sudo apt-get install libfontconfig1
sudo apt-get install mesa-common-dev
sudo apt-get install libglu1-mesa-dev -y
  1. python config
sudo apt-get install python-pip python3-pip
sudo apt-get install python-dev python-numpy
sudo apt-get install python3-dev python3-numpy
sudo pip3 install virtualenv virtualenvwrapper

add below in ~/.bashrc

export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh

reload

source ~/.bashrc

mkvirtualenv virtualenv_name

  1. compile and install opencv
cd && git clone https://github.com/Itseez/opencv.git && cd opencv && git checkout 3.0.0
# extra module  
cd && git clone https://github.com/Itseez/opencv_contrib.git && cd opencv_contrib && git checkout 3.0.0
cd && cd opencv && mkdir build
cd build

we are in the build folder, ready to build

cmake -D CMAKE_BUILD_TYPE=RELEASE \
    -D CMAKE_INSTALL_PREFIX=/usr/local \
    -D INSTALL_C_EXAMPLES=ON \
    -D INSTALL_PYTHON_EXAMPLES=ON \
    -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \
    -D WITH_CUDA=ON \
    -D ENABLE_FAST_MATH=1 \
    -D CUDA_FAST_MATH=1 \
    -D WITH_CUBLAS=1 \
    -D WITH_TBB=ON \
    -D WITH_V4L=ON \
    -D WITH_QT=ON \
    -D WITH_OPENGL=ON \
            -D WITH_IPP=ON \
    -D BUILD_NEW_PYTHON_SUPPORT=ON \
    -D WITH_NVCUVID=ON \
    -D BUILD_EXAMPLES=ON ..

build and install, the -j “with processor core number”, that make the build process faster,

I spend around 15 mins to build undert the enviorments CPU i7-5820

sudo make -j12 install

after installed, we need to add path to system envriorments variable

sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig
printf '# OpenCV\nPKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig\nexport PKG_CONFIG_PATH\n' >> ~/.bashrc
source ~/.bashrc

compile source code, that use cuda

#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>

#include "tick_meter.hpp"

int main(int argc, const char* argv[])
{
    if (argc != 2)
        return -1;

    const std::string fname(argv[1]);

    cv::namedWindow("CPU", cv::WINDOW_NORMAL);
    cv::namedWindow("GPU", cv::WINDOW_OPENGL);
    cv::cuda::setGlDevice();

    cv::Mat frame;
    cv::VideoCapture reader(fname);

    cv::cuda::GpuMat d_frame;
    cv::Ptr<cv::cudacodec::VideoReader> d_reader = cv::cudacodec::createVideoReader(fname);

    TickMeter tm;
    std::vector<double> cpu_times;
    std::vector<double> gpu_times;

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

        tm.reset(); tm.start();
        if (!d_reader->nextFrame(d_frame))
            break;
        tm.stop();
        gpu_times.push_back(tm.getTimeMilli());

        cv::imshow("CPU", frame);
        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 << std::endl;
        std::cout << "GPU : Avg : " << gpu_avg << " ms FPS : " << 1000.0 / gpu_avg << std::endl;
    }

    return 0;
}

#else

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

#endif
g++ source -o output -L/usr/local/cuda/lib64/ -lcuda -lcudart `pkg-config --cflags --libs opencv`

Note:

this manner is also apply to version3.1,

but I switch to 3.1, occur compiling code with opencv - /usr/bin/ld: cannot find -lippicv

that compile don’t know the path of lib ippicv, so either link or copy to well know path, or add to path

sudo cp /usr/local/share/OpenCV/3rdparty/lib/libippicv.a /usr/local/lib/