Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Low-pass filtering a color image using the FFT and IFFT

I am trying to apply the FFT on the color images. I extract the three components: red, green and blue then I apply fft2 to each one separately then I applied a Gaussian filter in each plane. Now I am trying to show the red, green and blue components after blurred. After, I apply ifft2 to get the result.

My problem is I see a gray image in each component. I am trying to show just the color planes alone but my code does not work. In addition, I want to combine these three components together to return back to the full color image. I wrote the following code below. Can anyone tell me what I'm doing wrong?

% Calculate FFT for R , G , B images

I = imread ('lena.jpg'); 

% Extract three images 
Red = I (: , : , 1);
Green = I (: , : , 2);
Blue = I(: , : , 3);

f_r = fftshift (Red); 
F_r = fft2 (f_r); 

f_g = fftshift (Green); 
F_g = fft2 (f_g); 

f_b = fftshift (Blue); 
F_b = fft2 (f_b); 

% Calculate the gaussian filter then find its FFT 
h = fspecial( 'gaussian', [512 512] , 3.0 );
h = fftshift (h); 
H = fft2(h);  % Fourier Transform of 2D Gaussian 

FF_R = H .* F_r ; 

FF_G = H .* F_g; 

FF_B = H .* F_b; 

% This is to get red, green and blue images 
b = zeros(512, 512);

% Inverse IFFT _RED 
Ir = ifftshift(FF_R);
Irr= ifft2 (Ir); 
I_R = fftshift (Irr); 
IFF_R = 1 + log (abs(I_R)); 
figure , imshow (IFF_R , [ ]); 

Con1 = im2uint8(IFF_R); 
just_red_2 = cat(3, Con1, b, b);
figure, imshow (just_red_2); 


% Inverse IFFT _Green 
Ig = ifftshift(FF_G);
Igg= ifft2 (Ig); 
I_G = fftshift (Igg); 
figure , imshow (1+ log(abs(I_G)), [ ]); 
just_green_2 = cat(3, b, I_G, b);
%figure, imshow (1 + log(abs(just_green_2)) ); 

% Inverse IFFT Blue 
Ib = ifftshift(FF_B);
Ibb= ifft2 (Ib); 
I_B = fftshift (Ibb); 
figure , imshow (1+ log(abs(I_B)), [ ]); 
just_blue_2 = cat(3, b,b, I_B);
%figure, imshow (1 + log(abs(just_blue_2)) );


%Combine the three component togather 
%full_image2 = cat (3, FF_R , FF_G , FF_B);
full_image2 = cat (3, just_red_2 (:,:,1) , just_green_2(:,:,2) , just_blue_2(:, :, 3)); 
%full_image2 (: , : , 1) = FF_R (: , : , 1);
%full_image2 (: , : , 2) = FF_G (: , : , 2); 
%full_image2 (: , : , 3) = FF_B (: , : , 3); 
Full = ifft2 ( ifftshift(full_image2));
figure, imshow (Full , [ ])

Final = fftshift(Full); 
figure , imshow ( full_image2 ) 
like image 355
seereen Avatar asked Nov 04 '14 20:11

seereen


People also ask

What is FFT filtering?

FFT-Filter. Filtering is a process of selecting frequency components from a signal. Origin offers an FFT Filter, which performs filtering by using Fourier transforms to analyze the frequency components in the input.

What is FFT on images?

The Fast Fourier Transform (FFT) is commonly used to transform an image between the spatial and frequency domain. Unlike other domains such as Hough and Radon, the FFT method preserves all original data. Plus, FFT fully transforms images into the frequency domain, unlike time-frequency or wavelet transforms.

What is ideal low pass filter in image processing?

In the field of Image Processing, Ideal Lowpass Filter (ILPF) is used for image smoothing in the frequency domain. It removes high-frequency noise from a digital image and preserves low-frequency components.

What is filtering in frequency domain?

Frequency Domain Filters are used for smoothing and sharpening of image by removal of high or low frequency components. Sometimes it is possible of removal of very high and very low frequency. Frequency domain filters are different from spatial domain filters as it basically focuses on the frequency of the images.


1 Answers

You're doing a lot of unnecessary computations. Once you filter the planes separately, you can combine them immediately. Also, your red component is performing a log transformation, while the other colour channels don't have this performed. In addition, you actually need to perform the fftshift once you transform the image so that you can centre the spectrum. You did the fftshift first, which is incorrect. The same thing needs to be applied to your filter definition. Once you filter the image, you have to reverse your operations carefully. The forward transformation consists of doing fft2 followed by fftshift. The reverse operations require you to ifftshift, then ifft2 after. You go in the reverse direction of your operations.

One thing I need to stress is that you need to cast your image planes to double to keep the precision of the computation intact. You don't do this, and so all of the computation is done in uint8.

It also is good to note that there may be some residual imaginary values after you perform the ifft2, so it's best to use real to eliminate the imaginary components. As per your comments, I've made a figure that displays the red, green and blue components with their hues intact, as well as the final blurred image in a 2 x 2 pane.

With this, here's your code modified to suit my comments. You also did not include your image with your post, but I used a version of Lena on Wikipedia:

Now, bear in mind that I removed a lot of your code to achieve your objective:

% Calculate FFT for R , G , B images

I = imread ('https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png');

I = double(I); %// Change - cast to double 

% Extract three images 
Red = I (: , : , 1);
Green = I (: , : , 2);
Blue = I(: , : , 3);

% // Change - Transform, then shift
f_r = fft2(Red); 
F_r = fftshift(f_r); 

f_g = fft2(Green); 
F_g = fftshift(f_g);

f_b = fft2(Blue); 
F_b = fftshift(f_b); 

% Calculate the gaussian filter then find its FFT 
h = fspecial( 'gaussian', [512 512] , 3.0 );

%// Change - Filter, then FFT shift
H = fft2(h);  % Fourier Transform of 2D Gaussian 
H = fftshift(H); 

% // Now filter
FF_R = H .* F_r ; 
FF_G = H .* F_g; 
FF_B = H .* F_b; 

%// Change - perform ifftshift, then ifft2, then cast to real
% Inverse IFFT _RED 
Ir = ifftshift(FF_R);
Irr = fftshift(real(ifft2(Ir)));

% Inverse IFFT _Green 
Ig = ifftshift(FF_G);
Igg = fftshift(real(ifft2(Ig)));

% Inverse IFFT _Blue
Ib = ifftshift(FF_B);
Ibb = fftshift(real(ifft2(Ib)));

%// Visualize the red, green and blue components
b = zeros(512, 512, 'uint8');
image_red = cat(3,Irr, b, b);
image_green = cat(3, b, Igg, b);
image_blue = cat(3, b, b, Ibb);

%Combine the three component together
%// Change - Removed fluff
b = uint8(cat(3, Irr, Igg, Ibb));

%// NEW - Display each component as well as the final image in a new figure
figure;
subplot(2,2,1);
imshow(image_red);
subplot(2,2,2);
imshow(image_green);
subplot(2,2,3);
imshow(image_blue);
subplot(2,2,4);
imshow(b);

This is the figure I get:

enter image description here

like image 180
rayryeng Avatar answered Nov 15 '22 07:11

rayryeng