积分图实现均值滤波的CUDA代码
没想到我2010年买的笔记本显卡GT330M 竟然还能跑CUDA,果断小试了一把,环境为CUDA6.5+VS2012,写了一个积分图实现均值滤波。类似于OpenCV的blur()函数。
使用lena.jpg做测试,效果如下:

代码在此:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <opencv2\opencv.hpp> using namespace std;
using namespace cv; __global__ void rowAddKernel(float* pIntegImgLena,int* pPtsImg,int imgW,int imgH)
{
const int tidx=blockDim.x*blockIdx.x + threadIdx.x;
if (tidx<imgW)
{
for (int j=; j<imgH; j++)
{
pIntegImgLena[j*imgW+ tidx] +=pIntegImgLena[(j-)*imgW+tidx];
pPtsImg[j*imgW+ tidx] +=pPtsImg[(j-)*imgW+ tidx];
}
}
} __global__ void colAddKernel(float* pIntegImgLena,int* pPtsImg,int imgW,int imgH)
{
const int tidy=blockDim.y*blockIdx.y + threadIdx.y;
if (tidy<imgH)
{
for (int i=; i<imgW; i++)
{
pIntegImgLena[tidy*imgW+ i] +=pIntegImgLena[tidy*imgW+i-];
pPtsImg[tidy*imgW+ i] +=pPtsImg[tidy*imgW+ i-];
}
}
} __global__ void filterKernel(uchar* pImgLena,float* pIntegImgLena,int* pPtsImg,int imgW,int imgH,int win)
{
const int tidx=blockDim.x*blockIdx.x + threadIdx.x;
const int tidy=blockDim.y*blockIdx.y + threadIdx.y;
if (tidx<imgW && tidy<imgH)
{
int left=tidx-win;
int right=tidx+win;
int top=tidy-win;
int bot=tidy+win; left=max(left, );
right=min(right, imgW-);
top=max(top, );
bot=min(bot, imgH-); int id1=top*imgW+left;
int id2=top*imgW+right;
int id3=bot*imgW+left;
int id4=bot*imgW+right;
int cnt=pPtsImg[id4]+pPtsImg[id1]-pPtsImg[id2]-pPtsImg[id3];
float sum=pIntegImgLena[id4]+pIntegImgLena[id1]-pIntegImgLena[id2]-pIntegImgLena[id3]; float value=sum/cnt; pImgLena[tidy*imgW+tidx]=(uchar)value;
}
} void main()
{
//读取原图像
string imgPath="data/lena.jpg";
Mat imgLena=imread(imgPath, );
int imgH=imgLena.rows;
int imgW=imgLena.cols;
namedWindow("lena");
imshow("lena", imgLena);
waitKey();
//滤波后的lena
Mat filterLena=imgLena.clone();
filterLena.setTo();
//积分图以及坐标索引图
Mat integImgLena=Mat::zeros(imgLena.size(), CV_32FC1);
Mat ptsImg=Mat::zeros(imgLena.size(), CV_32SC1);
//积分图初始化
imgLena.convertTo(imgLena, CV_32FC1);
integImgLena=imgLena.clone();
ptsImg.setTo(); //分配内存
uchar* pImgLena=NULL;
float* pIntegImgLena=NULL;
int* pPtsImg=NULL;
cudaMalloc(&pImgLena, imgH*imgW*sizeof(uchar));
cudaMalloc(&pIntegImgLena, imgH*imgW*sizeof(float));
cudaMalloc(&pPtsImg, imgH*imgW*sizeof(int)); //拷贝数据至GPU
cudaMemcpy(pImgLena, imgLena.data,imgH*imgW*sizeof(uchar), cudaMemcpyHostToDevice);
cudaMemcpy(pIntegImgLena, integImgLena.data,imgH*imgW*sizeof(float), cudaMemcpyHostToDevice);
cudaMemcpy(pPtsImg, ptsImg.data,imgH*imgW*sizeof(int), cudaMemcpyHostToDevice); //按行求前缀和
dim3 block(,);
dim3 grid((imgW+block.x-)/block.x,);
rowAddKernel<<<grid, block, >>>(pIntegImgLena, pPtsImg, imgW, imgH);
cudaThreadSynchronize();
//按列求前缀和
block=dim3(,);
grid=dim3(,(imgH+block.y-)/block.y);
colAddKernel<<<grid, block, >>>(pIntegImgLena, pPtsImg, imgW, imgH);
cudaThreadSynchronize();
//滤波
int win=;
block=dim3(,);
grid=dim3((imgW+block.x-)/block.x, (imgH+block.y-)/block.y);
filterKernel<<<grid, block, >>>(pImgLena,pIntegImgLena, pPtsImg, imgW, imgH, win);
cudaThreadSynchronize(); cudaMemcpy(filterLena.data, pImgLena, imgH*imgW*sizeof(uchar), cudaMemcpyDeviceToHost); cudaError err;
err=cudaGetLastError();
if (err!=cudaSuccess)
{
cout<<"err="<<err<<endl;
getchar();
} namedWindow("filterLena");
imshow("filterLena", filterLena);
waitKey(); cudaFree(pImgLena);
cudaFree(pIntegImgLena);
cudaFree(pPtsImg);
}
积分图实现均值滤波的CUDA代码的更多相关文章
- opencv-10-图像滤波-噪声添加与均值滤波-含opencv C++ 代码实现
开始之前 再说上一篇文章中, 我们想按照噪声产生, 然后将降噪的, 但是限于篇幅, 我就放在这一篇里面了, 说起图像的噪声问题就又回到了我们上一章的内容, 把噪声当作信号处理, 实际上数字图像处理实际 ...
- 【AdaBoost算法】积分图代码实现
一.积分图介绍 定义:图像左上方的像素点值的和: 在Adaboost算法中可用于加速计算Haar或MB-LBP特征值,如下图: 二.代码实现 #include <opencv/highgui.h ...
- 学习 opencv---(7) 线性邻域滤波专场:方框滤波,均值滤波,高斯滤波
本篇文章中,我们一起仔细探讨了OpenCV图像处理技术中比较热门的图像滤波操作.图像滤波系列文章浅墨准备花两次更新的时间来讲,此为上篇,为大家剖析了"方框滤波","均值滤 ...
- 滤波器——BoxBlur均值滤波及其快速实现
个人博客地址:滤波器--BoxBlur均值滤波及其快速实现 动机:卷积核.滤波器.卷积.相关 在数字图像处理的语境里,图像一般是二维或三维的矩阵,卷积核(kernel)和滤波器(filter)通常指代 ...
- OpenCV计算机视觉学习(4)——图像平滑处理(均值滤波,高斯滤波,中值滤波,双边滤波)
如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice &q ...
- 基于FPGA的均值滤波算法实现
我们为了实现动态图像的滤波算法,用串口发送图像数据到FPGA开发板,经FPGA进行图像处理算法后,动态显示到VGA显示屏上,前面我们把硬件平台已经搭建完成了,后面我们将利用这个硬件基础平台上来实现基于 ...
- 基础图像处理之混合空间增强——(Java:拉普拉斯锐化、Sobel边缘检测、均值滤波、伽马变换)
相信看过冈萨雷斯第三版数字图像处理的童鞋都知道,里面涉及到了很多的基础图像处理的算法,今天,就专门借用其中一个混合空间增强的案例,来将常见的几种图像处理算法集合起来,看能发生什么样的化学反应 首先,通 ...
- 基于MATLAB的均值滤波算法实现
在图像采集和生成中会不可避免的引入噪声,图像噪声是指存在于图像数据中的不必要的或多余的干扰信息,这对我们对图像信息的提取造成干扰,所以要进行去噪声处理,常见的去除噪声的方法有均值滤波.中值滤波.高斯滤 ...
- 浅析人脸检测之Haar分类器方法:Haar特征、积分图、 AdaBoost 、级联
浅析人脸检测之Haar分类器方法 一.Haar分类器的前世今生 人脸检测属于计算机视觉的范畴,早期人们的主要研究方向是人脸识别,即根据人脸来识别人物的身份,后来在复杂背景下的人脸检测需求越来越大,人脸 ...
随机推荐
- Ascall 码特殊字符——去除从windows上传文件的^M
在windows上编辑过的文件如果传到unix上,在每个文件的末尾都会有一个换行控制符^M,这个字符一般处于隐藏状态,除非cat -A才能看到,如果不去掉这个符号,很多脚本不能正常运行,很多文件不能正 ...
- Fiddler捕获localhost的网站
Fiddler如何捕获localhost的网站?在hosts文件中加入127.0.0.1 localsite这样也可以被捕获到.
- Spring MVC报错:The request sent by the client was syntactically incorrect ()
原因: 1.参数名称不一致 2.参数类型不一致
- Java数组的创建和初始化
我们说到数组,可能有的人就会比较害怕了,其实,数组只是把对象序列(很多个对象)或者基本类型序列(很多个基本类型)放在一起而已.数组是通过方括号下标操作符[]来定义和使用的.如果要定义,创建一个数组,只 ...
- 如何用Fritzing实现元器件自定义接线图
在用Micropython开发板完成小实验时,很多朋友反应对照接线图实际接线有时会有一些困扰.今天给大家介绍一款画图软件Fritzing 看看是怎么自定义制作接线图的. 前提条件 1.准备好元器件 ...
- Hadoop 2.6.0 完全分布式平台搭建
一.准备软件环境: hadoop-2.6.0.tar.gz CentOS release 6.5 jdk-7u67-linux-x64.tar.gz 网络配置: master1 ...
- Python进阶内容(四)--- 迭代器(Iterator)与生成器(Generator)
迭代器 我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是generator,包括生成器和带yield的ge ...
- 【倍增】洛谷P3379 倍增求LCA
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- sprintf的用法
正文:printf 可能是许多程序员在开始学习C 语言时接触到的第二个函数(我猜第一个是main),说起来,自然是老朋友了,可是,你对这个老朋友了解多吗?你对它的那个孪生兄弟sprintf 了解多吗? ...
- Redis in Docker on Linux Container
记录:在Docker中运行一个Redis实例当我们在Windows系统中安装好Docker以后,在Hyper-V中会自动创建一个Linux虚拟机,如果这个虚拟机没有运行,说明当前运行的是Windows ...