2D-FFT gives nonzero imaginary value at [1,1]

Perhaps this is just my imperfect knowledge of how FFT works, but according to the theory, the Fourier transform at zero frequency of real-valued data is always real, and I thought that this should also happen with FFT. Now, that’s actually what I have always observed in 1D signals, and usually with 2D data (images), but not always. For instance:

julia> using Images, TestImages, FFTW

julia> chelsea = Gray.(testimage("chelsea.png"));

julia> first(fft(channelview(chelsea))) # expected: null imaginary part
63396.11f0 + 0.0f0im

julia> frame = fill(zero(Gray), 520, 530); # variation with a black frame

julia> frame[111:410, 40:490] .= chelsea;

julia> first(fft(channelview(frame))) # small, but nonzero imaginary part
63396.105f0 - 0.0016288757f0im

How is this? Am I ignoring some point of how FFT works, or am I doing something wrong?

eps(63396.105f0) = 0.00390625f0 > 0.0016288757f0

You are worrying about an imaginary component that is smaller than the floating-point resolution of your real component. Your result is in fact real-valued (within the resolution of the number type used).

5 Likes