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?