i am trying to plot the figure of FFT magnitude of an image using the following code in the command window:
a= imread('lena','png')
figure,imshow(a)
ffta=fft2(a)
fftshift1=fftshift(ffta)
magnitude=abs(fftshift1)
figure,imshow(magnitude),title('magnitude')
However, the figure with the title magnitude shows nothing, even though MATLAB shows that it has computed abs()
on fftshift
. The figure is still empty, and there is no error. Also, why do we need to compute the phase shift before magnitude?
The reason why this is probably happening is because of the following things:
fft
of your image, it will produce a double valued result, even though your image is mostly unsigned 8-bit integer. MATLAB assumes thatdouble
formatted images have their intensities / colours between[0,1]
. By doingimshow
on just the magnitude itself, you will most likely get an entirely white image because I suspect a good majority of the FFT coefficients are bigger than 1. This is probably the blank figure that you're referring to.[0,1]
, the DC coefficient will be so large that if you try to display the image, you'll only see a white dot in the middle while every other component will be black.As a side note, the reason why you are doing
fftshift
is because by default, MATLAB assumes that the origin of the FFT for 2D is located at the top left corner. Doingfftshift
will allow the origin to be in the middle, which is what we would intuitively expect of the 2D FFT.In order to remedy this situation, I would suggest doing a
log
transformation on the FFT coefficients so you can visually see the results. I would also normalize the coefficients once youlog
transform it so that they go between[0,1]
. Do not actually modify the FFT coefficients as this would be improper. You need to leave them the same way that it is because if you intend to do any processing on the spectrum, you would start by working on the raw image. Doing filter design or anything of that sort will require the raw spectrum, as the final filter will depend on these coefficients untouched. Unless you actually want to do alog
operation as part of your pipeline, then leave these coefficients as is. As such, this can be done through the following MATLAB code:I'm going to show an example, using your code that you have provided but using another image as you haven't provided one here. I'm going to use the
cameraman.tif
image that's part of the MATLAB system path. As such:This is what I get:
As you can see, the magnitude is displayed more nicely. Also, the DC coefficient is in the middle of the spectrum thanks to
fftshift
.If you want to apply this for colour images,
fft2
should still work. It will apply the 2Dfft
to each colour plane by itself. However, if you want this to work, you'll not only need to take thelog
transform, but you'll also need to normalize each plane separately. You have to do this because if we tried doing theimshow
command we did earlier, it would normalize it so that the greatest value in the spectrum of the colour image gets normalized to 1. This will inevitably produce that same small dot effect that we talked about earlier.Let's try a colour image that's built-in to MATLAB:
onion.png
. We will use the same code that you used above, but we need an additional step of normalizing each colour plane by itself. As such:Note that I had to loop through each colour plane and use
mat2gray
to normalize each plane to[0,1
]. Also, I had to create a new variable calledlogMag
because I have to modify each colour plane individually, and you can't do this with a singleimshow
call.With this, these are the results I get:
What's different with this spectrum is that we are applying the FFT to each colour plane separately, and so you'll see a whole bunch of colour spatters because for each location in this image, we are visualizing a linear combination of components from the red, green and blue channels. For each location, we have a value in between
[0,1]
for each colour plane, and the combination of these give you a colour at this location. You could say that darker colours are for locations that have a relatively low magnitude for at least one of the colour channels, while locations that are brighter have a relatively high magnitude for at least one of the colour channels.Hope this helps!
Can't be sure about your version of "lena.png", but if it's a color RGB picture, you need to convert it first to grayscale, or at least select which RGB plane you want to examine.
I.e., the following works for http://optipng.sourceforge.net/pngtech/img/lena.png (color png):