Complex output after applying inverse fourier transform

22 views (last 30 days)
Brian Ha
Brian Ha on 30 Mar 2022
Commented: Brian Ha on 31 Mar 2022
I'm working on an image reconstruction project by using the method of Fast Fourier Transform (FFT). The code works well and output real matrix when all the pixels in the image are taken into account. However, after I extract the data by truncating the matrix of "Centered Fast Fourier Transform", the reconstructed image becomes a complex uint8 matrix and the following warning are displayed:
"Warning: Displaying real part of complex input.
> In images.internal.imageDisplayValidateParams>validateCData (line 146)
In images.internal.imageDisplayValidateParams (line 30)
In images.internal.imageDisplayParseInputs (line 79)
In imshow (line 253)
In Task2_Cross (line 38) "
clear all; close all; clc
Original_image = imread('Original Image');
figure(1);imshow(Original_image); title('Original Image');
% Convert the original RGB image to a grayscale image, if needed
Original_image = rgb2gray(Original_image);
figure(2); imshow(Original_image); title('Gray Image');
% Get the 2D Fast Fourier Transform (FFT) of an image
Fast_Fourier_Transform = fft2(Original_image);
% Fourier transform of an image
% Convert from complex double to double
Absolute = abs(Fast_Fourier_Transform);
figure(3);imshow(Absolute,[]);title('Fourier transform of an image');
% Get the centered spectrum
Centered_Fast_Fourier_Transform = fftshift(Fast_Fourier_Transform);
figure(4);imshow(abs(Centered_Fast_Fourier_Transform),[]);title('Centered fourier transform of Image')
% Apply log transform
Log_Transform = log(1+abs(Centered_Fast_Fourier_Transform));
figure(5);imshow(Log_Transform,[]);title('log transformed Image')
% Reconstruct the Image
% Uncomment the following lines for data extraction
Centered_Fast_Fourier_Transform = Centered_Fast_Fourier_Transform(6:251,:)
Centered_Fast_Fourier_Transform = Centered_Fast_Fourier_Transform(:,6:251)
Inverse_Centered_Fast_Fourier_Transform = ifftshift(Centered_Fast_Fourier_Transform);
Recontructed_image = ifft2(Inverse_Centered_Fast_Fourier_Transform);
% Convert to unit8
Recontructed_image = uint8(Recontructed_image)
figure(6);imshow(Recontructed_image,[]),title('reconstructed Image (FFT)')
As I know, when I apply FFT on real image A, I will get a complex matrix B. If I apply the inverse Fast Fourier Transform on this complex matrix, I should get a real reconstructed image C. May I know why the code doesn't work after I truncate the matrix? And how to fix it? Thank you.

Accepted Answer

David Goodmanson
David Goodmanson on 30 Mar 2022
Hi Brian,
I beleive the result is due to asymmetric truncation of the image in the frequency domain. I am inferring that your signal has length 256 and you are chopping 5 points off each end of the transform. Consider a 1d case with an even number of points, say 10. Given a real signal y, then if
z = fftshift(fft(y))
and assuming integer frequencies for simplicity, the frequency array corresponding to the transform is
ny -4 -3 -2 -1 0 1 2 3 4
where ny is the nyquist frequency, which you could say is 5 or -5. At the nyquist frequency, the value of z is real.
If you delete a frequency, then to keep the ifft result real (going back into the spacial domain), you have to also delete the matching negative frequency. If you delete, say, two points off each end similar to what you are doing, you end up with
-3 -2 -1 0 1 2
which is not going to work in general because of the unmatched -3 contribution. However, the following woud work:
ny -2 -1 0 1 2
If the nyquist contribution is kept, the result of the ifft will still be real. But since you are lopping off the largest frequencies, to stay in the spirit of this approach it would probably make sense to keep the new nyquist frequency but set its z value to 0.
The following code does this:
y = rand(24,20)
z = fftshift(fft(y))
mrow = 3; % number of rows to lop off each end
mcol = 4; % same for columns
[nrow ncol] = size(z);
ind = [2:mrow+1 nrow-mrow+1:nrow]
z(ind,:) = [];
ind = [2:mcol+1 ncol-mcol+1:ncol]
z(:,ind) = [];
z(1,:) = 0; % set new nyquist contribution to 0 (optional)
z(:,1) = 0; % same
yy = ifft(ifftshift(z))
In the spacial domain the resulting yy matrix is real. But with
ind = [1:mrow nrow-mrow+1:nrow]
(as in your code) the result is complex.
If there are an odd number of points the result is simpler since the nyquist frequency is not present in the frequency array. For 11 points,
-5 -4 -3 -2 -1 0 1 2 3 4 5
and now you can lop off points on each end in symmetric fashion. This is done In the code below and again yy is real.
y = rand(25,21)
z = fftshift(fft(y))
mrow = 3;
mcol = 4;
[nrow ncol] = size(z);
ind = [1:mrow nrow-mrow+1:nrow]
z(ind,:) = [];
ind = [1:mcol ncol-mcol+1:ncol]
z(:,ind) = [];
yy = ifft(ifftshift(z))
  1 Comment
Brian Ha
Brian Ha on 31 Mar 2022
Yessss, I have fixed it and the asymmetric truncation is what causes the problem. Thank you so much for your detailed reply!!!!

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!

Translated by