2

I have a simple Python 3 TKinter Image Editor using OpenCV3 and numpy. I wanted to implement a Fourier Transform and used the first example from here with numpy:

f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
magnitude_spectrum = 20*np.log(np.abs(fshift))

I can't just use fshift as result and display it. Unfortunately the line with 20*np.log... isn't explained on the site and reading other explanations for the fourier transform didn't explain it to me either.

Until now i have no parameter for this manipulation, but I tested that the output differs if I change 20 to something else. Should this be user configurable or why does this code example do this?

Cleb
  • 25,102
  • 20
  • 116
  • 151
xuiqzy
  • 179
  • 2
  • 14
  • 1
    `20*log(abs(f))` is typically used to generate a dB magnitude scale, which is not particularly appropriate for images (it's normally used for audio), but it probably gives a reasonable range of values for plotting. It's just arbitrary scaling of a log axis for display purposes though, so I wouldn't worry about it too much. – Paul R Jan 17 '16 at 22:05

2 Answers2

3

As explained in another answer, fshift is complex and cannot be displayed directly. If you want to see the spectrum you need to take the absolute value.

However, there is a reason for taking the logarithm. The values of the spectrum vary over a great range. So, often you only see a single peak (or in 2D a bright spot) at the center. The logarithm compresses the range of values - larger peaks are scaled down more than smaller peaks. This is useful for visualization because it allows you to see details at all amplitudes.

Here is an illustration:

enter image description here

Note that the scaling factor of 20 has a physical meaning for signals:

20 * log(abs(f)) = 10 * log(abs(f)^2)

The factor 10 is arbitrary, but the factor 2 (2*10) is equivalent to squaring the spectrum before taking fhe logarithm. If you only want to visualize the FFT, this factor does not matter - only the logarithm is important.

Community
  • 1
  • 1
MB-F
  • 22,770
  • 4
  • 61
  • 116
  • post title is a little weird and I think this great explanation should be in a post with better title.( it's a little bit hard to find it) – Abolfazl74 Apr 30 '21 at 10:29
  • There is not much I can do because my answer is permanently attached to the question. However, you could edit the title to make it easier to find. Alternatively, you could post a better question and mark it as a duplicate so that it links here. – MB-F May 01 '21 at 12:40
0

You cannot display fshift because it is a complex array. You can only plot real valued arrays.

In [26]: fshift.dtype
Out[26]: dtype('complex128')

np.abs returns the modulus or magnitude of those complex numbers.

You can see the parameters of fft in the numpy documentation. Remark that Scipy also has a fft implementation, a wrapper of fftpack. Last, you may find the scipy tutorial on Fourier Transforms useful.

Ramon Crehuet
  • 3,679
  • 1
  • 22
  • 37