最近我学习了用于透射电镜图像处理的DM_Script,我需要高斯模糊处理,我在http://www.dmscripting.com/recent_updates.html中找到了一个名字叫‘高斯模糊’的模糊处理程序
该代码通过将源图像的快速傅立叶变换( 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)我想问的是这个复杂的图像FFTProduct:=FFTSource*fftkernelimg.modulus().sqrt()
为什么高斯内核的快速傅立叶变换需要“.modulus().sqrt()”进行卷积?
这与高斯函数的傅里叶变换变成另一个高斯函数有关。还是与离散傅立叶变换的一种局限性有关?
请回答我谢谢
发布于 2017-03-19 19:07:38
这与任何浮点数值计算的一般精度限制有关。(见f.e.here,或更深入的here)
stand.dev的旋转(实数)高斯。西格玛应该转换为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)然后,当你将这些复杂的图像相乘时(在回传之前),你会引入更多的错误。通过使用模数,可以确保正向变换的核是纯实数的,因此可以得到更好的“阻尼”曲线。
更好的快速傅立叶变换滤波代码的实现实际上将直接创建std.dev为1/sigma的快速傅立叶变换(高斯),因为这是分析上正确的结果。只有在分析上不知道内核(或其FFT)的情况下,对内核进行FFT才有意义。
总而言之:当在程序代码中实现任何“数学”时,在你的脑海中通过数值计算的限制来思考它会付出巨大的代价。尽可能减少实际计算(即解析计算并使用结果,而不是依赖于蛮力数值计算),并在可能时尝试“重塑”方程,f.e.避免对许多小数字进行大和,注意检查精确的数值,尽量避免对小数字错误非常敏感的表达式等。
https://stackoverflow.com/questions/42872628
复制相似问题