【OpenCV CUDA】OpenCV和Cuda结合编程
一、利用OpenCV中提供的GPU模块
目前,OpenCV中已提供了许多GPU函数,直接使用OpenCV提供的GPU模块,可以完成大部分图像处理的加速操作。
基本使用方法,请参考:http://www.cnblogs.com/dwdxdy/p/3244508.html
该方法的优点是使用简单,利用GpuMat管理CPU与GPU之间的数据传输,而且不需要关注内核函数调用参数的设置,使用过程中,只需要关注处理的逻辑操作。
缺点是受限于OpenCV库的发展和更新,当需要完成一些自定义的操作时(OpenCV中没有提供相应的库),难以满足应用的需求,需要自己实现自定义操作的并行实现。此外,针对一些特殊需求,OpenCV提供并行处理函数,其性能优化并不是最优的,在具体的应用时,可能需要进一步优化,提高性能。
二、单独使用Cuda API编程
利用Cuda Runtime API、Cuda Driver API实现一些操作的并行加速,使用过程需要管理CPU与GPU之间的数据传输,内核函数调用参数的设置,内核函数的优化等。
优点是处理过程受控于用户,用户可以实现更多的并行加速处理操作。
缺点是使用复杂,代码编写量较多,需要熟悉Cuda相关资料和API接口。下面是简单的示例程序:
__global__ void swap_rb_kernel(const uchar3* src,uchar3* dst,int width,int height) {int x = threadIdx.x + blockIdx.x * blockDim.x;int y = threadIdx.x + blockIdx.y * blockDim.y;if(x < width && y < height){uchar3 v = src[y * width + x];dst[y * width + x].x = v.z;dst[y * width + x].y = v.y;dst[y * width + x].z = v.x;} }void swap_rb_caller(const uchar3* src,uchar3* dst,int width,int height) {dim3 block(32,8);dim3 grid((width + block.x - 1)/block.x,(height + block.y - 1)/block.y);swap_rb_kernel<<<grid,block,0>>>(src,dst,width,height);cudaThreadSynchronize(); }int main() {Mat image = imread("lena.jpg");imshow("src",image);size_t memSize = image.cols*image.rows*sizeof(uchar3);uchar3* d_src = NULL;uchar3* d_dst = NULL;CUDA_SAFE_CALL(cudaMalloc((void**)&d_src,memSize));CUDA_SAFE_CALL(cudaMalloc((void**)&d_dst,memSize));CUDA_SAFE_CALL(cudaMempcy(d_src,image.data,memSize,cudaMemcpyHostToDevice));swap_rb_caller(d_src,d_dst,image.cols,image.rows);CUDA_SAFE_CALL(cudaMempcy(image.data,d_dst,memSize,cudaMemcpyDeviceToHost));imshow("gpu",image);waitKey(0);CUDA_SAFE_CALL(cudaFree(d_src));CUDA_SAFE_CALL(cudaFree(d_dst));return 0; }
上述代码中,使用cudaMalloc,cudaMemcpy,cudaFree管理内存的分配、传输和释放。
注意:若image.data包含字节对齐的空白数据,上述程序无法完成正常的处理操作。
三、利用OpenCV中提供接口,并结合Cuda API编程
利用OpenCV已经提供的部分接口,完成一些Cuda编程的基本处理,简化编程的复杂程度;只是根据自己业务需求,自定义内核函数或扩展OpenCV已提供的内核函数。这样既可以充分利用OpenCV的特性,又可以满足业务的不同需求,使用方便,且易于扩展。下面是简单的示例程序:
//swap_rb.cu #include <opencv2/core/cuda_devptrs.hpp> using namespace cv; using namespace cv::gpu; //自定义内核函数 __global__ void swap_rb_kernel(const PtrStepSz<uchar3> src,PtrStep<uchar3> dst) {int x = threadIdx.x + blockIdx.x * blockDim.x;int y = threadIdx.y + blockIdx.y * blockDim.y;if(x < src.cols && y < src.rows){uchar3 v = src(y,x);dst(y,x) = make_uchar3(v.z,v.y,v.x);} }void swap_rb_caller(const PtrStepSz<uchar3>& src,PtrStep<uchar3> dst,cudaStream_t stream) {dim3 block(32,8);dim3 grid((src.cols + block.x - 1)/block.x,(src.rows + block.y - 1)/block.y);swap_rb_kernel<<<grid,block,0,stream>>>(src,dst);if(stream == 0)cudaDeviceSynchronize(); }
//swap_rb.cpp #include <opencv2/gpu/gpu.hpp> #include <opencv2/gpu/stream_accessor.hpp> using namespace cv; using namespace cv::gpu;void swap_rb_caller(const PtrStepSz<uchar3>& src,PtrStep<uchar3> dst,cudaStream_t stream);void swap_rb(const GpuMat& src,GpuMat& dst,Stream& stream = Stream::Null()) {CV_Assert(src.type() == CV_8UC3);dst.create(src.size(),src.type());cudaStream_t s = StreamAccessor::getStream(stream);swap_rb_caller(src,dst,s); }
//main.cpp #include <iostream> #include <opencv2/opencv.hpp> #include <opencv2/gpu/gpu.hpp> using namespace cv; using namespace cv::gpu; void swap_rb(const GpuMat& src,GpuMat& dst,Stream& stream = Stream::Null()); int main() {Mat image = imread("lena.jpg");imshow("src",image);GpuMat gpuMat,output;gpuMat.upload(image);swap_rb(gpuMat,output);output.download(image);imshow("gpu",image);waitKey(0);return 0; }
swap_rb.cu文件定义了内核函数和内核函数的调用函数,在调用函数中,设置内核函数的调用参数。
swap_rb.cpp文件定义了并行操作的入口函数,即主程序完成并行操作的需要调用的函数,其主要是封装内核函数的调用函数,并添加输入参数的验证、根据输入参数选择不同内核函数等操作。
main.cpp文件主程序,完成数据的输入、业务的处理和数据的输出。
总结
编程简易性和可控性是相对的,编程越方便,就越不容易控制。实际应用过程中,应当寻求编程简易性和可控性的平衡点,应根据应用需求,选取适当的方法,一般建议采用方法三。
【OpenCV CUDA】OpenCV和Cuda结合编程相关推荐
- [CUDA OpenCV]GPU加速的计算机视觉学习资源下载
点击我爱计算机视觉标星,更快获取CVML新技术 今天跟大家介绍一本学习CUDA加速的OpenCV的新书<Hands-On GPU-Accelerated Computer Vision with ...
- opencv、opencv_contrib及cuda联合编译详细教程
opencv.opencv_contrib及cuda联合编译详细教程 最近在使用opencv时需要用cuda加速,网上了很多帖子,踩了很多雷,摸索出来了一点规律,分享给大家,一起探讨(我也是刚刚入手, ...
- opencv进阶-OpenCV4.4 CUDA加速
OpenCV支持传统的图像处理的CUDA加速,从OpenCV4.2开始支持深度神经网络的CUDA加速,因此在OpenCV4.4中,CUDA是既可以加速传统的图像处理,特征与对象检测:又可以支持深度神经 ...
- CUDA 8的混合精度编程
CUDA 8的混合精度编程 Volta和Turing GPU包含 Tensor Cores,可加速某些类型的FP16矩阵数学运算.这样可以在流行的AI框架内更快,更轻松地进行混合精度计算.要使用Ten ...
- 【OpenCV学习】 《OpenCV3编程入门》--毛星云 01 邂逅OpenCV(OpenCV基本概念与基本架构) ROS系统上的运用(python实现)
对 <OpenCV3编程入门>第一章的学习笔记:理解什么是计算机视觉,什么是OpenCV,以及其中的联系等等. PS:此书为2014年出版,opencv的版本和接口也与现在有些不一致了,作 ...
- 一种基于CUDA标准的异构并行编程模型开发简介
一种基于CUDA标准的异构并行编程模型开发简介 目录 一.绪论 1.1研究背景及意义 1.2目标平台体系结构简介 二.HPPA基本组成结构 三.编译工具链开发 3.1 拆分工具HPCufe开发 3.2 ...
- android opencv 书籍,opencv android
本书将分为两个部分.第一部分为基础知识,从OpenCV框架的简单介绍到OpenCV.AndroidSDK.NDK的编程应用,系统全面地介绍OpenCV在移动领域的应用.所涉及的OpenCV中的核心模块 ...
- 一篇文章清晰了解NVIDAI显卡驱动(包括:CUDA、CUDA Driver、CUDA Toolkit、CUDNN、NCVV)
背景 开发过程中需要用到GPU时,通常在安装配置GPU的环境过程中遇到问题:比如:安装TensorFlow2.1过程中,想要使用到电脑的显卡来进行开发,但是发现默认需要CUDATOOLKIT=10.1 ...
- 了解NVIDIA显卡驱动(包括CUDA、CUDA Driver、CUDA Toolkit、CUDNN、NCVV)
背景 开发过程中需要用到GPU时,通常在安装配置GPU的环境过程中遇到问题:CUDA Toolkit和CUDNN版本的对应关系:CUDA和电脑显卡驱动的版本的对应关系:CUDA Toolkit.CUD ...
- 了解NVIDAI显卡驱动(包括:CUDA、CUDA Driver、CUDA Toolkit、CUDNN、NCVV)
转载 一篇 背景 开发过程中需要用到GPU时,通常在安装配置GPU的环境过程中遇到问题:CUDA Toolkit和CUDNN版本的对应关系:CUDA和电脑显卡驱动的版本的对应关系:CUDA Toolk ...
最新文章
- 对于css的简化属性
- 双目图像重叠的视差计算_双目视觉(stereo vision)
- System_Recovery_21.0.3_62137_Multilingual_Product
- 机器学习常用算法(LDA,CNN,LR)原理简述
- Intel DPDK包部署试验
- FileBuffer 与 ImageBuffer 互相转换(滴水PE作业)
- (二)深度学习数据处理-----图片数据处理
- ionic中定义路由的问题
- 洛谷P1364 医院设置
- 【GNN】百度「NLP」面试的一点总结
- wpa_supplicant 中 ISupplicant 服务代理客户端对象获取
- no symbol version section for versioned symbol `memcpy@GLIBC_2.4'
- 文件传输-FTP使用简介
- 计算机故障基本维修方法,11种打印机常见故障维修方法
- RGB888颜色码与十六位(RGB565)颜色码的转换
- Vue 微信扫码支付
- html导出excel加边框,利用js对象Blob导出的excel,有办法把表格的边框给浮现出来...
- 利用Java和photoShop实现照片拼图
- LaTex Verbatim 环境下使用数学符号
- 天龙 - Terrain