Removing pattern and noise in an image using FFT in matlab

Luciano Rodriguez picture Luciano Rodriguez · Dec 11, 2013 · Viewed 25.3k times · Source

I am using the clown.jpg image to be able to get rid of the obvious pattern/noise it has.

enter image description here

The first step that I did before taking FFT of the image is to rescale it a square image of powers of two (i.e. 256 x 256). Using FFT and fftshift in matlab gives the fast fourier transform with the intensities centered in the image. The following image is the result of using the previous functions mentioned.

enter image description here

I was successful to remove the pattern/noise by zeroing the "stars" manually on the FFT image as shown below:

enter image description here

Taking the IFFT I get a much better quality of picture (not shown).

The question that I have is if there is an automated way of zeroing the "stars"? I have created an interval of where to zero the images since we don't want to remove the brightest "star", the DC component, nor the low values. Such a threshold is given below:

filter = (fLog > .7*max(fLog(:)) ) | (fLog < .25*max(fLog(:)) )

where fLog is the log(1+abs(Fourier image)) and .7 and .25 are the corresponding
interval percentages.

The output mask (which I will multiply to the Fourier Image) is found below. Black corresponds to the value of 0 and white corresponds to 1. Notice that the filtering of this mask removes some "stars" and keeps some of the DC component. Obviously this method is not the best.

enter image description here

I was reading about doing a high pass filter, but that seems to remove all the outer values in the Fourier image. This is based on my previous testing (I didn't include those images).

Is there something that you recommend to highlight the high intensity values except the DC component. Ideally I would like to get the mask to look like:

enter image description here

source: http://users.accesscomm.ca/bostrum/Imaging/tips/tip1.html

In another site, it was mentioned to use "highpass and level correct the FFT data to retain only the stray dots that represent the raster pattern." I am unclear on how to do that exactly.

source: http://www.robotplanet.dk/graphics/raster_removal/

Your help will be greatly appreciated.

Here is my source code to help:

I = imread('clown.jpg'); % Read Image

% convert to grayscale
I = rgb2gray(I);

% normalize the image and conver to doubleI
I = double(mat2gray(I));

% Resize the image
I = imresize(I, [256 256]);

% get the size of the image
[rows,cols] = size(I);

% apply FFT
f = fftshift(fft2(I));

% used to plot the image
fLog = log(1 + abs(f));

% filter by a range based on fLog

filter = (fLog > .7*max(fLog(:)) ) | (fLog < .25*max(fLog(:)) );

B = abs(ifft2(f.*filter));

colormap(gray)
subplot(2,2,1),imagesc(I); title('Original Image')
subplot(2,2,2),imagesc(fLog); title('Fourier Image')
subplot(2,2,3),imagesc(filter); title('Zeroed Fourier Image')
subplot(2,2,4),imagesc(B); title('Cleaned Image')
annotation('textbox', [0 0.9 1 0.1], ...
    'String', 'Fourier Analysis on Clown Image', ...
    'EdgeColor', 'none', ...
    'HorizontalAlignment', 'center', ...
    'FontSize', 15, ...
    'FontWeight', 'bold')

Answer

lennon310 picture lennon310 · Dec 12, 2013

I tried to detect the local maximum magnitude in the frequency domain, and zero them along with their neighborhoods. It is not exactly clean, but at least realize some automatic-zero to some extent. enter image description here

My code:

I=I-mean(I(:));
f = fftshift(fft2(I));
fabs=abs(f);

roi=3;thresh=400;
local_extr = ordfilt2(fabs, roi^2, ones(roi));  % find local maximum within 3*3 range

result = (fabs == local_extr) & (fabs > thresh);

[r, c] = find(result);
for i=1:length(r)
    if (r(i)-128)^2+(c(i)-128)^2>400   % periodic noise locates in the position outside the 20-pixel-radius circle
        f(r(i)-2:r(i)+2,c(i)-2:c(i)+2)=0;  % zero the frequency components
    end
end

Inew=ifft2(fftshift(f));
imagesc(real(Inew)),colormap(gray),