CUDA 08 | 低通滤波 在生命游戏实例中,我们知道卷积可以使用纹理内存轻松实现。而滤波则是卷积在频率域中的表达,我们尝试使用CUFFT库来实现几种不同的低通滤波。 1. 离散傅里叶变换与低通滤波 傅里叶级数可以表示任意函数,那么求一个函数的傅里叶变换可以理解为求这个函数在傅里叶级数(空间)下的基。从图像的角度上说,就是求图像对二维正余弦信号的“贡献值”。离散傅里叶正变换公式如下:
其中
是一幅M*N的图像,当
时,显然
就是图像像素值的总和,称为基频。u,v相对比较低时称作低频,相对比较高时称作高频。高频往往包含着一些图像细节关键信息,在图像上表现为梯度的剧烈变化。低频往往包含图像的基本亮度信息。低通滤波即只允许低频通过,会舍弃掉高频信息,图像因此而变模糊。 傅里叶反变换如下:
前面乘以
是为了满足能量守恒定律,确保变换前后的一致性。 现在来谈谈低通滤波,低通滤波,高通滤波,带通滤波都是对正变换得到的
进行处理,在这里也就是声明一个滤波器
,与
逐点相乘即可,考虑如下三种滤波器: 理想低通滤波器(ILPF) 设置一个阈值
,当
时,令其通过,即
,否则屏蔽,
M=N=256, d0=20 高斯低通滤波器(GLPF)
M=N=256, d0=20 巴特沃斯低通滤波器(BLPF)
M=N=256, d0=20 2. cufft中的二维离散傅里叶变换 我们使用CUDA的cufft库来实现傅里叶正反变换,然后用我们自己的核函数来实现滤波。cufft中涉及到的函数主要有: 定义一个cufft句柄,然后使用cufftPlan2d初始化,两个N代表分别图像的长宽,使用复数CUFFT_C2C。 cufftComplex为库中定义的复数类型结构体,其中成员x和y分别代表实部和虚部。cufftExecC2C代表执行傅里叶变换,CUFFT_FORWARD和CUFFT_INVERSE分别表示正变换和反变换。 最后回收变量。 其中有几点值得注意:原始的傅里叶变换是非中心化的,也就是说变换后的基频位于(0,0)处,而在低通滤波中,我们希望基频位于中心,也就是(N/2,N/2)处,这样就可以直接用上一节的滤波器逐项相乘进行滤波。利用傅里叶变换的周期性,在傅里叶变换前分别先对输入乘
,即正变换为
,反变换为
cufft的反变换没有除以MN,即
,为了保证变换前后的一致性,我们需要手动让变换结果除以MN在每次执行完cufftExecC2C使用cudaDeviceSynchronize()函数进行同步在编译时需要加上cufft链接库-lcufft,同时我还用了opencv,因此完整的nvcc编译命令为 3. 程序实现 4. 结果展示 这里只做了低通滤波,可以用类似的方式实现高通滤波,斜坡滤波等一系列频域滤波器。下面展示用第1部分图示的三个滤波器滤波后的结果。
原图
理想滤波器
高斯滤波器
巴特沃斯滤波器
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/90926.html