1 整体思路
查阅opencv的官方文档,可看到有个cudacodec扩展,用他可方便的进行编解码。唯一麻烦的是需要自行编译opencv。
同时,为了考虑后续方便,顺手编译了FFMPEG,并将其与OPENCV绑定。
在之前的博文“鲲鹏主机+昇腾Atlas 300I Pro+龙蜥8.6 全国产化主机使用NPU推理YoloV5环境安装全过程”中已经干过一次了,类似的来搞一把。
2 准备环境
2.1 安装CMake
同之前的博文,CMake官网下载后安装
./cmake-3.29.0-rc4-linux-aarch64.sh --skip-license --prefix=/usr
2.2 安装nv-codec-headers(可选)
如果不需要FFMPEG,可以无视这步。
注意他对CUDA版本和驱动版本的依赖。所以需要根据本机版本选择合适的分支。
官网传送门
以笔者本机为例,可见驱动版本为510.39.01,CUDA版本为11.6:
$ nvidia-smi
Mon Apr 15 01:30:12 2024
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 510.39.01 Driver Version: 510.39.01 CUDA Version: 11.6 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|===============================+======================+======================|
| 0 Tesla T4 On | 00000000:01:00.0 Off | 0 |
| N/A 54C P0 28W / 70W | 303MiB / 15360MiB | 0% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| 0 N/A N/A 1492699 C /usr/local/bin/ollama 301MiB |
+-----------------------------------------------------------------------------+
那么选择11.1版本是合适的。同时Video Codec SDK的版本为11.1.5。
安装比较简单,常规的make && make install
即可。
2.3 安装Nvidia Codec SDK
官网传送门在此
注意他对CUDA版本和驱动版本的依赖,以及nv-codec-headers 对他版本的依赖。因此不能无脑下最新的,需要由此寻找合适的历史版本。
下载完的压缩包中的Read_Me.pdf中有详细的版本要求介绍,也可以根据nv-codec-headers里要求的版本型号进行处理。(应当是一致的)
解压后,将Interface
目录下的头文件,拷贝到你的CUDA安装目录即可,默认路径为/usr/local/cuda/include
。千万不要去理那些动态库,那个是配套他的测试DEMO编译用的,可以不用管。
2.4 签出opencv和opencv-contrib
统一使用最近的4.9.0的tag
export GIT_SSL_NO_VERIFY=true
git clone https://github.com/opencv/opencv.git
cd opencv
git checkout 4.9.0
cd ..
git clone https://github.com/opencv/opencv_contrib.git
git checkout 4.9.0
cd ..
3 编译安装
3.1 FFMPEG
可以直接用Video Codec SDK里面配套的FFMPEG 4.4,避免不必要的麻烦
cd Video_Codec_SDK_11.1.5/Samples/External/FFmpeg/src
unzip ffmpeg-4.4.zip
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:${PKG_CONFIG_PATH}
./configure --enable-shared --enable-pic --enable-cuda --enable-cuvid --enable-nvenc --enable-nvdec --enable-nonfree --enable-libnpp --extra-cflags=-I/usr/local/cuda/include/ --extra-ldflags=-L/usr/local/cuda/lib64/
make && make install
测试转码,如果没啥报错且文件可用,就表示OK了。
ffmpeg -c:v h264_cuvid -i old.mp4 -c:v h264_nvenc new.mp4
3.2 编译OPENCV
在编译之前,需要先查阅Nvidia官网获得你的cuda_arch_bin
版本。以笔者本机为例。Tesla T4的数值为7.5
。
文章来源:https://www.toymoban.com/news/detail-858700.html
cd opencv
mkdir build
cd build
cmake -D WITH_FFMPEG=ON \
-D FFMPEG_INCLUDE_DIRS=/usr/local/include \
-D FFMPEG_LIBRARIES="/usr/local/lib/libavcodec.so;/usr/local/lib/libavformat.so;/usr/local/lib/libavutil.so;/usr/local/lib/libswscale.so;/usr/local/lib/libswresample.so" \
-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \
-D WITH_CUDA=ON -D WITH_CUDACODEC=ON \
-D CUDA_ARCH_BIN=7.5 \
-D BUILD_opencv_python3=yes -D BUILD_opencv_python2=no \
-D PYTHON3_EXECUTABLE=/root/miniconda3/bin/python3.11 \
-D PYTHON3_INCLUDE_DIR=/root/miniconda3/include/python3.11/ \
-D PYTHON3_LIBRARY=/root/miniconda3/lib/libpython3.11.so \
-D PYTHON3_NUMPY_INCLUDE_DIRS=/root/miniconda3/lib/python3.11/site-packages/numpy/core/include/ -D PYTHON3_PACKAGES_PATH=/root/miniconda3/lib/python3.11/site-packages \
-D PYTHON3_DEFAULT_EXECUTABLE=/root/miniconda3/bin/python3.11 \
..
make
make install
如果需要图形化交互,还需要准备一些系统库文章来源地址https://www.toymoban.com/news/detail-858700.html
yum install gtk2-devel
4 代码示例
import cv2
if __name__ == '__main__':
rtsp_url = 'rtsp://admin:123456@192.168.1.100/'
decoder = cv2.cudacodec.createVideoReader(rtsp_url)
#不设置的化默认是BGRA,为了方便后续处理,指定为BGR
decoder.set(cv2.cudacodec.COLOR_FORMAT_BGR)
count = 0
while True:
ret,gpu_frame = decoder.nextFrame()
if ret :
frame = gpu_frame.download()
if count == 0 :
cv2.imwrite('test_img.bmp', frame)
frame_queue.append(np.array(frame[:, :, ::-1]))
count += 1
到了这里,关于自编译支持CUDA硬解的OPENCV和FFMPEG的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!