【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(,);
dim3 grid((width + block.x - )/block.x,(height + block.y - )/block.y); swap_rb_kernel<<<grid,block,>>>(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(); CUDA_SAFE_CALL(cudaFree(d_src));
CUDA_SAFE_CALL(cudaFree(d_dst));
return ;
}
上述代码中,使用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(,);
dim3 grid((src.cols + block.x - )/block.x,(src.rows + block.y - )/block.y); swap_rb_kernel<<<grid,block,,stream>>>(src,dst);
if(stream == )
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();
return ;
}
swap_rb.cu文件定义了内核函数和内核函数的调用函数,在调用函数中,设置内核函数的调用参数。
swap_rb.cpp文件定义了并行操作的入口函数,即主程序完成并行操作的需要调用的函数,其主要是封装内核函数的调用函数,并添加输入参数的验证、根据输入参数选择不同内核函数等操作。
main.cpp文件主程序,完成数据的输入、业务的处理和数据的输出。
总结
编程简易性和可控性是相对的,编程越方便,就越不容易控制。实际应用过程中,应当寻求编程简易性和可控性的平衡点,应根据应用需求,选取适当的方法,一般建议采用方法三。
【OpenCV & CUDA】OpenCV和Cuda结合编程的更多相关文章
- 《CUDA并行程序设计:GPU编程指南》
<CUDA并行程序设计:GPU编程指南> 基本信息 原书名:CUDA Programming:A Developer’s Guide to Parallel Computing with ...
- CUDA 8的混合精度编程
CUDA 8的混合精度编程 Volta和Turing GPU包含 Tensor Cores,可加速某些类型的FP16矩阵数学运算.这样可以在流行的AI框架内更快,更轻松地进行混合精度计算.要使用Ten ...
- 【OpenCV入门教程之一】 安装OpenCV:OpenCV 3.0 +VS 2013 开发环境配置
图片太多,具体过程参照: [OpenCV入门教程之一] 安装OpenCV:OpenCV 3.0.OpenCV 2.4.8.OpenCV 2.4.9 +VS 开发环境配置 说下我这边的设置: 选择deb ...
- [OpenCV] Install OpenCV 3.3 with DNN
OpenCV 3.3 Aug 3, 2017 OpenCV 3.3 has been released with greatly improved Deep Learning module and l ...
- 【CUDA开发】CUDA面内存拷贝用法总结
[CUDA开发]CUDA面内存拷贝用法总结 标签(空格分隔): [CUDA开发] 主要是在调试CUDA硬解码并用D3D9或者D3D11显示的时候遇到了一些代码,如下所示: CUdeviceptr g_ ...
- 【并行计算-CUDA开发】CUDA软件架构与Nvidia硬件对应关系
前面扯了很多,不过大多都是在讲CUDA 在软体层面的东西:接下来,虽然Heresy 自己也不熟,不过还是来研究一下硬体的部分吧-毕竟要最佳化的时候,好像还是要大概知道一下相关的东西的.这部分主要参考资 ...
- ffmpeg+cuda+opencv
为了让ffmpeg使用gpu进行解码,可以按以下步骤: 1 下载nvidia官网提供的ffmpeg,编译安装 https://developer.nvidia.com/ffmpeg 注意原来的选项上还 ...
- CUDA+OpenCV 绘制朱利亚(Julia)集合图形
Julia集中的元素都是经过简单的迭代计算得到的,很适合用CUDA进行加速.对一个600*600的图像,需要进行360000次迭代计算,所以在CUDA中创建了600*600个线程块(block),每个 ...
- opencv 4.0 + linux + cuda静态编译
#下载最新的opencv git clone "https://github.com/opencv/opencv.git" git clone "https://gith ...
- Pitfalls of using opencv GpuMat data in CUDA kernel code
Please note that cv::cuda::GpuMat and cv::Mat using different memory allocation method. cv::cuda::Gp ...
随机推荐
- 关于cnas培训
关于cnas(2014-12-9----2014-12-12) 目的:完成内审相关知识培训,可以做一个合格的内审人员 过程: 1.为什么会存在实验室 2.iso9000是怎么产生的,以及存在的意义 3 ...
- 使用Javascript来创建一个响应式的超酷360度全景图片查看幻灯效果
360度的全景图片效果常常可以用到给客户做产品展示,今天这里我们推荐一个非常不错的来自Robert Pataki的360全景幻灯实现教程,这里教程中将使用javascript来打造一个超酷的全景幻灯实 ...
- django shell 集合
1.创建project $ django-admin startproject mysite 2.真正执行,修改数据库 $ python manage.py migrate 3.运行服务 $ pyth ...
- 实时流式计算框架Storm 0.9.0发布通知(中文版)
Storm0.9.0发布通知中文翻译版(2013/12/10 by 富士通邵贤军 有错误一定告诉我 shaoxianjun@hotmail.com^_^) 我们很高兴宣布Storm 0.9.0已经成功 ...
- Turtle Online:致力于打造超接地气的PC前端架构,组件+API,快速搭建前端开发
架构创作初衷 每当新开一个项目时,都会绞尽脑汁去考虑采用哪种框架:requirejs/seajs.jquery/zepto.backbone.easeUI/Bootstrap/AngularJS……, ...
- WPF中多个RadioButton绑定到一个属性
如图样: 在View中: <RadioButton IsChecked="{Binding Option, Converter={cvt:EnumToBooleanConverter} ...
- 标志数在wordcount程序中的应用与拓展
wordcount程序要求测出文本中的单词数,字符数和行数. 设计思路: 将文件读入,逐字检测,检测到空格单词数加一,检测到回车行数单词数加一,如果既不是回车也不是空格则说明是字符,字符数加一 编程时 ...
- Web 项目可能会用到的20款优秀的开源工具
开源的应用程序和它们的源代码可以免费获得,因为版权是属于任何进行过修改或者提交代码的人.大多数提供开源软件的公司都可以建立行业标准,因此可以获得有利的竞争优势. 很多的开源应用程序和工具都有很强的替代 ...
- 终极事务处理(XTP,Hekaton)——万能大招?
在SQL Server 2014里,微软引入了终极事务处理(Extreme Transaction Processing),即大家熟知的Hekaton.我在网上围观了一些文档,写这篇文章,希望可以让大 ...
- Google FlatBuffers——开源、跨平台的新一代序列化工具
前段时间刚试用了一个序列化工具cereal,请看cereal:C++实现的开源序列化库,打算再总结下我对google proto buf序列化库的使用呢, 结果还没动手,大Google又出了一个新的. ...