I am trying to implement the Wiener Filter to perform deconvolution on blurred image. My implementation is like this
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)
This implementation is based on the Wiki Page.
The TIFF image used is from : http://www.ece.rice.edu/~wakin/images/lena512color.tiff
But here is a PNG version:
I have a input image motion blurred by a diagonal kernel and some gaussian additive noise is added to it. The lena picture is 512x512 and the blurring kernel is 11x11.
When I apply my wiener_filter to this image the result is like this. .
I think this deblurred image is not of good quality. So I would like to ask if my implementation is correct.
Update the way I add noise.
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 < 0)] = 0
# Saturate upper bound
dummy[np.where(dummy > 255)] = 255
return np.uint8(dummy)
In the absence of noise, a Wiener filter is equivalent to an ideal inverse filter. Read image into the workspace and display it. I = im2double (imread ( 'cameraman.tif' )); imshow (I); title ( 'Original Image (courtesy of MIT)' ); Simulate a motion blur.
This example shows how to use Wiener deconvolution to deblur images. Wiener deconvolution can be used effectively when the frequency characteristics of the image and additive noise are known, to at least some degree. Read and display a pristine image that does not have blur or noise.
By default, the Wiener restoration filter assumes the NSR is equal to 0. In this case, the Wiener restoration filter is equivalent to an ideal inverse filter, which can be extremely sensitive to noise in the input image. In this example, the noise in this restoration is amplified to such a degree that the image content is lost.
Wiener Filter is used to denoise and deblur noisy images corrupted by Gaussian noise and motion blurring. The implemented filter was tested on the Lena image with the resolutions of 1960x1960 and 512x512 attached in the repo.
Use skimage.restoration.wiener, which is usually used like:
>>> from skimage import color, data, restoration
>>> 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 = restoration.wiener(img, psf, 1100)
I have also used it in: Deblur an image using scikit-image.
For data comparison, you can find a sample implementation of Wiener filtering and unsupervisived Wiener filtering at
http://scikit-image.org/docs/dev/auto_examples/plot_restoration.html
If you give your original image data, we may be able to help further.
EDIT: Original link seems to be down, try this one: http://scikit-image.org/docs/dev/auto_examples/filters/plot_restoration.html
We could try unsupervised weiner too (deconvolution with a Wiener-Hunt approach, where the hyperparameters are automatically estimated, using a stochastic iterative process (Gibbs sampler), as described here):
deconvolved, _ = restoration.unsupervised_wiener(im, psf)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With