There is nothing preventing us from extending the transforms we discussed before to 2D. One of the most common applications are image processing.
11.1 Fourier
If we apply FFT to a matrix \(X\in\mathrm{R}^{m\times n}\) we can simply apply the 1D version to every row and then to every column of the resulting matrix. The other way round will produce the same final result.
This is shown in the code below but note we should use the more efficient np.fft.fft2.
(b) Image after applying FFT on each individual row
(c) Image after applying FFT on each individual column
(d) Row and column wise FFT (order does not matter)
Figure 11.1: Image of MCI I and the row/column wise FFT.
Of course we can use this to compress the image by removing small values from the transform.
Show the code for the figure
import matplotlib.pyplot as pltimport imageio.v3 as iioimport numpy as np%config InlineBackend.figure_formats = ['svg']im = np.asarray(iio.imread("https://www.mci.edu/en/download/27-logos-bilder?""download=618:mci-eu-web"))def rgb2gray(rgb):return np.dot(rgb[...,:3], [0.2989, 0.5870, 0.1140])def myplot(A): plt.figure() plt.imshow(A, cmap="gray") plt.axis("off") plt.gca().set_aspect(1)A = rgb2gray(im)A_fft = np.fft.fft2(A)A_fft_sort = np.sort(np.abs(A_fft.reshape(-1)))myplot(A)for c in (0.05, 0.01, 0.002): thresh = A_fft_sort[int(np.floor((1- c) *len(A_fft_sort)))] A_fft_th = A_fft * (np.abs(A_fft) > thresh) A_th = np.fft.ifft2(A_fft_th).real myplot(A_th)
(a) Original image.
(b) 5% of FFT coefficients
(c) 1% of FFT coefficients
(d) 0.2% of FFT coefficients
Figure 11.2: Image of MCI I and the reconstruction with various amounts of FFT coefficients left.
We can also use the FFT for de-noising and filtering of signals. It is rather simple to just eliminate certain frequency bands in the frequency domain.
Show the code for the figure
import matplotlib.pyplot as pltimport imageio.v3 as iioimport numpy as np%config InlineBackend.figure_formats = ['svg']np.random.seed(6020)im = np.asarray(iio.imread("https://www.mci.edu/en/download/27-logos-bilder?""download=618:mci-eu-web"))def rgb2gray(rgb):return np.dot(rgb[...,:3], [0.2989, 0.5870, 0.1140])def myplot(A): plt.figure() plt.imshow(A, cmap="gray") plt.axis("off") plt.gca().set_aspect(1)A = rgb2gray(im)A_noise = A + (200* np.random.randn(*A.shape)).astype('uint8')A_noise_fft = np.fft.fft2(A_noise)A_noise_fft_shift = np.fft.fftshift(A_noise_fft)F = np.log(np.abs(A_noise_fft_shift) +1)myplot(A_noise)myplot(F)nx, ny = A.shapeX, Y = np.meshgrid(np.arange(-ny/2+1, ny /2+1), np.arange(-nx /2+1, nx /2+1))R2 = np.power(X, 2) + np.power(Y, 2)ind = R2 <150**2A_noise_fft_shift_filter = A_noise_fft_shift * indF_filter = np.log(np.abs(A_noise_fft_shift_filter) +1)A_filter = np.fft.ifft2(np.fft.fftshift(A_noise_fft_shift_filter)).realmyplot(A_filter)myplot(F_filter)
(a) Noisy image.
(b) Noisy FFT coefficients
(c) Filtered/De-noised image
(d) Filtered/De-noised FFT coefficients
Figure 11.3: Image of MCI I and the reconstruction with various amounts of FFT coefficients left.
11.2 Wavelet
Similar to the FFT also the Wavelet transform is used in much the same situations.
Before we go on and apply the wavelet transform in the same situations we show how the multi level approach looks like for an image. For the image we use the Daubechies 1 wavelets.