Wiener Filter para imagen deblur

Estoy intentando implementar el filtro Wiener para realizar la deconvolución en una imagen borrosa. Mi implementación es así.

import numpy as np from numpy.fft import fft2, ifft2 def wiener_filter(img, kernel, K = 10): dummy = np.copy(img) kernel = np.pad(kernel, [(0, dummy.shape[0] - kernel.shape[0]), (0, dummy.shape[1] - kernel.shape[1])], 'constant') # Fourier Transform dummy = fft2(dummy) kernel = fft2(kernel) kernel = np.conj(kernel) / (np.abs(kernel) ** 2 + K) dummy = dummy * kernel dummy = np.abs(ifft2(dummy)) return np.uint8(dummy) 

Esta implementación se basa en la página Wiki .

La imagen TIFF utilizada es de: http://www.ece.rice.edu/~wakin/images/lena512color.tiff
Pero aquí hay una versión PNG a continuación:

Tengo un movimiento de imagen de entrada borroso por un núcleo diagonal y se le agrega algo de ruido aditivo gaussiano. La imagen de lena es 512×512 y el núcleo difuminado es 11×11.

Cuando aplico mi wiener_filter a esta imagen, el resultado es así. introduzca la descripción de la imagen aquí .

Creo que esta imagen borrosa no es de buena calidad. Así que me gustaría preguntar si mi implementación es correcta.

¡Muchas gracias!

Actualizar la forma en que agrego ruido.

 from scipy.signal import gaussian, convolve2d def blur(img, mode = 'box', block_size = 3): # mode = 'box' or 'gaussian' or 'motion' dummy = np.copy(img) if mode == 'box': h = np.ones((block_size, block_size)) / block_size ** 2 elif mode == 'gaussian': h = gaussian(block_size, block_size / 3).reshape(block_size, 1) h = np.dot(h, h.transpose()) h /= np.sum(h) elif mode == 'motion': h = np.eye(block_size) / block_size dummy = convolve2d(dummy, h, mode = 'valid') return np.uint8(dummy), h def gaussian_add(img, sigma = 5): dummy = np.copy(img).astype(float) gauss = np.random.normal(0, sigma, np.shape(img)) # Additive Noise dummy = np.round(gauss + dummy) # Saturate lower bound dummy[np.where(dummy  255)] = 255 return np.uint8(dummy) 

Use skimage.restration.wiener , que generalmente se usa como:

 >>> from skimage import color, data, restration >>> img = color.rgb2gray(data.astronaut()) >>> from scipy.signal import convolve2d >>> psf = np.ones((5, 5)) / 25 >>> img = convolve2d(img, psf, 'same') >>> img += 0.1 * img.std() * np.random.standard_normal(img.shape) >>> deconvolved_img = restration.wiener(img, psf, 1100) 

También lo he usado en: Deblur una imagen usando scikit-image .

Para la comparación de datos, puede encontrar una implementación de muestra del filtrado de Wiener y el filtrado de Wiener sin supervisión en

http://scikit-image.org/docs/dev/auto_examples/plot_restration.html

Si proporciona los datos de su imagen original, podremos ayudarlo aún más.

EDIT: el enlace original parece estar caído, intente este: http://scikit-image.org/docs/dev/auto_examples/filters/plot_restration.html

También podríamos probar weiner sin supervisión (desconvolución con un enfoque de Wiener-Hunt, donde los hiperparámetros se estiman automáticamente, usando un proceso iterativo estocástico (muestra de Gibbs), como se describe aquí ):

 deconvolved, _ = restration.unsupervised_wiener(im, psf)