我用Numpy计算逆滤波正确吗?
在一门数字图像处理的课程中,我们被分配了一个任务,就是使用反向滤波来修复图像。我在用numpy这个工具。下面的变量名称尽量和《数字图像处理》这本书中的名称保持一致。
这是原始图像的放大图。

这是和原始图像大小相同的高斯核“zz.tif”。

这是没有添加噪声的高斯平滑图像的放大图。

f = imtools.load_image( sys.argv[1], mode="L", dtype="float" )
zz = imtools.load_image( "zz.tif", mode="L", dtype="float" )
F = np.fft.fft2( f )
F2 = np.fft.fftshift( F )
# normalize to [0,1]
H = zz/255.
# calculate the damaged image
G = H * F2
# Inverse Filter
F_hat = G / H
# cheat? replace division by zero (NaN) with zeroes
a = np.nan_to_num(F_hat)
f_hat = np.fft.ifft2( np.fft.ifftshift(a) )
imtools.save_image( np.abs(f_hat), "out.tif" )
imtools只是我用PIL和numpy封装的一个工具,用来加载和存储图像。(我也可以分享这个源代码。)
这是经过反向滤波处理后的图像的放大图。

我计算反向滤波的方式正确吗?我使用numpy的方式对吗?
最后图像中的波纹是正常现象,还是我做错了什么?
2 个回答
我对Python了解不多,但“振铃”现象在逆滤波中是正常的。这种现象的根源在于吉布斯现象。因为输入信号并不是完全平滑的,它有一些不连续的地方,所以理论上需要无限多个傅里叶成分来完整表示它。实际上,由于显示器的分辨率是有限的,图像是由像素构成的,所以只需要有限数量的成分就足够了。然而,由于在H中乘以零,记录的图像会丢失一些信息,因此恢复后的图像只能近似输入图像,包含的成分带宽有限,低于显示器的带宽,这就导致了吉布斯振荡。
为了减轻这种现象,可以使用适当的正则化方法,比如使用二维维纳滤波器:F_hat=G * H.conjugate()/(abs(H)2+NSR2),其中NSR是噪声与信号比的估计值,比如在最高空间频率下从0线性增加到10。当NSR的估计值足够接近时,恢复后你应该会看到很少的“振铃”现象。
一般来说,按照我所知道的,你的做法是正确的。
这里的“嗡嗡声”是因为你使用的高通滤波器太“尖锐”了,但这正是你所用方法的特点。
不过,你可以考虑用 numpy.fft.rfft2
(也叫“实数快速傅里叶变换”)和 numpy.fft.irfft2
,而不是 numpy.fft.fft2
和 numpy.fft.ifft2
,因为你处理的都是实数值。这样做可能会稍微快一点。