视频截帧+光流 基于CUDA9+OpenCV3
在计算机视觉领域中,视频算法是重要的一个部分,不同于图像,视频需要含有时序特征的多帧图像,同时,还包括一定的运动信息,如光流。在预处理时,需要将视频中的图像和光流提取出来,开源工程dense_flow已经实现这个功能,支持GPU操作。
在CUDA 9和OpenCV 3中,配置dense_flow工程,高级版本temporal-segment-networks。同时,推荐视频的Benchmark工程mmaction。
参考:
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的编译步骤如下:
- 下载opencv,下载opencv_contrib;
- 修改2个cmake文件,和1个hpp文件;
- 修改hdf5、ffmpeg、nonfree(可选);
- make,安装opencv;
OpenCV 3
CUDA 9不支持OpenCV2.x,只能选用3.x,如3.1.0,参考
CUDA9OpenCV源码
下载OpenCV源码文件,并解压:
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文件,并解压:
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,参考。
Error:
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文件夹中:
- 869956383.mp4为测试视频,建立tmp文件夹。
- 执行命令,注意空格全部替换为“=”,参考和参考。
- 在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输出结果:
ResultGPU使用情况
GPUOK, that's all! Enjoy it!