CUDA图形处理学习

_梦魇花葬 2014-07-14 03:27:17
加精
最近有点想学习一下CUDA的图形处理,然后发一个帖子,请给位小伙伴来指点一下!
CUDA里的图像拉伸有很多方法,比较常用的方法是将图像放大后,利用卷积对图像进行滤波处理。这种方法时间复杂度高,处理复杂。相对而言,使用纹理内存进行图像拉伸,由于纹理内存本身对传入的图像数组有线性滤波作用,所以使用纹理拾取函数从源图像纹理内存取值,赋值给输出图像,即可完成图像拉伸及图像滤波两种功能。
利用纹理内存的硬件插值功能,直接使用浮点型的坐标读取相应的源图像“像素”值,并赋值给目标图像。这里没有进行对源图像读取的越界检查,这是因为纹理内存硬件插值功能可以处理越界访问的情况,越界访问会按照事先的设置得到一个相对合理的像素颜色值,不会引起错误。使用cuda数组储存图像数据时,滤波效果更好。 但是texture纹理内存做数据寄存器是不可取的,实验证明其存取速度并不高。纹理内存更适于图像放缩及图像旋转处理。
kernel函数:
//宏:DEF_BLOCK_X 和 DEF_BLOCK_Y
// 定义了默认的线程块尺寸。
#define DEF_BLOCK_X 32
#define DEF_BLOCK_Y 8
// Kernel 函数:_stretchImgKer(拉伸图像)
// 根据给定的拉伸倍数 N 和 M,将输入图像拉伸,将其尺寸从 width * height 变成
// (width * N) * (height * N)
// 全局变量:texRef(作为输入图像的纹理内存引用)
// 纹理内存只能用于全局变量,因此将硬件插值的旋转变换的 Kernel 函数的输入图像列
// 于此处。
static texture texRef;
// Kernel 函数:_StretchImgKer(拉伸图像)
static __global__ void _stretchImgKer(
ImageCuda inimg, ImageCuda outimg, int timesWidth, int timesHeight)//拉伸倍数 //timesWidth*timesHeight
{
// 计算当前线程的位置。
int c = blockIdx.x * blockDim.x + threadIdx.x;
int r = blockIdx.y * blockDim.y + threadIdx.y;
// 检查第一个像素点是否越界,如果越界,则不进行处理,一方面节省计算
// 资源,另一方面防止由于段错误导致程序崩溃。
if (r >= outimg.imgMeta.height || c >= outimg.imgMeta.width)
return;
// 计算第一个输出坐标点对应的图像数据数组下标。
int outidx = r * outimg.pitchBytes + c;
// 通过目标坐标点反推回源图像中的坐标点,这一步是关键,图像的旋转处理也可使用
float inc = c/(float)timesWidth;
float inr = r/(float)timesHeight;
// 通过上面的计算,求出了第一个输出坐标对应的源图像坐标。这里利用纹理内存的
// 硬件插值功能,直接使用浮点型的坐标读取相应的源图像“像素”值,并赋值给目
// 标图像。这里没有进行对源图像读取的越界检查,这是因为纹理内存硬件插值功能
// 可以处理越界访问的情况,越界访问会按照事先的设置得到一个相对合理的像素颜
// 色值,不会引起错误。纹理拾取同时也具有平滑滤波作用,输出图像噪声小。
outimg.imgMeta.imgData[outidx] = tex2D(texRef,inc,inr);
}

主函数:
//为CUDA数组分配内存,并将输入图像拷贝到内存
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(sizeof (unsigned char) * 8, 0, 0, 0, cudaChannelFormatKindUnsigned);
//纹理和数组绑定
errcode = cudaBindTexture2D( NULL, &texRef, inimg->imgData, &channelDesc, inimg->width, inimg->height, inimgCud->pitchBytes);
if (errcode != NO_ERROR)
return errcode;
// 计算调用 Kernel 函数的线程块的尺寸和线程块的数量。
dim3 blocksize, gridsize;
blocksize.x = DEF_BLOCK_X;
blocksize.y = DEF_BLOCK_Y;
gridsize.x = (outsubimgCud.imgMeta.width + blocksize.x - 1) / blocksize.x;
gridsize.y = (outsubimgCud.imgMeta.height + blocksize.y - 1) / blocksize.y;
// 调用核函数。
_stretchImgKer<<>>(
insubimgCud, outsubimgCud, timesWidth, timesHeight)
};

实验结果还是可以的,如下图:
...全文
4447 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
Llovejk 2018-06-13
  • 打赏
  • 举报
回复
版主应该是用了Image.h的头文件吧?想问一下版主有这个头文件里成员函数的定义吗?希望提供一下源码,非常感谢
a505204290 2016-06-26
  • 打赏
  • 举报
回复
楼主您好!!!我刚刚开始学习cuda。。。跪求您这套的完整代码!!!拜托!!!caisimin1994@126.com!!!蟹蟹!!!!!!
liangyuweizhuo 2016-01-04
  • 打赏
  • 举报
回复
楼主,您好~刚刚开始做CUDA图像处理相关的东西,可以把你的资料发给我一份吗??谢谢了 hitzhaoliangyu@126.com
ddd497 2015-09-17
  • 打赏
  • 举报
回复
博主你好,我是cuda新手,想请教你怎么用cuda对输入的两幅图的像素点进行并行处理
beautifu-girl 2015-03-31
  • 打赏
  • 举报
回复
楼主你好,我现在在用cuda对图像处理的c代码进行加速,初学阶段,想问楼主从主函数用IplImage 读入图像怎么才能转换成楼主上面的代码中的inimg的形式啊 。。。能不能把你的完整的主函数代码发我一下。。284270335@qq.com
aries刘 2014-11-06
  • 打赏
  • 举报
回复
引用 20 楼 sparrow986831 的回复:
可以提出问题来
问一下。楼主 。cuda是如何读取图像的? 还有就是有没有完整版的代码。可不可以发给我一份 我的qq 747625786。
aries刘 2014-10-29
  • 打赏
  • 举报
回复
问一下。楼主。你有CUDA在图像处理中 图像插值算法的代码吗?我想看一下,可不可以啊
qq_21986083 2014-10-14
  • 打赏
  • 举报
回复
想问下楼主是那个环境下的cuda编程啊 本人刚开始接触cuda 想问下Linux下的cuda编程问题可以么?
_梦魇花葬 2014-07-27
  • 打赏
  • 举报
回复
可以提出问题来
qq_18141077 2014-07-21
  • 打赏
  • 举报
回复
回复看看而已!
_梦魇花葬 2014-07-19
  • 打赏
  • 举报
回复
没考虑哪些!后期再看看吧!
_梦魇花葬 2014-07-19
  • 打赏
  • 举报
回复
还没做好!只是简单测试下CUDA在图像处理方面的应用!
_梦魇花葬 2014-07-19
  • 打赏
  • 举报
回复
没有做呀! 你需要这方面的数据?
zhao3728 2014-07-19
  • 打赏
  • 举报
回复
版主有没有测试一下看看效率提升了多少啊?
qq_16415459 2014-07-17
  • 打赏
  • 举报
回复
okokokokokokok
_梦魇花葬 2014-07-17
  • 打赏
  • 举报
回复
我手上有一些具体的代码,有需要的可以给我发消息!~~
_梦魇花葬 2014-07-17
  • 打赏
  • 举报
回复
根据不同的现实应用,采用不同的CUDA编程,可以有效的利用GPU的资源,从而很好的实现!
_梦魇花葬 2014-07-17
  • 打赏
  • 举报
回复
CUDA在现实生活当中还是有很高的应用的~~~
万物同源 2014-07-17
  • 打赏
  • 举报
回复
_梦魇花葬 2014-07-17
  • 打赏
  • 举报
回复
加油!~~一起学习,一起进步!
加载更多回复(8)

353

社区成员

发帖
与我相关
我的任务
社区描述
CUDA高性能计算讨论
社区管理员
  • CUDA高性能计算讨论社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧