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

久未见 提交于 2019-12-19 09:07:00

问题


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 ) 

回答1:


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:



来源:https://stackoverflow.com/questions/26744673/low-pass-filtering-a-color-image-using-the-fft-and-ifft

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!