Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing sinusoidal noise with Butterworth filter

I'm trying to remove the sinusoidal noise in this image:

enter image description here

Here is its DFT spectrum (after applying log and arbitrary intensity scaling):

enter image description here

I already have a Butterworth filter to apply to this image. It will knock out the mid-frequency peaks. I'm taking care to scale it from [0..255] to [0..1.0] after loading. Here's the filter:

enter image description here

The results aren't great:

enter image description here

My questions:

  • Why is there still a significant amount of noise remaining in the image?
  • Why is the result darker than the original image? The filter clearly does not touch the DC term, so I'd expect the average intensity to be the same.
  • Why is the filter only taking out some of the peaks? It comes from a textbook so I'm inclined to believe that it is correct, but there are other peaks in the spectrum -- are they also part of the noise? I tried removing them using concentric filters, but it didn't do much good and darkened the image beyond recognition.

I've taken the image (cropped) and filter from the book Digital Image Processing by Gonzalez and Woods. In their example, the periodic noise is completely removed by the filtering, and the mean intensity of the image remains the same.

My source code for loading the image and filter, DFT, filtering, IDFT is below:

import cv

def unshift_crop(comp, width, height):
    result = cv.CreateImage((width, height), cv.IPL_DEPTH_8U, 1)
    for x in range(height):
        for y in range(width):
            real, _, _, _ = cv.Get2D(comp, x, y)
            real = int(real) * ((-1)**(x+y))
            cv.Set2D(result, x, y, cv.Scalar(real))
    return result

def load_filter(fname):
    loaded = cv.LoadImage(fname, cv.CV_LOAD_IMAGE_GRAYSCALE)
    flt = cv.CreateImage(cv.GetSize(loaded), cv.IPL_DEPTH_32F, 2)
    width, height = cv.GetSize(loaded)
    for i in range(width*height):
        px, _, _, _ = cv.Get1D(loaded, i)
        #cv.Set1D(flt, i, cv.Scalar(px/255.0, 0))
        cv.Set1D(flt, i, cv.Scalar(px/255.0, px/255.0))
    return flt

if __name__ == '__main__':
    import sys
    fname, filt_name, ofname = sys.argv[1:]
    img = cv.LoadImage(fname, cv.CV_LOAD_IMAGE_GRAYSCALE)
    width, height = cv.GetSize(img)
    src = cv.CreateImage((width*2, height*2), cv.IPL_DEPTH_32F, 2)
    dst = cv.CreateImage((width*2, height*2), cv.IPL_DEPTH_32F, 2)
    cv.SetZero(src)
    for x in range(height):
        for y in range(width):
            px, _, _, _ = cv.Get2D(img, x, y)
            px = float(px) * ((-1) ** (x+y))
            cv.Set2D(src, x, y, cv.Scalar(px, 0))
    cv.DFT(src, dst, cv.CV_DXT_FORWARD)
    flt = load_filter(filt_name)
    cv.Mul(dst, flt, src)
    cv.DFT(src, dst, cv.CV_DXT_INV_SCALE)
    result = unshift_crop(dst, width, height)
    cv.SaveImage(ofname, result)

EDIT

There was a bug in the original source where the filter imaginary components were loaded as zero. This is what caused the result image to appear darker than it really was. I've fixed this and commented the related line.

Using the fixed source and the filter that @0x69 provided (yeah, I know it's not really a Butterworth filter, but at this stage I'm happy to try anything), this is the result:

enter image description here

Better than what I had to start with, but still not as good as I'm hoping for. Can anyone beat this? I suspect putting more notches in to take out the remaining peaks may be of some benefit.

EDIT 2

I've contacted the author. This is their response:

The problem is that the image used in the experiment was floating point, while the one shown in the book (and the original provided in the downloads) are 8 bits. This is required for printing, etc.

In order to duplicate the experiment, you have to start with the noise-free image and then add your own noise to it.

like image 756
mpenkov Avatar asked Mar 02 '11 09:03

mpenkov


People also ask

What filter is used for noise reduction?

The Median filter is the popular known order-statistic filter in digital image processing. Median filter is very popular technique for the removal of impulse noise because of its good de-noising power and mathematical accuracy.

Which filter is used to remove Poisson noise?

Non-local mean filter to remove Poisson noise2 is an extension of normal non-local mean filtering algorithm which was developed for removing additive Gaussian noise. Authors2 considers Poisson distribution along with noisy input image and pre-filtered image to select parameters for the filter.


1 Answers

I've tried to use such modified filter: enter image description here
and what i've got is this ->
enter image description here
I can't fully explain results, but my best guess is that sinusoidal noise by interacting with main image signal somehow generates secondary, third,... harmonic noise waves. Result is also far from ideal, seems still some noise harmonics remains here... BTW, thanks for interesting question.

EDIT:

My second attempt for filter improvement. Filter:
enter image description here Filtered result:
enter image description here
Seems this time no clear sinusoidal noise pattern is visible.

like image 75
Agnius Vasiliauskas Avatar answered Sep 23 '22 02:09

Agnius Vasiliauskas