pythonnumpyopencvimage-processingdft

Image phase spectrum has an complex part


I wanted to see the phase of the image in my hand, but while doing this, I realized that the phase of the image was 3-dimensional, so plt.implot does not process. chat gpt said that this was an error because it consists of complex numbers, the size of phase_spectrum is as follows (1640, 1080, 2)

image_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
value_channel_float = np.float32(value_channel)
dft = cv2.dft(np.float32(value_channel_float), flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
magnitude_spectrum = 20*np.log(cv2.magnitude(dft_shift[:,:,0], dft_shift[:,:,1]))
phase_spectrum = np.angle(dft_shift)

Solution

  • The output of cv2.dft is a two-dimensional matrix with two channels: one for real and one for imaginary. However, both channels are floats and not like one real and one imaginary. Hence, better to use this:

    %matplotlib notebook
    import matplotlib.pyplot as plt
    import numpy as np
    from matplotlib.colors import LogNorm
    im = np.zeros((1000, 1000)) # create empty array
    im[200:800, 200:800] = 255 # draw a rectangle
    imFFT = np.fft.fft2(im) # take FFT
    imFFTShifted = np.fft.fftshift(imFFT) # shift to centre
    magSpectrum = np.abs(imFFTShifted) # this is how you calculate the magSpectrum
    phaseSpectrum = np.angle(imFFTShifted) # this is the phaseSpectrum
    fig, ax = plt.subplots(nrows = 1, ncols = 3)
    ax[0].imshow(im)
    ax[1].imshow(magSpectrum, norm = LogNorm())
    ax[2].imshow(phaseSpectrum, norm = LogNorm())
    

    A demonstration of taking this:

    imFFTOpenCV = cv2.dft(im, flags=cv2.DFT_COMPLEX_OUTPUT)
    imFFTNumpy = np.fft.fft2(im) 
    print("Data type of imFFTOpenCV: "+str(imFFTOpenCV.dtype))
    print("Data type of imFFTNumpy: "+str(imFFTNumpy.dtype))
    

    Results:

    Data type of imFFTOpenCV: float64
    Data type of imFFTNumpy: complex128
    

    You would need to adjust the FFT using cv2 before going with the typically FFT calculations. I recommend just using numpy...