使用scipy.fftpack进行频域过滤,ifft2无法获得理想的结果

发布于 2021-01-29 16:17:06

我试图使用以下代码在频域的灰度输入lena图像上简单地应用高斯滤波器,这是我得到的错误输出:

在此处输入图片说明

from scipy import signal
from skimage.io import imread
import scipy.fftpack as fp
import matplotlib.pyplot as plt

im = imread('lena.jpg') # read lena gray-scale image
# create a 2D-gaussian kernel with the same size of the image
kernel = np.outer(signal.gaussian(im.shape[0], 5), signal.gaussian(im.shape[1], 5))

freq = fp.fftshift(fp.fft2(im))
freq_kernel = fp.fftshift(fp.fft2(kernel))
convolved = freq*freq_kernel # simply multiply in the frequency domain
im_out = fp.ifft2(fp.ifftshift(convolved)).real # output blurred image

在此处输入图片说明

但是,如果我使用相同的方法,则会signal.fftconvolve得到所需的模糊图像输出,如下所示:

im_out = signal.fftconvolve(im, kernel, mode='same')  # output blurred image

在此处输入图片说明

我的输入图片是220x220,是否存在填充问题?如果是这样,如何解决它并使第一个代码(不带fftconvolve)工作?任何帮助将不胜感激。

关注者
0
被浏览
52
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    首先,不需要在执行IFFT之前就将FFT的结果移回去。这只是大量的转移,对结果没有影响。无论您是否同时移动两个数组,两个数组的乘积都以相同的方式发生。

    您在输出中注意到的问题是四个象限已交换。发生这种情况的原因是因为滤波器的大小偏移了一半,导致输出发生了相同的偏移。

    为什么要转移?好吧,因为FFT将原点放在图像的左上角。这不仅对于FFT的输出如此,对于其输入也是如此。因此,您需要生成一个内核,其起源在左上角。怎么样?只需
    致电 之前 申请ifftshift即可: __fft

    freq = fp.fft2(im)
    freq_kernel = fp.fft2(fp.ifftshift(kernel))
    convolved = freq*freq_kernel
    im_out = fp.ifft2(convolved).real
    

    请注意,ifftshift将原点从中心移到左上角,而fftshift将原点从角移到中心。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看