使用快速傅里叶变换模糊矩阵
Blur a matrix using Fast Fourier Transforms
我想模糊矩阵中的值,以便在相邻元素中我们不会有急剧的过渡。
从维基百科页面 Gaussian Blur 我找到了一些关于高斯模糊的信息。我用最简单的算法试过了,因此 运行-time 太长了。坦率地说,我不确定我的实现是否正确,因为在边界瓦片上仍然存在急剧过渡。
我注意到这种模糊可以通过更快的离散傅里叶变换来完成,但我想不出来。
所以,我们可以用下面的公式得到模糊矩阵:
blurredMatrix = IFFT[FFT[initialMatrix]FFT[weightingFunction]]
其中 FFT/IFFT 是快速傅立叶 Transform/Inverse 快速傅立叶变换。
目前我正在尝试对 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 做卷积才有效。在大多数模糊应用中,内核比图像小得多,例如3x3,所以 FFT 会慢很多。
有很多实现小核卷积的方法。
大多数现代硬件都支持此类内部操作(MMX、SSE、GPU...)。
FFT 可能不适合您的情况。
在 C++ 中,OpenCV 支持跨平台和硬件加速图像卷积。卷积确实是(如果不是的话)任何图像和信号处理包中最基本的操作之一。
我想模糊矩阵中的值,以便在相邻元素中我们不会有急剧的过渡。
从维基百科页面 Gaussian Blur 我找到了一些关于高斯模糊的信息。我用最简单的算法试过了,因此 运行-time 太长了。坦率地说,我不确定我的实现是否正确,因为在边界瓦片上仍然存在急剧过渡。
我注意到这种模糊可以通过更快的离散傅里叶变换来完成,但我想不出来。
所以,我们可以用下面的公式得到模糊矩阵:
blurredMatrix = IFFT[FFT[initialMatrix]FFT[weightingFunction]]
其中 FFT/IFFT 是快速傅立叶 Transform/Inverse 快速傅立叶变换。
目前我正在尝试对 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 做卷积才有效。在大多数模糊应用中,内核比图像小得多,例如3x3,所以 FFT 会慢很多。
有很多实现小核卷积的方法。
大多数现代硬件都支持此类内部操作(MMX、SSE、GPU...)。
FFT 可能不适合您的情况。
在 C++ 中,OpenCV 支持跨平台和硬件加速图像卷积。卷积确实是(如果不是的话)任何图像和信号处理包中最基本的操作之一。