1

最近我学习了用于 TEM 图像处理的 DM_Script,我需要高斯模糊处理,我在http://www.dmscripting.com/recent_updates.html找到了一个名为“Gaussian Blur”的程序

该代码通过将源图像的快速傅里叶变换(FFT)乘以高斯核图像的FFT,最后对其进行傅里叶逆变换来实现高斯模糊算法。

这是代码的一部分,

// Carry out the convolution in Fourier space

compleximage fftkernelimg:=realFFT(kernelimg) (-> FFT of Gaussian-kernel image)
compleximage FFTSource:=realfft(warpimg) (-> FFT of source image)
compleximage FFTProduct:=FFTSource*fftkernelimg.modulus().sqrt()
realimage invFFT:=realIFFT(FFTProduct)

我想问的是这个 compleximage FFTProduct:=FFTSource*fftkernelimg.modulus().sqrt()

为什么高斯核的 FFT 需要 '.modulus().sqrt()' 进行卷积?

这与一个高斯函数的傅里叶变换变成另一个高斯函数有关吗?或者它与离散傅立叶变换的一种限制有关?

请回答我 谢谢

4

1 回答 1

0

这与任何浮点数值计算的一般精度限制有关。(请参阅此处的fe ,或更深入的此处

stand.dev 的旋转(实值)高斯分布。sigma 应转换为 1/sigma 的 100% 实值旋转高斯函数。但是,以数字方式执行此操作会显示偏差:只需尝试以下操作:

number sigma = 30
number A0 = 1
realimage first := RealImage( "First", 8, 256, 256 )
first = A0 * exp( - (iradius**2/(2*sigma*sigma) ))
first.showimage()
complexImage second := FFT(first)
second.Showimage()

image nonZeroImaginaryMask = ( 0 != second.Imaginary() )
nonZeroImaginaryMask.Showimage()
nonZeroImaginaryMask.SetLimits(0,1)

然后,当您将这些复杂图像相乘(在回传之前)时,您将引入更多错误。通过使用模数,可以确保前向变换的内核是纯实数,因此是更好的“阻尼”曲线。

FFT 滤波代码的更好实现实际上将直接使用 1/sigma 的 std.dev 创建 FFT(高斯),因为这是分析上正确的结果。只有在分析上不知道内核(或其 FFT)时,才对内核进行 FFT 才有意义。

一般来说:当在程序代码中实现任何“数学”时,在你脑后考虑数值计算限制可能会付出巨大的代价。尽可能减少实际计算(即分析计算并使用结果而不是依赖于蛮力数值计算)并尽可能尝试“重塑”方程,fe避免对许多小数字进行大和,小心检查精确数值,尽量避免对小数值错误等非常敏感的表达式。

于 2017-03-19T11:07:37.950 回答