Как упомянуто в комментариях Cris Luengo , есть несколько вещей, которые необходимо исправить:
- Предоставленная эллиптическая форма для фильтра нижних частот имеет смысл вчастотная область, поэтому вам не нужно вычислять ее БПФ.
Величина фильтра 255
масштабирует результаты на ту же величину.Когда вы сохраняете такие большие значения, тип uint8
оборачивается, сохраняя только 8 младших разрядов, в результате чего получается что-то похожее на шум.Это можно исправить, просто изменив значение фильтра:
draw1.ellipse(bbox, fill=1)
После перенастройки масштабирования вычисленное значение filtered
все еще может немного выйти за пределы желаемого диапазона 0-255в некоторых областях изображения.Это создает пятна с наложением (черные области в областях, окруженных белыми пикселями, белые области в областях, окруженных черными пикселями, или даже градиентные полосы, где изображение переходит от белого к черному и белому).Чтобы избежать этого, обычно необходимо обрезать значения в диапазоне 0-255 следующим образом:
ifft2 = np.real(fftpack.ifft2(fftpack.ifftshift(filtered)))
ifft2 = np.maximum(0, np.minimum(ifft2, 255))
После внесения этих исправлений у вас должен быть следующий код:
from scipy import fftpack
import numpy as np
import imageio
from PIL import Image, ImageDraw
image1 = imageio.imread('image.jpg',as_gray=True)
#convert image to numpy array
image1_np=np.array(image1)
#fft of image
fft1 = fftpack.fftshift(fftpack.fft2(image1_np))
#Create a low pass filter image
x,y = image1_np.shape[0],image1_np.shape[1]
#size of circle
e_x,e_y=50,50
#create a box
bbox=((x/2)-(e_x/2),(y/2)-(e_y/2),(x/2)+(e_x/2),(y/2)+(e_y/2))
low_pass=Image.new("L",(image1_np.shape[0],image1_np.shape[1]),color=0)
draw1=ImageDraw.Draw(low_pass)
draw1.ellipse(bbox, fill=1)
low_pass_np=np.array(low_pass)
#multiply both the images
filtered=np.multiply(fft1,low_pass_np)
#inverse fft
ifft2 = np.real(fftpack.ifft2(fftpack.ifftshift(filtered)))
ifft2 = np.maximum(0, np.minimum(ifft2, 255))
#save the image
imageio.imsave('fft-then-ifft.png', ifft2.astype(np .uint8))
и следующее отфильтрованное изображение: