Фильтр низких частот для размытия изображения - PullRequest
0 голосов
/ 12 февраля 2019

Я пытаюсь размыть изображение, используя fft, пропустив созданный мной фильтр нижних частот, но на выходе получается изображение, полное серого шума.Я просто пытаюсь следовать основам здесь, но, похоже, что-то не так с моей реализацией:

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(image)

#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=255)

low_pass_np=np.array(low_pass)
low_pass_fft=fftpack.fftshift(fftpack.fft2(low_pass))

#multiply both the images
filtered=np.multiply(fft1,low_pass_fft)

#inverse fft
ifft2 = abs(fftpack.ifft2(fftpack.ifftshift(filtered)))

#save the image
imageio.imsave('fft-then-ifft.png', ifft2.astype(np .uint8))

Original Image:

Low Pass filter created

Resultant Image

1 Ответ

0 голосов
/ 13 февраля 2019

Как упомянуто в комментариях 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))

и следующее отфильтрованное изображение:

enter image description here

...