OpenCV使用指南(v2.1)
文档版本 | 作者 | 发布日期 | 说明 |
0.8 | Haiyong | 初始版本 | |
1.0 | Haiyong | 更新opencv-python | |
1.5 | Haiyong | 补充修改 "已知问题” | |
2.1 | ShangJun | 版本更新 |
1. 概述
OpenCV 是一个广泛使用的开源计算机视觉库,提供图像处理、视频分析、特征提取、目标检测等丰富功能,适用于科研、工业和嵌入式开发等多种场景,它同时支持 CUDA 硬件加速,可将部分图像视频编解码,图像处理、滤波、几何变换、特征计算等操作卸载到GPU 上执行。
PPU SDK 可以兼容支持OpenCV的硬件加速能力,目前已支持最新的OpenCV版本为4.13。
带有硬件加速能力的opencv-python库: **opencv_contrib_python **已加入SAIL pip源,最新版本是4.13.0.90, 可直接pip install进行安装:
pip install opencv-contrib-python==4.13.0.90 -i https://art-pub.eng.t-head.cn/artifactory/api/pypi/pypi_index/simple --force-reinstall如下文档介绍如何自行定制编译带硬件加速能力 OpenCV 和 OpenCV-python 包。
在安装或者自行编译安装带硬件加速能力 的OpenCV 和 OpenCV-python 包之前,建议先卸载环境中已经安装的OpenCV和OpenCV-python包。
2. 编译安装opencv
2.1 下载代码
git clone --branch 4.13.0 --depth 1 https://github.com/opencv/opencv.git
git clone --branch 4.13.0 --depth 1 https://github.com/opencv/opencv_contrib.git
git clone --branch 4.13.0 --depth 1 https://github.com/opencv/opencv_extra.git
cd opencv
ln -sf ../opencv_contrib opencv_contrib2.2 准备脚本
编译前请确认已经安装PPU SDK并执行了envsetup.sh,配置好SDK的环境。
编译删除了一些模块,尽可能多的打开了cuda加速模块,用户可以根据自己的实际需要做增删修改:
mkdir build
cd build
cmake_option=""
# 根据需要配置SKIP modules,这里的skip只是示例,用户可以取消
SKIP_LIST=(xfeatures2d matlab xobjdetect xphoto wechat_qrcode)
SKIP_DEFINES=''
for m in ${SKIP_LIST[@]}; do
SKIP_DEFINES+=" -DBUILD_opencv_${m}=OFF"
done
cmake_option+=" ${SKIP_DEFINES}"
# 根据需要增加需要的module,这里打开了尽可能多的cuda加速modules
ENABLE_LIST=(legacy ximgproc cudev cudastereo cudaarithm cudaimgproc cudacodec cudafilters cudawarping cudaoptflow cudabgsegm cudafeatures2d cudaobjdetect cudalegacy)
ENABLE_DEFINES=''
for m in ${ENABLE_LIST[@]}; do
ENABLE_DEFINES+=" -DBUILD_opencv_${m}=ON"
done
cmake_option+=" -DWITH_CUDA=ON -DWITH_CUDNN=ON -DWITH_CUBLAS=ON -DWITH_CUFFT=ON -DOPENCV_DNN_CUDA=ON -DCUDA_ARCH_BIN=80 -DWITH_NVCUVID=ON"
cmake_option+=" -DOPENCV_ENABLE_NONFREE=ON"
cmake_option+=" ${ENABLE_DEFINES}"
# 关掉了一些不是必须的选项,用户可以取消
cmake_option+=" -DWITH_OPENCL=OFF -DOPENCV_DNN_OPENCL=OFF"
cmake_option+=" -DWITH_ANDROID_MEDIANDK=OFF -DWITH_GTK=OFF -DWITH_IPP=OFF -DBUILD_JAVA=OFF"
cmake_option+=" -DWITH_V4L=OFF -DWITH_GSTREAMER=OFF -DWITH_1394=OFF"
# 指定opencv contrib位置,这里放在opencv目录下一级
cmake_option+=" -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules/"
# 这里指定编译安装位置在源码上一级目录;如果不指定,make install会安装到/usr/local目录
cmake_option+="-DOPENCV_GENERATE_PKGCONFIG -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=../"2.3 配置FFmpeg支持
如果系统没有安装FFmpeg,在opencv configure时,仅仅打开-DWITH_FFMPEG=ON,编译是无法找到ffmpeg的,最终编译的libopencv_videoio.so不会包含对ffmpeg的支持。
有关FFmpeg的编译和使用,可以参考另一篇指南文档 “Video FFmpeg使用指南”。
假设你的FFmpeg安装目录是 FFMPEG_PATH,在build_opencv.sh中补充如下脚本:
export PKG_CONFIG_LIBDIR=$FFMPEG_PATH/lib/pkgconfig:$PKG_CONFIG_LIBDIR
cmake_option+=" -DWITH_FFMPEG=ON -DOPENCV_FFMPEG_USE_FIND_PACKAGE=ON -DOPENCV_FFMPEG_SKIP_BUILD_CHECK=ON -DFFMPEG_DIR=./"配置成功,在编译的时候可以看到(Yes后面显示的是本地的FFmpeg版本):
-- Video I/O:
-- FFMPEG: YES (find_package)
-- avcodec: YES (60.31.102)
-- avformat: YES (60.16.100)
-- avutil: YES (58.29.100)
-- swscale: YES (7.5.100)
-- avresample: NO请把ffmpeg目录指向自编译的支持硬件加速的ffmpeg安装目录。
2.4 配置testcase和samples
增加如下option可以编译并安装opencv自带的testcases和testdata,此项不是必须的:
cmake_option+=" -DBUILD_PERF_TESTS=ON -DBUILD_TESTS=ON -DINSTALL_TESTS=ON -DOPENCV_TEST_DATA_PATH=../opencv_extra/testdata"这里opencv_extra是test data所在目录,前面的脚本已经从github下载了。
2.5 编译
cmake $cmake_option ..
make -j && make install2.6 运行示例
进入安装目录下的bin目录:
cd ../bin
export LD_LIBRARY_PATH=$FFMPEG_PATH/lib:../lib:$LD_LIBRARY_PATH # 把ffmpeg和opencv lib目录加入LD_LIBRARY_PATH
export OPENCV_TEST_DATA_PATH=../share/opencv4/testdata # testdata是git clone https://github.com/opencv/opencv_extra.git得到的目录可以执行相关native测试程序。
3. 编译安装opencv-python
3.1 下载代码
git clone --branch 90 --depth 1 https://github.com/opencv/opencv-python.git因为上面我们编译的是opencv 4.13,所以这里需要下载对应的opencv-python版本。
3.2 修改setup.py
我们可以直接使用 #2.1 已经下载好的opencv和opencv_contrib代码,不需要重新下载
cd opencv-python
rm opencv opencv_contrib opencv_extra multibuild -r
# 假设opencv-python, opencv, opencv_contrib都在同一个目录
ln -sf ../opencv opencv
ln -sf ../opencv_contrib opencv_contrib
ln -sf ../opencv_extra opencv_extra
git clone https://github.com/multi-build/multibuild.git修改setup.py,去掉对submodule的git update,更改编译options(修改项跟上面#2.2差不多,可以根据需要自行增删):
diff --git a/setup.py b/setup.py
index e25e51b..cb8da9b 100755
--- a/setup.py
+++ b/setup.py
@@ -187,6 +187,49 @@ def main():
"-DBUILD_DOCS=OFF",
"-DPYTHON3_LIMITED_API=ON",
"-DBUILD_OPENEXR=ON",
+ "-DWITH_OPENCL=OFF",
+ "-DOPENCV_DNN_OPENCL=OFF",
+ "-DWITH_FFMPEG=ON",
+ "-DOPENCV_FFMPEG_USE_FIND_PACKAGE=ON",
+ "-DOPENCV_FFMPEG_SKIP_BUILD_CHECK=ON",
+ "-DWITH_CUDA=ON",
+ "-DWITH_CUDNN=ON",
+ "-DWITH_CUBLAS=ON",
+ "-DWITH_CUFFT=ON",
+ "-DOPENCV_DNN_CUDA=ON",
+ "-DCUDA_ARCH_BIN=80",
+ "-DWITH_NVCUVID=ON",
+ "-DWITH_V4L=OFF",
+ "-DWITH_GSTREAMER=OFF",
+ "-DWITH_1394=OFF",
+ "-DWITH_ANDROID_MEDIANDK=OFF",
+ "-DWITH_GTK=OFF",
+ "-DWITH_IPP=OFF",
+ "-DBUILD_JAVA=OFF",
+ "-DWITH_VTK=OFF",
+ "-DENABLE_FLAKE8=OFF",
+ "-DENABLE_PYLINT=OFF",
+ "-DBUILD_opencv_legacy=ON",
+ "-DOPENCV_ENABLE_NONFREE=ON",
+ "-DBUILD_opencv_xfeatures2d=OFF",
+ "-DBUILD_opencv_matlab=OFF",
+ "-DBUILD_opencv_xobjdetect=OFF",
+ "-DBUILD_opencv_xphoto=OFF",
+ "-DBUILD_opencv_wechat_qrcode=OFF",
+ "-DBUILD_opencv_ximgproc=ON",
+ "-DBUILD_opencv_cudev=ON",
+ "-DBUILD_opencv_cudastereo=ON",
+ "-DBUILD_opencv_legacy=ON",
+ "-DOPENCV_ENABLE_NONFREE=ON",
+ "-DBUILD_opencv_xfeatures2d=OFF",
+ "-DBUILD_opencv_matlab=OFF",
+ "-DBUILD_opencv_xobjdetect=OFF",
+ "-DBUILD_opencv_xphoto=OFF",
+ "-DBUILD_opencv_wechat_qrcode=OFF",
+ "-DBUILD_opencv_ximgproc=ON",
+ "-DBUILD_opencv_cudev=ON",
+ "-DBUILD_opencv_cudastereo=ON",
]
+ (
# CMake flags for windows/arm64 build
3.3 编译
依赖skbuild,可以 pip install scikit-build
export ENABLE_CONTRIB=1
python3 setup.py bdist_wheel3.4 安装
编译生成的opencv_contrib_python-4.13.0.90-cp37-cp37m-linux_x86_64.whl在dist目录下
pip install dist/opencv_contrib_python-4.13.0.90-cp37-cp37m-linux_x86_64.whl此时可以进入python交互页面,输入 import cv2看看能否成功。
4. 已知问题
cuBLAS:
GEMM:cublasCgemm_v2 is not supported.
cuFFT:
Dft/Convolve:cufftPlan2d is not supported.
cudacodec:
不支持MPEG4/MPEG2/VC1/VP8等比较旧的视频格式
cudaoptflow
部分测试项不支持,PPU没有opt flow 硬件
除此之外,还会有少量native测试项在PPU上会失败,经过分析都是可以跳过的,主要包括如下情况:
结果不一致,浮点精度有较小的误差,但在ulp许可范围。这其中有一些测试项在NV A100卡上也一样会Fail。
kernel代码变量没有初始化为0,或者分配的GPU内存没有memset为0导致的结果差异:在NV的环境下,局部变量和分配的设备内存会被默认初始化为0,但PPU不会。
算子或者算法采用不相同导致的结果差异。
5. 使能示例
Ultralytics yolov5使用opencv-python做目标检测模型推理的前处理和后处理的硬件编解码加速
https://github.com/ultralytics/yolov5.git
前处理使能PPU Video解码硬件加速,需要显式使用FFmpeg做VideoCapture,并配置cuvid硬件加速的选项,参考下面的代码段:
+os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = "hwaccel;cuvid|video_codec;h264_cuvid|vsync;0"
- cap = cv2.VideoCapture(path)
+cap = cv2.VideoCapture(path, cv2.CAP_FFMPEG)后处理cv2.VideoWriter默认使用FFmpeg进行视频编码,如果按照该文档配置了硬件加速的FFmpeg
默认会走到硬件编码,无需修改代码:
result = cv2.VideoWriter("object_tracking.mp4",
cv2.VideoWriter_fourcc(*'avc1'),
fps,
(w, h))