can scipy.signal.wiener filter reduce noise?

Viewed 368

hi guys greetings

I found a wiener filter function on scipy website, and i want to use it to reduce noises like salt&pepper noise.

the function :

scipy.signal.wiener(im, mysize=None, noise=None)

here is the source on scipy website, where they demonstrate the function by applying it to a random image : [https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.wiener.html][1]

I found other wiener filter functions, but they require me to define/input the blurring kernel, where it will be needed for the process of deconvolution, so why this function that i found on scipy does not require me to define or input the blurring kernel and just ask to input the Im(image) and mysize(the size of the Wiener filter window)

here's an example of a wiener filter function code, where you need to input the blurring kernel:

def wiener_filter(img, kernel, K):
    kernel /= np.sum(kernel)
    dummy = np.copy(img)
    dummy = fft2(dummy)
    kernel = fft2(kernel, s = img.shape)
    kernel = np.conj(kernel) / (np.abs(kernel) ** 2 + K)
    dummy = dummy * kernel
    dummy = np.abs(ifft2(dummy))
    return dummy
1 Answers

You can actually look at the implementation through its source. For closure, it's found below:

def wiener(im, mysize=None, noise=None):
    im = np.asarray(im)
    if mysize is None:
        mysize = [3] * im.ndim
    mysize = np.asarray(mysize)
    if mysize.shape == ():
        mysize = np.repeat(mysize.item(), im.ndim)

    # Estimate the local mean
    lMean = correlate(im, np.ones(mysize), 'same') / np.prod(mysize, axis=0)

    # Estimate the local variance
    lVar = (correlate(im ** 2, np.ones(mysize), 'same') /
            np.prod(mysize, axis=0) - lMean ** 2)

    # Estimate the noise power if needed.
    if noise is None:
        noise = np.mean(np.ravel(lVar), axis=0)

    res = (im - lMean)
    res *= (1 - noise / lVar)
    res += lMean
    out = np.where(lVar < noise, lMean, res)

    return out

So for this source, the reason why you don't need to specify the convolution kernel is that it estimates the noise profile of the image and removes that from the image.

In summary, this is what the source does:

  1. Given a window size defined by mysize, we estimate the local mean within each window of the image.
  2. We also estimate the local variance of each window within the same window size constraints defined by mysize.
  3. Estimate the noise power if needed. If none is provided, the noise profile is estimated as the mean of the output of (2).
  4. Take the input image and remove the mean so that the image is centred at 0.
  5. Scale the output of (4) by (1 - noise) / (output of (2)).
  6. Add the mean back to (5). The scaling ensures the removal of the variation due to the noise.
  7. The final output is such that any values in the variance image (output of (2)) is less than the corresponding noise output, we set that to the local mean, and else we leave it alone.

This is actually a standard implementation of the 2D blind Weiner filter. The implementation of SciPy is based on MATLAB's implementation found here.

Related