新余管道保温施工 详解python中GPU版本的opencv常用方法介绍

123     2026-01-12 15:17:33
铁皮保温

引言

本篇是以python的视角介绍相关的函数还有自我使用中的一些问题,本想在这篇之前总结一下opencv编译的全过程,但遇到了太多坑,暂时不太想回看做过的笔记,所以这里主要总结python下GPU版本的opencv。

主要函数说明

threshold():二值化,但要指定设定阈值 blendLinear():两幅图片的线形混 calcHist() createBoxFilter ():创建一个规范化的2D框过滤器 canny边缘检测 createGaussianFilter():创建一个Gaussian过滤器 createLaplacianFilter():创建一个Laplacian过滤器 createLinearFilter():创建一个线形过滤器 createMorphologyFilter():形态学运算滤波器;腐蚀、开、关等操作 createSolbelFilter():创建一个solbel过滤器 createHougnCirclesDetector():创建一个霍夫原检测器 createMedianFilter():创建一个中值滤波过滤器 createTemplateMatching():模板匹配 cvtColor():颜色空间转换 dft():执行浮点矩阵的正向或逆离散傅里叶变换 drawColorDisp():颜色差异图像 equalizeHist():将灰度图像的直方图均衡化 findMinMax() findMinMaxLoc() flip():翻转二维矩阵 merge():用几个单通道矩阵构成一个多通道矩阵 split():将多通道矩阵分离成多个单通道矩阵 getCudaEnabledDeviceCount():获取可用的gpu数目 getDevice():返回由cuda::setDevice或默认初始化的当前设备索引 printCudaDeviceInfo() resetDevice():显示地销毁和清理与当前进程中当前设备相关的所有资源 setDevice():设置一个device并为当前线程初始化它;如果省略次函数的调用,则在第一次CUDA使用时初始化默认设备 remap():对图像应用一般的几个变换 resize():调整一个图像大小 rotate():在原点(0,0)周围旋转一个图像,然后移动它 sum():返回矩阵元素的和

上述是在cv2.cuda下总结出来的一些可以使用的方法,因为底层是C++,并且python主要调用的是cv2.so文件,如果我们想要看到一个对象到底有什么样的作用还有一系列的使用方式,我们可以利用python的魔法方法__dir__ 与help查看:

我将上述dir显示的所有方法都打印在了上面,可以复制下来对比哪些方法能用,哪些不能。对于进行GPU编译过的opencv来讲,cv2.cuda下的基本都是GPU方法,而cv2里的方法还是CPU的,这也导致了opencv的局限,因为目前所提供的编译版本的cuda方法都是基于图像的变化和算法,对流的部分是一个空缺,所以如果如果要对视频做操作的话,很大概率会导致内存泄漏:

这是我之前的valgrind测试报告,可以很明显的看出在用opencv进行操作的时候有内存泄漏。所以如果只是对图片做某些算法操作,比如DNN、canny等,速度提升是很明显的。但只是resize或者read这样的操作,都无法发挥出GPU本来的优势,运行率反而不如直接CPU快,具体原因可以看我下面的三种写法:

OpenCV Mat与UMat

邮箱:215114768@qq.com

OpenCV3以后引入了一个新的图像容器对象UMat,它的使用与功能基本和Mat类似,但一个代表着将图片存进GPU,一个是CPU,UMat格式需要支持openCL,OpenCL是一个面向异构系统通用的并行编程标准,也是基于此,才能在opencv中实现UMat和Mat的转换:

上面是C++的伪代码,而python的写法和这个类似:

在opencv-python中,目前我已知的4.1.0以上版本是都有同意OpenGL,如果想知道到底支不支持,可以输入如下代码测试:

返回True即为支持openCL,而如果项目中报错"cv::ocl::OpenCLAllocator::upload",这是因为当前版本的openCL与显卡驱动或者说cuda不兼容,所以安全起见,可以设置cv2.ocl.setUseOpenCL(False)。

另外,在GPU enabled OpenCV in Python中,写了一个例子:

这段代码分别计算了GPU和CPU对于图像进行灰度化到边缘检测的时间,设备保温施工然后看起来测试结果是比较让人满意的:

但实际上,我在多进程读取图像做分析的时候发现,如果用UMat的格式,其生产图片的率远远没有我消费速度快,因为我没有做什么算法相关操作,并且在进程数达到一定量,它会出现异常,也就是说,在我的测试中,它并不太适用于多进程或者多线程,虽然这个是简单的方案。

使用GPU下的opencv

使用的步骤与上面方法类似,只是OpenCV中GPU模块,已经封装的内核函数的调用,其使用步骤如下:

1.验证OpenCV是否已启用GPU模块。

2.上传待处理数据到GPU (Mat --> GpuMat)。

3.调用OpenCV支持的GPU的处理函数。

4.下载处理结果到CPU (GpuMat —> Mat)。

其示例程序如下,完成颜色转换,BGR2GRAY。

这个版本的方法就比上面Umat的方式多很多,也是我在开头引用的所有函数以及相关对象方法都是经过GPU编译的opencv,这个版本是一定要经过编译的,编译的坑我会在之后的博文中说明,那么在编译成功后,就可以看到我介绍的函数,以及GitHub中有一个demo可以运行:

关于上述更详细的参数介绍,可以通过opencv官方的C++文档进行比对:

cv::cuda::GpuMat Class Reference

上面的代码如果理解了UMat格式的定义,那么这里的opencv产生的数据结构就是gpu_mat,相对应的get方法换成了download,而图片先要upload进这个gpu_mat容器里,它要比UMat更可靠与完整,在opencv4.1以后已经建立了相关的生态体系,除了解码之外,我看到大多数用opencv的都是在用GPU的dnn算法,从issue的实验结果上看,确实提升是巨大的。

但这里还是有一个问题,如果出现内存泄漏,怎样去规避和降低,这个只能说因代码而异了。。我在kaggle和opencv官网上找到了两种方案来解决这个问题,但对我来说没啥作用,但如果出现了泄漏,这两种可以参考:

使用gc手动回收:

https://www.kaggle.com/c/aptos2019-blindness-detection/discussion/106622

比如:qq号是123456,那么邮箱就是:123456@qq.com

1. **选择U盘**:选择一个容量适中、读写速度稳定的U盘。一般建议至少使用8GB的U盘,以确保有足够的空间存储操作系统的ISO镜像文件。

使用qimage2ndarray库:

https://answers.opencv.org/question/136206/memory-leak-while-using-cv2videocapture/

后,我引用一张opencv使用cuda运行程序的流程图来说明内部过程,取自【OpenCV】OpenCV中GPU模块使用,我觉得是比较生动形象了:

到此这篇关于详解python中GPU版本的opencv常用方法介绍的文章就介绍到这了,更多相关python中GPU版本的opencv内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!