c++ - 使用快速傅里叶变换模糊矩阵

标签 c++ wolfram-mathematica gaussian convolution fftw

我想模糊矩阵中的值,这样在相邻元素中我们就不会出现尖锐的过渡。

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

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

所以,我们可以用下面的公式得到模糊矩阵:

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

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

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

我使用 GaussianMatrix 作为权重函数。

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

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

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

然后,我尝试创建模糊矩阵,如下所示:

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 进行卷积才有效。在大多数模糊应用中,内核比图像小得多,例如3x3,因此 FFT 会明显变慢。

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

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

关于c++ - 使用快速傅里叶变换模糊矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30374868/

相关文章:

wolfram-mathematica - mathematica 未在绘图标签中正确显示 SubsuperscriptBox

python - 在 python sklearn 中对一维数组使用高斯混合

wolfram-mathematica - 在曲线边缘绘制箭头

c - 1 除以非常大的数返回 0, C

c++ - 用 boost::geometry 扩展多边形?

c++ - 错误 : 'A' is an inaccessible base of 'B'

c++ - Runge Kutta 圆周运动法

c++ - 无法将带有俄语字符的 wstring 写入文件

wolfram-mathematica - 如何修复程序