Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python: bandpass filter of an image

I have a data image with an imaging artifact that comes out as a sinusoidal background, which I want to remove. Since it is a single frequency sine wave, it seems natural to Fourier transform and either bandpass filter or "notch filter" (where I think I'd use a gaussian filter at +-omega).

My data.  The red spots are what I want, the background sine wave in kx+ky is unwanted.

In trying to do this, I notice two things:

1) simply by performing the fft and back, I have reduced the sine wave component, shown below. There seems to be some high-pass filtering of the data just by going there and back?

import numpy as np

f = np.fft.fft2(img)                  #do the fourier transform
fshift1 = np.fft.fftshift(f)          #shift the zero to the center
f_ishift = np.fft.ifftshift(fshift1)  #inverse shift
img_back = np.fft.ifft2(f_ishift)     #inverse fourier transform
img_back = np.abs(img_back)

This is an image of img_back:

The inverse fourier transform, no filter applied.

Maybe the filtering here is good enough for me, but I'm not that confident in it since I don't have a good understanding of the background suppression.

2) To be more sure of the suppression at the unwanted frequencies, I made a boolean 'bandpass' mask and applied it to the data, but the fourier transform ignores the mask.

a = shape(fshift1)[0]
b = shape(fshift1)[1]

ro = 8
ri = 5
y,x = np.ogrid[-a/2:a/2, -b/2:b/2] 
m1 = x*x + y*y >= ro*ro 
m2 = x*x + y*y <= ri*ri
m3=np.dstack((m1,m2))       
maskcomb =[]
for r in m3:
    maskcomb.append([any(c) for c in r])  #probably not pythonic, sorry
newma = np.invert(maskcomb)
filtdat = ma.array(fshift1,mask=newma) 
imshow(abs(filtdat))
f_ishift = np.fft.ifftshift(filtdat) 
img_back2 = np.fft.ifft2(f_ishift) 
img_back2 = np.abs(img_back2)

Here the result is the same as before, because np.fft ignores masks. The fix to that was simple:

filtdat2 = filtdat.filled(filtdat.mean())

Unfortunately, (but upon reflection also unsurprisingly) the result is shown here:

The result of a brickwall bandpass filter.

The left plot is of the amplitude of the FFT, with the bandpass filter applied. It is the dark ring around the central (DC) component. The phase is not shown.

Clearly, the 'brickwall' filter is not the right solution. The phenomenon of making rings from this filter is well explained here: What happens when you apply a brick-wall filter to a 1D dataset.

So now I'm stuck. Perhaps it would be better to use one of the built in scipy methods, but they seem to be for 1d data, as in this implementation of a butterworth filter. Possibly the right thing to do involves using fftconvolve() as is done here to blur an image. My question about fftconvolve is this: Does it require both 'images' (the image and the filter) to be in real space? I think yes, but in the example they use a gaussian, so it's ambiguous (fft(gaussian)=gaussian). If so, then it seems wrong to try to make a real space bandpass filter. Maybe the right strategy uses convolve2d() with the fourier space image and a homemade filter. If so, do you know how to make a good 2d filter?

like image 357
Claire Thomas Avatar asked Aug 11 '15 21:08

Claire Thomas


People also ask

What does a bandpass filter do to an image?

Band-pass filters attenuate signal frequencies outside of a range (band) of interest. In image analysis, they can be used to denoise images while at the same time reducing low-frequency artifacts such a uneven illumination. Band-pass filters can be used to find image features such as blobs and edges.

How do you apply a high pass filter to an image in Python?

Method 1: High Pass Filter(HPF) in Python OpenCV Now that we have an image, using the Python OpenCV module we shall read the image. Given the size of the image, we can also resize the shape this step is completely optional. While resizing the image you can pass an interpolation so that the image maintains its quality.

What are band reject filter in digital image processing?

A band reject filter is useful when the general location of the noise in the frequency domain is known. A band reject filter blocks frequencies within the chosen range and lets frequencies outside of the range pass through.

What is low pass and high pass filter in image processing?

Low pass filter: Low pass filter is the type of frequency domain filter that is used for smoothing the image. It attenuates the high frequency components and preserves the low frequency components. High pass filter: High pass filter is the type of frequency domain filter that is used for sharpening the image.


1 Answers

So, one problem here is that your background sinusoid has a period not terribly different from the signal components you are trying to preserve. i.e., the spacing of the signal peaks is about the same as the period of the background. This is going to make filtering difficult.

My first question is whether this background is truly constant from experiment to experiment, or does it depend on the sample and experimental setup? If it is constant, then background frame subtraction would work better than filtering.

Most of the standard scipy.signal filter functions (bessel, chebychev, etc.) are, as you say, designed for 1-D data. But you can easily extend them to isotropic filtering in 2-D. Each filter in frequency space is a rational function of f. The two representations are [a,b] which are the coefficiets of the numerator and denominator polynomial, or [z,p,k] which is the factored representation of the polynomial i.e.,: H(f) = k(f-z0)*(f-z1)/(f-p0)*(f-p1) You can just take the polynomial from one of the filter design algorithms, evaluate it as a function of sqrt(x^2+y^2) and apply it to your frequency domain data.

Can you post a link to the original image data?

like image 167
Evan Avatar answered Sep 18 '22 06:09

Evan