维纳滤波器用于图像去模糊

9

我正在尝试实现维纳滤波器来对模糊图像进行反卷积。我的实现方式如下:

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)

这个实现是基于维纳反卷积的Wiki页面。所用的TIFF图像来自:http://www.ece.rice.edu/~wakin/images/lena512color.tiff,这里有一个PNG版本:

我的输入图像被对角线内核模糊,并添加了一些高斯噪声。Lena图片为512x512,模糊内核为11x11。
当我将维纳滤波器应用于此图像时,结果如下图所示。enter image description here
我认为这张去模糊的图片质量不佳。所以我想问一下我的实现是否正确。
更新:我添加噪声的方式。
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)

仅仅出于兴趣,当你在新的(模糊的)图像上运行“锐化”卷积时会发生什么呢?它能修复吗? - VC.One
我对图像处理是新手。这里您所说的锐化核是否类似于(拉普拉斯矩阵 + 由0中心组成的1矩阵)?谢谢。@VC.One - yc2986
没事,我测试了一下,它只是让(倾斜的)运动模糊更加清晰,但也看起来“肮脏”。 - VC.One
3个回答

3
使用skimage.restoration.wiener来进行图像恢复,通常使用方法如下:
>>> 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)

我还在以下问题中使用了它:使用scikit-image去模糊图像


2

我的输入是一个由此链接提供的丰富多彩的Lena图像: http://www.ece.rice.edu/~wakin/images/lena512color.tiff。我使用PIL图像加载此图像并将其转换为RGB格式。我添加了一个卷积噪声和另一个标准差相对较小的加性高斯噪声。 - yc2986
2
@tfv:你的链接挂了。 - CpCd0y

2
我们也可以尝试无监督维纳滤波(使用维纳-亨特方法进行反卷积,其中超参数会自动估计,使用随机迭代过程(Gibbs采样),如此处所述):
deconvolved, _ = restoration.unsupervised_wiener(im, psf)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接