Фильтрация частотной области с помощью scipy.fftpack, ifft2 не дает желаемого результата - PullRequest
0 голосов
/ 06 июля 2018

Я пытаюсь просто применить фильтр Гаусса к полутоновому входному изображению Лены в частотной области со следующим кодом, и вот неправильный вывод, который я получаю:

enter image description here

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

enter image description here

Однако, если я делаю то же самое, но использую signal.fftconvolve, я получаю желаемое размытое изображение, как показано ниже:

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

enter image description here

Мое входное изображение 220x220, есть ли проблема с заполнением? если да, то как ее решить и заставить работать первый код (без fftconvolve)? любая помощь будет высоко оценена.

1 Ответ

0 голосов
/ 06 июля 2018

Прежде всего, нет необходимости сдвигать результат FFT, просто чтобы сдвинуть его обратно перед выполнением IFFT. Это просто означает, что они не влияют на результат. Умножение двух массивов происходит одинаково, независимо от того, сдвигаете ли вы их оба или нет.

Проблема, которую вы заметили в своих выходных данных, заключается в том, что четыре квадранта поменялись местами. Причина этого заключается в том, что фильтр смещен наполовину по своему размеру, вызывая такое же смещение на выходе.

Почему это смещено? Ну, потому что БПФ помещает начало координат в верхний левый угол изображения. Это верно не только для вывода БПФ, но и для его ввода. Таким образом, вам нужно сгенерировать ядро, источник которого находится в верхнем левом углу. Как? Просто примените 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 смещает его от угла к центру.

...