2014-11-04 6 views
2

Я пытаюсь применить БПФ к цветным изображениям. Я извлекаю три компонента: красный, зеленый и синий, затем я применяю fft2 к каждому отдельно, затем я применил фильтр Гаусса в каждой плоскости. Теперь я пытаюсь показать красные, зеленые и синие компоненты после размытия. После этого я применяю ifft2, чтобы получить результат.Низкочастотная фильтрация цветного изображения с использованием FFT и IFFT

Моя проблема: я вижу серое изображение в каждом компоненте. Я пытаюсь показать только цветные плоскости, но мой код не работает. Кроме того, я хочу объединить эти три компонента вместе, чтобы вернуться к полноцветному изображению. Я написал следующий код ниже. Может ли кто-нибудь сказать мне, что я делаю неправильно?

% 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) 

ответ

3

Вы делаете много ненужных вычислений. Как только вы фильтруете самолеты отдельно, вы можете сразу их объединить. Кроме того, ваш красный компонент выполняет преобразование log, в то время как другие цветные каналы этого не выполняют. Кроме того, вам действительно нужно выполнить fftshift после преобразования изображения, чтобы вы могли центрировать спектр. Сначала вы сделали fftshift, что неверно. То же самое нужно применить к определению фильтра. Как только вы фильтруете изображение, вы должны тщательно отменить свои операции. Форвардное преобразование состоит из fft2, а затем fftshift. Для обратных операций требуется ifftshift, затем ifft2 после. Вы идете в обратном направлении своей деятельности.

Одна вещь, которую я должен подчеркнуть, - это то, что вам нужно лить свои плоскости изображения, чтобы удвоить, чтобы сохранить точность вычислений в целости. Вы этого не делаете, поэтому все вычисления сделаны в uint8.

Также хорошо заметить, что после выполнения ifft2 могут быть некоторые остаточные мнимые значения, поэтому лучше всего использовать real для устранения мнимых компонентов. В соответствии с вашими комментариями, я сделал фигуру, которая отображает красные, зеленые и синие компоненты с неповрежденными оттенками, а также окончательное размытое изображение в области 2 x 2.

С этим, вот ваш код, измененный в соответствии с моими комментариями. Вы также не включать изображения с вашего поста, но я использовал версию Лены в Википедии:

Теперь, имейте в виду, что я удалил много кода, чтобы достичь своей цели:

% 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); 

Это цифра, я получаю:

enter image description here

+0

Спасибо за ваш повтор .... на самом деле это требование применять FFT т o гауссовский и 3 изображения отдельно, затем умножайтесь, затем вернитесь к цветам! ... есть ли проблема, если я переключу шаги? – Seereen2004

+0

@ Seereen2004 - Ну, вы можете сначала выполнить «ifftshift», а затем применить «fft» после этого, чтобы передать спектр в верхний левый угол. Я не понимаю, что вы подразумеваете под «переключением шагов». – rayryeng

+0

Когда я пробую ваш код, у меня не получилось правильное изображение! ... ему нужно снова сменить ... и я вижу, что зеленый самый! – Seereen2004

Смежные вопросы