# Band-pass filter an image

Ok so i have some HR-TEM images. In this technique fringes appear whereever a crystalline structure is present. This fringes are separated by a certain distance depending on the material, this is our wavelength. I would like to enter a wavelength range defined by two values, say .50 to .55 nm or in pixels. The output should be that all but these freqeuncies as defined by the WL should be filtered out of the image, a band-pass.

So here's an example using some commercial software:

I guess the approach is to Fourrier transform, filter out, and fourrier back. My attempt wasn't even close to getting a result...

Thanks!

-
Even if your attempt wasn't even close to what you want. It's nice to show that you have tried. –  Murta Sep 30 '13 at 12:12
Well my approach was basically what is shown below, first manually, then after i discovered it, using the band pass function. But i would like the incredibly clean result i see in the example. –  arnonymous Sep 30 '13 at 12:29
Please include the original file, not the compressed file with annotations on it. There's plenty of noise being introduced that way... –  The Toad Sep 30 '13 at 16:50

How about the built-in BandpassFilter?

img = ImagePartition[
Import["http://i.stack.imgur.com/gi0kV.jpg"],
{Scaled[1/2], Scaled[1]}][[1, 1]]

Manipulate[BandpassFilter[img, {n1, n2}, l],
{n1, 0, 1},
{n2, 0, 1},
{l, 1, 100, 1}, ContinuousAction -> False]


-
Well, this was basically what i tried, it does work. But in the example i gave, the filtering seems to be a lot cleaner, as in almost no noise. I guess it really regenerates the image. –  arnonymous Sep 30 '13 at 12:27
I would guess an ImageAdjust around the BandpassFilter is in order. –  Rahul Sep 30 '13 at 18:00

There are many ways to filter images. Here is a simple setting:

h = {{1, 2, 3, 2, 1}, {1, 2, 3, 2, 1}, {1, 2, 3, 2, 1}, {1, 2, 3, 2, 1}, {1, 2, 3, 2, 1}};
x = RandomReal[{0, 1}, {20, 20}];
{d1h, d2h} = Dimensions[h];
{d1x, d2x} = Dimensions[x];
m = d1h + d1x - 1;
n = d2h + d2x - 1;


where we define a matrix x (this is like the image) and a filtering kernel h (the 2D impulse response of the filter). You can filter in the spatial domain using

yConvPad = ListConvolve[h, xPad, {1, 1}];


or

yCorrPad = ListCorrelate[Reverse[h], xPad, {-1, -1}];


or in the frequency domain

ffth = Fourier[PadRight[h, {m, n}], FourierParameters -> {1, -1}];
fftx =  Fourier[PadRight[x, {m, n}], FourierParameters -> {1, -1}];
yFourier = InverseFourier[ffth fftx, FourierParameters -> {1, -1}] // Chop;


This takes the transform of the kernel, the transform of the image, and then multiplies them point by point. Taking the inverse transform then returns the same answer as the two spatial domain techniques. To do band-pass filtering, you would want a kernel that represented a bandpass filter (rather than the above h) which represents a lowpass type filter. Or, you could specify the transform of the kernel directly (i.e., ffth) and bypass the need to find the bandpass kernel altogether.

But whether you choose to use convolution, correlation, or the Fourier transform, it's all the same but for numerical issues, that is, yFourier = yConvPad = yCorrPad.

-