In the previous sections, you learned how to use numpy.fft
for a one and multi-dimensional ndarray
, and saw the implementation details underneath the hood. Now it's time for some applications. In this section, we are going to use the Fourier transform to do some image processing. We will analyze the spectrum, and then we will interpolate the image to enlarge it to twice the size. First, let's download the exercise image from the Packt Publishing website blog post:
https://www.packtpub.com/books/content/python-data-scientists. Save the image to your local directory as scientist.png
.
This is a RGB image, which means that, when we convert it to an ndarray
, it will be three-dimensional. To simplify the exercise, we use the image module in matplotlib
to read in the image and convert it to grayscale:
In [52]: from matplotlib import image In [53]: img = image.imread('./scientist.png') In [54]: gray_img = np.dot(img[:,:,:3], [.21, .72, .07]) In [55]: gray_img.shape Out[55]: (317L, 661L) In [56]: plt.imshow(gray_img, cmap = plt.get_cmap('gray')) Out[56]: <matplotlib.image.AxesImage at 0xa6165c0> In [57]: plt.show()
You will get the following image as the result:
The pre-processing part is done. We read the image into a three-dimensional ndarray
(img
) and applied the luminosity formula to convert the RGB image to grayscale using 0.21R + 0.72G + 0.07B. We used the pyplot
module in matplotlib
to show the grayscale image. Here we didn't apply any axis label in the plot, but we can see from the axis scale that ndarray gray_img
represents a 317 x 661 pixel image.
Next, we are going to do the Fourier transform and show the spectrum:
In [58]: fft = np.fft.fft2(gray_img) In [59]: amp_spectrum = np.abs(fft) In [60]: plt.imshow(np.log(amp_spectrum)) Out[60]: <matplotlib.image.AxesImage at 0xcdeff60> In [61]: plt.show()
This code will give the following output:
First, we use a two-dimensional Fourier transform for gray_img
, and plot the amplitude spectrum using a log-scale color map. We can see that the corners are different due to the zero-frequency component. Remember, when we use numpy.fft.fft2()
, the order follows the standard order, and we want to place the zero-frequency component to the center. So let's use the shift routine:
In [62]: fft_shift = np.fft.fftshift(fft) In [63]: plt.imshow(np.log(np.abs(fft_shift))) Out[63]: <matplotlib.image.AxesImage at 0xd201dd8> In [64]: plt.show()
This changes the image to:
We can now see that the zero-frequency component is in the center. Let's go to the last step of this exercise: interpolating the image to enlarge the size. The techniques we are using here are very simple; we interpolate zero-frequency into the fft_shift
array and make it twice the size. Then we inverse fft_shift
to the standard order and do another inverse transform back to the original domain:
In [65]: m, n = fft_shift.shape In [66]: b = np.zeros((int(m / 2), n)) In [67]: c = np.zeros((2 * m - 1, int(n / 2))) In [68]: fft_shift = np.concatenate((b, fft_shift, b), axis = 0) In [69]: fft_shift = np.concatenate((c, fft_shift, c), axis = 1) In [70]: ifft = np.fft.ifft2(np.fft.ifftshift(fft_shift)) In [71]: ifft.shape Out[71]: (633L, 1321L) In [72]: ifft = np.real(ifft) In [73]: plt.imshow(ifft, cmap = plt.get_cmap('gray')) Out[73]: <matplotlib.image.AxesImage at 0xf9a0f98> In [74]: plt.show()
In the previous code block, we first retrieved the shape of our fft_shift
array (the same size as gray_img
). Then we created two zero ndarrays
and padded them to the fft_shift
array in four directions to enlarge it. So when we inverse the modified fft_shift
array back to the standard order, the zero-frequency will be perfectly in the middle. And when we do the inverse transformation, you can see that the shape has been doubled. In order to let the pyplot
module plot the new array, we need to convert the array to real numbers. After plotting the new array, we can see that the axis scales are double the size. And we barely lose any details or get any image blur as a result of it. The image has been interpolated using the Fourier transformation.
3.141.47.25