Reputation: 73
So currently I'm trying to wrap my head around the fourier transform (in 2D). I wanted to fourier transform an image and return back in only the magnitude spectrum just like this topic on this site:
https://dsp.stackexchange.com/questions/16995/image-reconstructionphase-vs-magnitude
However my image (using spyder ide) comes out like this with some weird artificant in the middle, using the same image from the link above.
original image:
Magnitude spectrum:
The code that I'm using is in python using numpy (np), OpenCV and Matplotlib:
import numpy as np
import cv2
from matplotlib import pyplot as plt
from os import listdir
from os.path import isfile, join
image1 = cv2.imread("Images/test2.png", 0)
fourier = np.fft.fft2(image1)
magnitude = abs(fourier)
inverse = np.fft.ifftshift(np.fft.ifft2(magnitude))
plt.subplot(), plt.imshow(np.uint8(inverse), cmap='gray')
plt.title(''), plt.xticks([]), plt.yticks([])
plt.show()
What am I doing wrong?
Update: added imports
Upvotes: 3
Views: 1518
Reputation: 60514
The weird thing in the middle of your plot is large values being wrapped (conversion to uint8 takes the modulus). When not casting, you see only a white dot in the middle. Typically (for a natural images), the DFT has very high magnitudes at the origin, with magnitudes reducing exponentially for higher frequencies.
The best way to display the DFT is to apply a logarithmic transformation to the magnitude:
inverse = np.fft.ifftshift(np.fft.ifft2(magnitude))
inverse = np.log(np.abs(inverse))
plt.subplot(), plt.imshow(inverse, cmap='gray')
Upvotes: 3
Reputation: 8059
You can try changing the np.uint8
to np.abs
. Since you want clipping above 255 and not modulus you should do something like this:
inverse = np.fft.ifftshift(np.fft.ifft2(magnitude))
inv = np.abs(inverse)
inv[inv > 255] = 255
plt.subplot(), plt.imshow(inv, cmap='gray')
Upvotes: 3