我正在编写一个 Python 应用程序,它使用 OpenCV 的 Python 绑定来进行标记检测和其他图像处理。我想使用 OpenCV 的 CUDA 模块来 CUDA 加速我的应用程序的某些部分,并在他们的 .hpp
文件中注意到他们似乎正在使用 Python 和 Java 的 OpenCV 导出宏。但是,我似乎无法访问那些 CUDA 功能,即使我正在构建 OpenCV WITH_CUDA=ON
。
是否需要使用诸如 PyCUDA 之类的包装器才能访问 GPU 功能,例如 cudaarithm 中的阈值?或者,如果我在 Python 代码中调用 cv2.threshold() (而不是常规的基于 CPU 的实现),这些 CUDA 加速函数是否已经在使用?
CV_EXPORTS double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type, Stream& stream = Stream::Null());
我看到的 cv2
的子模块如下:
- 错误
- 阿鲁科
- 细节
- 鱼眼
- 弗兰
- 指令
- 毫升
- ocl
- 奥格
- 视频标签
cv2.cuda
, cv2.gpu
和 cv2.cudaarithm
都返回 AttributeError
我正在运行以构建 OpenCV 的 CMake 指令如下:
cmake -DOPENCV_EXTRA_MODULES_PATH=/usr/local/lib/opencv_contrib/modules/ \
-D WITH_CUDA=ON -D CUDA_FAST_MATH=1 \
-D ENABLE_PRECOMPILED_HEADERS=OFF \
-D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_EXAMPLES=OFF \
-D BUILD_opencv_java=OFF \
-DBUILD_opencv_bgsegm=OFF -DBUILD_opencv_bioinspired=OFF -DBUILD_opencv_ccalib=OFF -DBUILD_opencv_cnn_3dobj=OFF -DBUILD_opencv_contrib_world=OFF -DBUILD_opencv_cvv=OFF -DBUILD_opencv_datasets=OFF -DBUILD_openc
v_dnn=OFF -DBUILD_opencv_dnns_easily_fooled=OFF -DBUILD_opencv_dpm=OFF -DBUILD_opencv_face=OFF -DBUILD_opencv_fuzzy=OFF -DBUILD_opencv_hdf=OFF -DBUILD_opencv_line_descriptor=OFF -DBUILD_opencv_matlab=OFF -DBUILD_o
pencv_optflow=OFF -DBUILD_opencv_plot=OFF -DBUILD_opencv_README.md=OFF -DBUILD_opencv_reg=OFF -DBUILD_opencv_rgbd=OFF -DBUILD_opencv_saliency=OFF -DBUILD_opencv_sfm=OFF -DBUILD_opencv_stereo=OFF -DBUILD_opencv_str
uctured_light=OFF -DBUILD_opencv_surface_matching=OFF -DBUILD_opencv_text=OFF -DBUILD_opencv_tracking=OFF -DBUILD_opencv_viz=OFF -DBUILD_opencv_xfeatures2d=OFF -DBUILD_opencv_ximgproc=OFF -DBUILD_opencv_xobjdetect
=OFF -DBUILD_opencv_xphoto=OFF ..
原文由 ostrumvulpes 发布,翻译遵循 CC BY-SA 4.0 许可协议
因此,正如@NAmorim 的答案和评论线程中所证实的那样, OpenCV 的各种 CUDA 模块没有可访问的 Python 绑定。
通过使用 Cython 访问我需要的 CUDA 函数并实现必要的逻辑来将我的 Python 对象(主要是 NumPy 数组)转换为 OpenCV C/C++ 对象并返回,我能够绕过这个限制。
工作代码
我首先写了一个 Cython 定义文件,
GpuWrapper.pxd
。该文件的目的是引用外部 C/C++ 类和方法,例如我感兴趣的 CUDA 方法。我们还需要将 Python 对象转换为 OpenCV 对象的能力。我从 OpenCV 的
modules/python/src2/cv2.cpp
复制了前几百行。您可以在下面的附录中找到该代码。我们终于可以编写 Cython 包装器方法来调用 OpenCV 的 CUDA 函数了!这是 Cython 实现文件的一部分,
GpuWrapper.pyx
。在运行设置脚本对代码进行 cythonize 和编译后(见附录),我们可以将 GpuWrapper 作为 Python 模块导入并运行
cudaWarpPerspectiveWrapper
。这允许我通过 CUDA 运行代码,只有 0.34722222222222854% 的不匹配——非常令人兴奋!参考文献(最多只能发布 2 个)
附录
pyopencv_converter.cpp
setupGpuWrapper.py