視頻截幀+光流 基於CUDA9+OpenCV3

在計算機視覺領域中,視頻算法是重要的一個部分,不一樣於圖像,視頻須要含有時序特徵的多幀圖像,同時,還包括必定的運動信息,如光流。在預處理時,須要將視頻中的圖像和光流提取出來,開源工程dense_flow已經實現這個功能,支持GPU操做。python

在CUDA 9和OpenCV 3中,配置dense_flow工程,高級版本temporal-segment-networks。同時,推薦視頻的Benchmark工程mmactiongit

參考:github

dense_flow: https://github.com/yjxiong/dense_flow
temporal-segment-networks: https://github.com/yjxiong/temporal-segment-networks
mmaction: https://github.com/open-mmlab/mmaction
複製代碼

編譯OpenCV

OpenCV的編譯步驟以下:算法

  1. 下載opencv,下載opencv_contrib;
  2. 修改2個cmake文件,和1個hpp文件;
  3. 修改hdf五、ffmpeg、nonfree(可選);
  4. make,安裝opencv;

OpenCV 3

CUDA 9不支持OpenCV2.x,只能選用3.x,如3.1.0,參考ubuntu

CUDA9

OpenCV源碼

下載OpenCV源碼文件,並解壓:bash

wget https://github.com/opencv/opencv/archive/3.1.0.zip

unzip 3.1.0.zip

cd opencv-3.1.0
複製代碼

opencv_contrib

在opencv-3.1.0中,下載opencv_contrib文件,並解壓:ide

wget https://github.com/opencv/opencv_contrib/archive/3.1.0.zip

unzip 3.1.0.zip
複製代碼

位置以下:測試

opencv_contrib

緣由是,SURF或SIFT算法移入opencv_contrib,須要參於源碼編譯,在dense_flow中,調用SURF算法,不然沒法找到SURF,參考ui

Error:this

undefined reference to `cv::xfeatures2d::SURF::create(double, int, int, bool, bool)'
複製代碼

修改cmake文件

CMake Error:

CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
CUDA_nppi_LIBRARY (ADVANCED)
複製代碼

緣由是,nppi已經廢棄,須要替換其餘的CUDA,同時,CUDA 2.0已經不兼容當前版本,須要刪除。

須要修改cmake文件夾下的FindCUDA.cmake和OpenCVDetectCUDA.cmake,還有修改common.hpp。

修改FindCUDA.cmake文件,3處替換:

替換

find_cuda_helper_libs(nppi)
複製代碼

find_cuda_helper_libs(nppial)
  find_cuda_helper_libs(nppicc)
  find_cuda_helper_libs(nppicom)
  find_cuda_helper_libs(nppidei)
  find_cuda_helper_libs(nppif)
  find_cuda_helper_libs(nppig)
  find_cuda_helper_libs(nppim)
  find_cuda_helper_libs(nppist)
  find_cuda_helper_libs(nppisu)
  find_cuda_helper_libs(nppitc)
複製代碼

替換

set(CUDA_npp_LIBRARY "${CUDA_nppc_LIBRARY};${CUDA_nppi_LIBRARY};${CUDA_npps_LIBRARY}")
複製代碼

set(CUDA_npp_LIBRARY "${CUDA_nppc_LIBRARY};${CUDA_nppial_LIBRARY};${CUDA_nppicc_LIBRARY};${CUDA_nppicom_LIBRARY};${CUDA_nppidei_LIBRARY};${CUDA_nppif_LIBRARY};${CUDA_nppig_LIBRARY};${CUDA_nppim_LIBRARY};${CUDA_nppist_LIBRARY};${CUDA_nppisu_LIBRARY};${CUDA_nppitc_LIBRARY};${CUDA_npps_LIBRARY}")
複製代碼

替換

unset(CUDA_nppi_LIBRARY CACHE)
複製代碼

unset(CUDA_nppial_LIBRARY CACHE)
  unset(CUDA_nppicc_LIBRARY CACHE)
  unset(CUDA_nppicom_LIBRARY CACHE)
  unset(CUDA_nppidei_LIBRARY CACHE)
  unset(CUDA_nppif_LIBRARY CACHE)
  unset(CUDA_nppig_LIBRARY CACHE)
  unset(CUDA_nppim_LIBRARY CACHE)
  unset(CUDA_nppist_LIBRARY CACHE)
  unset(CUDA_nppisu_LIBRARY CACHE)
  unset(CUDA_nppitc_LIBRARY CACHE)
複製代碼

修改OpenCVDetectCUDA.cmake文件,2處刪除:

將"Fermi"註釋,將"Kepler"提早,即刪除"Fermi"的if分支,主要是爲了刪除CUDA的2.0版本兼容。

set(__cuda_arch_ptx "")
  if(CUDA_GENERATION STREQUAL "Fermi")
    set(__cuda_arch_bin "2.0")
  elseif(CUDA_GENERATION STREQUAL "Kepler")
    set(__cuda_arch_bin "3.0 3.5 3.7")
複製代碼

修改成

set(__cuda_arch_ptx "")
  if(CUDA_GENERATION STREQUAL "Kepler")
    set(__cuda_arch_bin "3.0 3.5 3.7")
複製代碼

在CUDA版本大於6.5時,刪除2.0版本的兼容,修改完成以下:

elseif(${CUDA_VERSION} VERSION_GREATER "6.5")
        set(__cuda_arch_bin "3.0 3.5")
複製代碼

opencv-3.1.0/modules/cudev/include/opencv2/cudev/common.hpp的頭文件中,添加:

#include <cuda_fp16.h>
複製代碼

參考

hdf5 error

Error:

hdf5.hpp:40:18: fatal error: hdf5.h: No such file or directory
複製代碼

修改opencv-3.1.0/modules/python/common.cmake文件,在文件頭部中,添加

find_package(HDF5)
include_directories(${HDF5_INCLUDE_DIRS})
複製代碼

參考

nonfree error

Error:

fatal error: opencv2/nonfree/nonfree.hpp: No such file or directory
複製代碼

安裝包libopencv-nonfree-dev:

sudo apt-get update
sudo add-apt-repository --yes ppa:xqms/opencv-nonfree
sudo apt-get update
sudo apt-get install libopencv-nonfree-dev
複製代碼

若是不成功,更換ppa的源:

sudo add-apt-repository --remove ppa:xqms/opencv-nonfree
sudo add-apt-repository --yes ppa:jeff250/opencv
sudo apt-get update
sudo apt-get install libopencv-dev
sudo apt-get install libopencv-nonfree-dev
複製代碼

參考參考

ffmpeg error

Error:

c->flags |= CODEC_FLAG_GLOBAL_HEADER
複製代碼

opencv-3.1.0/modules/videoio/src/cap_ffmpeg_impl.hpp中,添加:

#define AV_CODEC_FLAG_GLOBAL_HEADER (1 << 22)
#define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER
#define AVFMT_RAWPICTURE 0x0020
複製代碼

參考

make

執行make操做,在OPENCV_EXTRA_MODULES_PATH中,須要引入opencv_contrib

make -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D OPENCV_EXTRA_MODULES_PATH=/data1/wcl/workspace/opencv-3.1.0/opencv_contrib-3.1.0/modules/ ..
複製代碼

執行make,32進程:

make -j32  
複製代碼

安裝,而且將opencv導入系統環境。

sudo make install  
sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig
複製代碼

編譯DenseFlow

參考

安裝libzip-dev

apt-get install libzip-dev
複製代碼

下載dense_flow工程,切換OpenCV的3.1分支:

git clone --recursive http://github.com/yjxiong/dense_flow
git checkout remotes/origin/opencv-3.1
複製代碼

指定OpenCV_DIR,編譯工程:

mkdir build && cd build
OpenCV_DIR=/opencv-3.1.0/build cmake .. -DCUDA_USE_STATIC_CUDA_RUNTIME=OFF
make -j32
複製代碼

編譯成功以後,在build文件夾中:

  1. 869956383.mp4爲測試視頻,創建tmp文件夾。
  2. 執行命令,注意空格所有替換爲「=」,參考參考
  3. 在tmp文件夾中,生成視頻幀以image前綴,x軸光流以flow_x前綴,y軸光流以flow_y前綴,其他參數參考
./extract_gpu -f=980044841.mp4 -x=./tmp/flow_x -y=./tmp/flow_y -i=./tmp/image -b=20 -t=1 -d=0 -s=1 -o=dir
複製代碼

Error,提示沒法打開視頻,將空格替換爲「=」便可。

FATAL [default] Check failed: [video_stream.isOpened()]
複製代碼

測試視頻:

Test

輸出結果:

Result

GPU使用狀況

GPU


OK, that's all! Enjoy it!

相關文章
相關標籤/搜索