【问题标题】:Blur a matrix using Fast Fourier Transforms使用快速傅里叶变换模糊矩阵
【发布时间】:2015-08-03 04:30:35
【问题描述】:

我想模糊矩阵中的值,以便在相邻元素中我们不会有尖锐的过渡。

从维基百科页面Gaussian Blur 我找到了一些关于高斯模糊的信息。我用最简单的算法试过了,因此运行时间太长了。坦率地说,我不确定我的实现是否正确,因为在边界图块上仍然存在急剧过渡。

我注意到这种模糊可以通过离散傅里叶变换来完成,速度要快得多,但我想不通。

因此,我们的想法是我们可以使用以下公式获得模糊矩阵:

blurredMatrix = IFFT[FFT[initialMatrix]FFT[weightingFunction]]

其中 FFT/IFFT 是快速傅里叶变换/快速傅里叶逆变换。

目前我正在尝试对 Wolfram Mathematica 进行一些测试,以确保这种傅里叶变换的近似是正确的。

我使用GaussianMatrix 作为 weightingFunction。

我需要二维模糊,所以我创建了如下高斯矩阵:

假设我们的初始矩阵有 nxn 大小,其中 n = 2k+1

G = Chop[GaussianMatrix[k] GaussianMatrix[k], 10^6]

然后,我尝试创建如下 blurredMatrix:

blurredMatrix = Chop[FourierDCT[(FourierDCT[G]) (FourierDCT[initialMatrix]), 3], 10^-6]

但结果我得到了零。

看来我做错了。

另外,我尝试了另一种方法:

f[xi_, yj_] := 1/(2 \[Pi] \[Sigma]^2) Exp[-(((xi^2) + (yj^2) )/(2 \[Sigma]^2))];<br/>
[Sigma] = 3;<br/>
G = Chop[N[Table[f[i, j], {i, 1, 100}, {j, 1, 100}]]]; <br/>
Tavg = Chop[ 1000 InverseFourier[(Fourier[G]) (Fourier[T]) ], 10^-6]; <br/>

使用这种方法,图片看起来很好(图像模糊),但是blurredMatrix和initialMatrix的值之间存在很大差异。

似乎有一些规范化或其他问题。

我需要用 C/C++ 编写代码,C 中有一个库 FFTW 库,它支持离散傅里叶变换。

如果这是一种错误的模糊方式,请告诉我,还有其他可能做我想做的事。

【问题讨论】:

  • 使用 FFT 进行卷积只有在你有非常大的卷积核时才有效。在大多数模糊应用程序中,内核比图像小得多,因此 FFT 会明显变慢。你想要的模糊内核是多大的?
  • @AdiShavit,我使用的是 3x3 内核,但内核的大小由环境变量控制。我在互联网上发现了一些文章可以使高斯模糊更快,但我不确定这是否是正确的方法。另外,我需要对大量矩阵进行模糊处理。
  • 如果您可以使用显卡,则可以使用 CUDA 进行卷积。事实证明,显卡在进行大型矩阵计算时非常有效。
  • 试图编辑以前的,但太慢了。我找到了一个关于这个概念的教程。找到一个关于这个概念的教程:developer.download.nvidia.com/assets/cuda/files/… 就像这些人说的,nVidia 也建议不要对这个内核大小使用 FFT 方法。

标签: c++ wolfram-mathematica gaussian convolution fftw


【解决方案1】:

仅当卷积核非常大时,使用 FFT 进行卷积才有效。在大多数模糊应用程序中,内核比图像小得多,例如3x3,因此 FFT 会明显变慢。

有很多实现小内核卷积的方法。
大多数现代硬件都支持此类内在操作(MMX、SSE、GPU...)。
在您的情况下,FFT 可能不是要走的路。

在 C++ 中,OpenCV 支持跨平台和硬件加速的图像卷积。卷积确实是任何图像和信号处理包中最基本的操作之一(如果不是的话)。

【讨论】:

  • 能否分享一些实现的链接?
  • 我添加了一个指向 OpenCV 的链接,但是在不了解您的平台和环境的情况下,很难给出具体的内容。我确信网络搜索将为大多数平台提供数十种选择。
猜你喜欢
  • 2011-07-12
  • 2017-09-14
  • 2012-12-10
  • 2010-12-13
  • 2013-03-31
  • 2012-05-25
  • 2015-08-19
  • 2020-03-29
  • 1970-01-01
相关资源
最近更新 更多