最近需要在python的环境下面使用ffmpeg和opencv的GPU版本,因此基于在conda下面创建了一个虚拟环境,然后进行两者的联合编译。
1.前期准备
编译之前需要安装一些需要的原生库,这个教程太多了,就不在这里叙述需要装哪些了的,出现了问题的话,再去装相应的库,包括cuda和cudnn的必要安装。
2.ffmpeg的编译
(1)安装yasm
wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
tar -zxvf yasm-1.3.0.tar.gz
cd yasm-1.3.0
./configure
make && make install
(2)安装nasm,和x264
因为笔者需要解码H.264的视频,所以安装了X264
//下载
wget https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.gz
tar -zxvf nasm-2.15.05.tar.gz
cd nasm-2.15.05/
./configure
make
make install
//libx264安装
git clone https://code.videolan.org/videolan/x264.git
cd x264/
./configure --enable-shared --enable-pthread --enable-pic
make
make install
(3)安装nv-codec-headers
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git
cd nv-codec-headers
sudo make install
后续编译ffmpeg的时候,可能出现:
ERROR: cuda requested, but not all dependencies are satisfied: ffnvcodec的错误,则需要
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:${
PKG_CONFIG_PATH}
改成自己的环境下的路径
(4)ffmpeg
笔者安装的是ffmpeg-4.4.2这个版本的,需要的话可以去官网上直接下载的
tar -zxvf ffmpeg-4.4.2.tar.gz
cd ffmpeg-4.4.2
./configure --enable-libx264 --enable-gpl --enable-shared --extra-cflags=-I/usr/local/include --extra-ldflags=-L/usr/local/lib --enable-pic
make
make install
在这里编译的时候需要把,x264给编译进去,以方便之后的测试。在编译完成ffmpeg之后,在进行opencv编译的时候,可能寻找不到ffmpeg,必须开启这个才能寻找到ffmpeg。
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/ffmpeg/lib/pkgconfig/
测试ffmpeg-GPU是否编译成功的话,使用
ffmpeg -hwaccels
会出现cuda
如果出现ffmpeg: error while loading shared libraries: libx264.so.164: cannot open sh或者ffmpeg: error while loading shared libraries: libavdevice.so.58: cannot open shared object file: No such file or directory的错误,修改ld.so.conf文件
sudo vi /etc/ld.so.conf
/usr/local/ffmpeg/lib
/usr/local/ffmpeg
退出后使之生效
sudo ldconfig
根据自己的路径去定义的。
(4)nvcuvdid编译
下载Video_Codec_SDK_11.1.5.zip文件,地址:
NVIDIA VIDEO CODEC SDK
复制nvcuid/cuviddec头文件
sudo cp ./Video_Codec_SDK_11.0.10/Interface/nvcuvid.h /usr/local/cuda/include
sudo cp ./Video_Codec_SDK_11.0.10/Interface/cuviddec.h /usr/local/cuda/include
(5)opencv-GPU编译
首先你编译的python环境下面必须有numpy
笔者下载的是opencv-4.6.0的版本,opencv_contrib-4.6版本也与之对应。我在opencv-4.6.0解压的路径下面创建了两个文件,build和install,方便编译的后版本放置。
切换到build下进行编译
编译的opencv具体参数如下:
cmake3 -D CMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS} -g -fPIC -O3 -std=c++11 -fopenmp" \
-D CMAKE_BUILD_TYPE=RELEASE \
-D OPENCV_DOWNLOAD_PATH=/opt/open/opencv-cache \ #用于存放ippicv以及下载的一些东西
-D BUILD_TESTS=OFF \
-D BUILD_opencv_dnn=OFF \
-D BUILD_opencv_objdetect=OFF \
-D BUILD_opencv_face=OFF \
-D BUILD_opencv_xfeatures2d=OFF \
-D BUILD_opencv_cudaoptflow=OFF \
-D BUILD_opencv_wechat_qrcode=OFF \
-D BUILD_opencv_cudaobjdetect=OFF \
-D CMAKE_INSTALL_PREFIX=../install \ #最后编译完成的版本会放在这里
-D OPENCV_EXTRA_MODULES_PATH=/opt/open/opencv_contrib-4.6.0/modules \ #这个需要指定你自己的路径
-D INSTALL_C_EXAMPLES=OFF \
-D INSTALL_PYTHON_EXAMPLES=OFF \
-D OPENCV_ENABLE_NONFREE=OFF \
-D WITH_FFMPEG=ON \ #编译加入ffmpeg
-D CUDA_ARCH_BIN=7.5 \ #算力要根据自己的显卡来匹配
-D WITH_CUDA=ON \ #开启cuda的支持
-D WITH_CUBLAS=ON \
-D CUDA_FAST_MATH=ON \
-D WITH_CUFFT=ON \
-D WITH_NVCUVID=ON \
-D WITH_V4L=OFF \
-D WITH_LIBV4L=OFF \
-D OPENCV_VS_VERSIONINFO_SKIP=ON \
-D WITH_OPENGL=OFF \
-D BUILD_EXAMPLES=OFF \
-D WITH_OPENEXR=OFF \
-D OPENCV_GENERATE_PKGCONFIG=YES \
-D BUILD_opencv_world=OFF \
-D BUILD_opencv_python2=OFF \
-D BUILD_opencv_python3=ON \
-D PYTHON_DEFAULT_EXECUTABLE=/root/anaconda3/envs/pytorch/bin/python3 \ #后面的这些必须指定到你自己的ananconda环境下面
-D PYTHON3_EXECUTABLE=/root/anaconda3/envs/pytorch/bin/python3 \
-D PYTHON3_LIBRARY=/root/anaconda3/envs/pytorch/lib/libpython3.8.so \
-D PYTHON_INCLUDE_DIR=/root/anaconda3/envs/pytorch/include/python3.8 \
-D PYTHON3_NUMPY_INCLUDE_DIRS=/root/anaconda3/envs/pytorch/lib/python3.8/site-packages/numpy/core/include \
-D PYTHON3_PACKAGES_PATH=/root/anaconda3/envs/pytorch/lib/python3.8/site-packages \
..
笔者的python环境是3.8的,因此后面的python直接指定到anaconda路径下面去了的
在其中如果出现了OpenCV 4.x+ requires enabled C++11 support这类的错误,需要添加
-D CMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS} -g -fPIC -O3 -std=c++11 -fopenmp"
-D BUILD_TESTS=OFF
上述的代码已经加入进去了的,如果用到一些其他的opencv功能的话,需要在cmake阶段编译进去。
编译完成之后发现,ffmpeg和cuda已经加入进去了
cmake阶段完成之后在依次输入
make -j8
make install
如果出现error: identifier “nullptr” is undefined的错误,需要在cmake阶段加入
-D CUDA_NVCC_FLAGS="-std=c++11 --expt-relaxed-constexpr" \
编译完成后需要再python的环境下面进行测试,
import cv2
dir(cv2.cuda)
会显示一堆cuda下面的函数,到了这一步即编译成功