How can I correctly use ifft2 on an image that I've used roifilt2 on?

30 ビュー (過去 30 日間)
Molly Watts
Molly Watts 2019 年 8 月 6 日
コメント済み: Molly Watts 2019 年 8 月 9 日
Hello,
I'm new to matlab (and coding) and this is my first question - I hope that I am able to describe this correctly.
I am creating a circular region of interest to apply a gaussian filter. I have an image, which I fourier transform using FFT2, I use log on the FFT2 magnitude (in order to see image better), create a circular mask on this image (much thanks to the past answers and code from Image Analyst on this), and then apply a gaussian filter. When I IFFT2 to go back - I don't get anything close to my original image. It's mostly all a dark gray.
When I've tried this without any region of interest, just the gaussian filter on the total image, it worked if I took the log of the convolution of my filter with image of magnitude. (Its still in my code - %% out)
Because of this - I tried using log on the image resulting from the roifilt2 and I also tried log on my IFFT - but it didn't work.
I'm wondering where I am going wrong.
Many thanks,
Molly
%% Fourier & Gaussian Mask
close all;
extfilt = {'*.jpg;*.png'};
% pick a file
[filename,filepath] = uigetfile(extfilt,'Pick an image file!');
fontsize = 12;
%Original image
subplot (2,3,1);
img = imread([filepath filename]);
img2 = double(mean(img,3));
imagesc(img2); colormap gray;
title('Original image');
axis image;
%fourier transform
F = fft2(img2);
F = fftshift(F);
%magnitude only
subplot (2,3,4);
F_mag = log(1 + abs(F));
imagesc(F_mag);
axis image;
title('fourier transform: magnitude - DRAW HERE', 'FontSize', fontsize);
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0, 0.04, 1, 0.96]);
%create circular region of interest with ability to accept/redraw circle
promptMessage = sprintf('Do you want to Continue with the program,\nor redraw the circle?');
titleBarCaption = 'Continue?';
again = true;
while again
uiwait(helpdlg('Draw a circle'));
circ_reg = drawcircle();
% hROI.Deletable = true;
% waitfor(hROI);
% Get binary image and center coordinates.
mask = circ_reg.createMask();
centroidxy = circ_reg.Position;
% See if user want this one or wants to redraw.
buttonText = questdlg(promptMessage, titleBarCaption, 'Continue', 'Redraw', 'Continue');
if contains(buttonText, 'Continue')
break; % Continue with the rest of the program after the while loop.
else
% Delete the unwanted image.ROI object.
delete(circ_reg);
end
end
subplot(2, 3, 2);
imshow(mask);
title('Binary Image Mask', 'FontSize', fontsize);
%create Gaussian filter
width = .1; % width of gaussian
[x,y] = ndgrid(zscore(1:size(mask,1)),zscore(1:size(mask,2)));
gaus2d = exp(-(x.^2 + y.^2) ./ (2*width^2));
gaus2d = gaus2d/sum(gaus2d(:));
%visualize gaussian
subplot (2,3,5);
imagesc(gaus2d);
axis image; axis off;
title('gaussian filter');
%appling gaussian filter if no BW created
%G = log(1+abs(F_mag.*gaus2d));
%imagesc(G);
%axis image;
subplot(2,3,3);
filt_mask = roifilt2(gaus2d, F_mag, mask);
imagesc(filt_mask);
axis image;
title('gaussian blur');
%phase component - do I need to apply the gaussian filter to the defined masked region??
Fou_Phase = angle(F);
%ifft2
subplot (2,3,6);
combo = filt_mask.*exp(1i*Fou_Phase);
img_combo2 = real(ifft2(fftshift(combo)));
imagesc(img_combo2);
axis image;
title('inverse fourier');

採用された回答

Sourav Bairagya
Sourav Bairagya 2019 年 8 月 9 日
After inspecting your code, it seems that there are two important missing steps.
First, the roifilt2 function is working properly but the issue is in one of its inputs.
You are first computing FFT of the given input image and then scaling the dynamic range of the FFT by logarithmic function and then feeding this transformed “F_mag” to the roifilt2 function for the processing. As dynamic range of “F_mag” is already compressed, hence output of roifilt2 function i.e. filt_mask’s dynamic range will also be compressed. Hence, before feeding this into ifft2 function it is necessary to decompress its dynamic range.
You can do this by this line of code:
filt_mask = roifilt2(gaus2d, F_mag, mask);
imagesc(filt_mask);
axis image;
title('gaussian blur');
filt_mask = exp(filt_mask)-1;
Secondly, when the processed magnitude spectrum (filt_mask) and phase spectrum (Fou_phase) are combined into a single matrix “combo”, result is the shifted version of the processed FFT, as the original FFT has already been shifted at the starting of the code. Hence, here it is needed to unshift this processed FFT to get the output FFT.
You have tried to do this in the code, but you have used the wrong function. Instead of using fftshift again, use ifftshift.
img_combo2 = real(ifft2(ifftshift(combo)));
To know more details about ifftshift function, follow this link:
  1 件のコメント
Molly Watts
Molly Watts 2019 年 8 月 9 日
Brilliant! Thank you Sourav for your help and answer. I realy appreciate it.

サインインしてコメントする。

その他の回答 (0 件)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by