395 次浏览

傅里叶变换-numpy

傅里叶变换,可以将函数表示成三角函数的的积分(线性组合)

傅里叶变换基本公式:
\(\)\(F(\omega)=F(f(t)) = \lmoustache ^\infty _{-\infty} f(t) e ^{-i \omega t} dt\)\(\)
\(\)\(f(t) = F^{-1}[F(\omega)] = \frac{1}{2 \pi}\lmoustache ^\infty _{-\infty} F(\omega e^{i \omega t}d\omega)\)\(\)

一般使用计算机进行傅里叶变换,采集的是一个离散的信号,所以一般使用的是离散傅里叶变换,但是离散傅里叶变换,时间复杂度是O(N*N),大多数时候使用快速傅里叶变换。

离散傅里叶变换:
我们将采集的离散信号进行标号[0, …. , N-1], 离散信号记为m
\(\)\(F[m]= F(f)[m]= \sum ^N _ {n=0}f[n]e^{-\frac{2\pi i nm}{N}}\)\(\)
因为傅里叶变换就是使用一组正交函数基进行线性组合,通过转换到向量乘法,\(\)\(f\)\(\)为关于n的向量,\(\)\(e^{-\frac{2\pi inm}{N}}\)\(\)是关于\(\)\(e^{-\frac{2\pi i}{N}}\)\(\)的矩阵,同时这个矩阵是个对称阵,从这个对称阵中,我们还可以发现在以N为周期的离散傅里叶变换中,变换的结果也是对称的(这也是\(\)\(e^{-\frac{2\pi i}{N}}\)\(\)的一个良好性质,\(\)\(e^{-\frac{2\pi iN}{N}}=1\)\(\))。

使用numpy进行傅里叶变换,调用numpy.fft即可。

import numpy as np
import matplotlib.pyplot as plt

img = plt.imread("cat01.jpg")
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
fo = np.fft.ifftshift(fshift)
iff = np.fft.ifft2(f)

# 低通滤波
crow, ccol = int(img.shape[0] / 2), int(img.shape[1] / 2)
mask = np.zeros((img.shape[0], img.shape[1]), np.uint8)
mask[crow-40:crow+40, ccol-40:ccol+40] = 1
mask_img = fshift * mask
img_idf = np.fft.ifftshift(mask_img)
lowpass_iff = np.fft.ifft2(img_idf)

# 高通滤波
crow, ccol = int(img.shape[0] / 2), int(img.shape[1] / 2)
mask = np.ones((img.shape[0], img.shape[1]), np.uint8)
mask[crow-40:crow+40, ccol-40:ccol+40] = 0
mask_img = fshift * mask
img_idf = np.fft.ifftshift(mask_img)
highpass_iff = np.fft.ifft2(img_idf)

plt.figure(figsize=(10, 8))
plt.subplot(231)
plt.imshow(img, cmap='gray')
plt.title('Origin Image')
plt.axis('off')

plt.subplot(232)
plt.imshow(20 * np.log(np.abs(fshift)),cmap='gray')
plt.title('Fourier Transform')

plt.subplot(234)
plt.imshow(np.abs(iff),cmap='gray')
plt.title('ifft2')
plt.axis('off')

plt.subplot(235)
plt.imshow(np.abs(lowpass_iff),cmap='gray')
plt.title('low pass')
plt.axis('off')

plt.subplot(236)
plt.imshow(np.abs(highpass_iff),cmap='gray')
plt.title('high pass')
plt.axis('off')

plt.show()

可以从运行结果看到,进行一次傅里叶变换,为了更好的查看信号在频域上的分布,使用np.fft.fftshift函数进行整理,第2张图可以看到,结果是对称,也符合傅里叶变换之后的对称性。从第4张图可以看到,通过低通滤波,图片变得模糊了许多,这也就是低通滤波的作用。高通滤波则是可以更好的提取细节信息,如图5。

当然对于最后两张图,我们很容易想到CNN的卷积操作,不同于这里我们对频谱进行排序,然后进行过滤,CNN直接使用一个conv算子进行计算,减少了傅里叶变换的工作。