快速傅里叶变换(Fast Fourier Transform,FFT)是一种算法,用于快速计算离散傅里叶变换(DFT)及其逆变换。傅里叶变换将时间或空间域的信号转换为频率域的信号,便于分析信号的频率特性。FFT显著提高了计算效率,将计算复杂度从 O ( n 2 ) O(n^2) O(n2)降低到 O ( n log n ) O(n \log n) O(nlogn)。
FFT的基本原理
傅里叶变换的基本公式为:
X ( k ) = ∑ n = 0 N − 1 x ( n ) ⋅ e − j 2 π N k n X(k) = \sum_{n=0}^{N-1} x(n) \cdot e^{-j \frac{2\pi}{N}kn} X(k)=n=0∑N−1x(n)⋅e−jN2πkn
其中, x ( n ) x(n) x(n)是时间域信号, X ( k ) X(k) X(k)是频率域信号, N N N是信号的长度, j j j是虚数单位。
FFT利用分治法,将DFT分解成若干个更小的DFT计算。常用的算法包括Cooley-Tukey算法、分裂基算法等。
Cooley-Tukey算法
Cooley-Tukey算法是最常用的FFT算法,它将DFT分解成两个长度为 N / 2 N/2 N/2的DFT,递归计算,直到达到最小子问题。
-
将原始序列分为奇数和偶数两部分:
X ( k ) = ∑ n = 0 N / 2 − 1 x ( 2 n ) ⋅ e − j 2 π N 2 n k + ∑ n = 0 N / 2 − 1 x ( 2 n + 1 ) ⋅ e − j 2 π N ( 2 n + 1 ) k X(k) = \sum_{n=0}^{N/2-1} x(2n) \cdot e^{-j \frac{2\pi}{N} 2nk} + \sum_{n=0}^{N/2-1} x(2n+1) \cdot e^{-j \frac{2\pi}{N} (2n+1)k} X(k)=n=0∑N/2−1x(2n)⋅e−jN2π2nk+n=0∑N/2−1x(2n+1)⋅e−jN2π(2n+1)k -
通过变换得到:
X ( k ) = ∑ n = 0 N / 2 − 1 x ( 2 n ) ⋅ e − j 2 π N / 2 n k + e − j 2 π N k ∑ n = 0 N / 2 − 1 x ( 2 n + 1 ) ⋅ e − j 2 π N / 2 n k X(k) = \sum_{n=0}^{N/2-1} x(2n) \cdot e^{-j \frac{2\pi}{N/2} nk} + e^{-j \frac{2\pi}{N} k} \sum_{n=0}^{N/2-1} x(2n+1) \cdot e^{-j \frac{2\pi}{N/2} nk} X(k)=n=0∑N/2−1x(2n)⋅e−jN/22πnk+e−jN2πkn=0∑N/2−1x(2n+1)⋅e−jN/22πnk -
递归计算两个 N / 2 N/2 N/2长度的DFT,最终合并结果。
FFT的应用
FFT广泛应用于信号处理、图像处理、音频处理、谱分析等领域。例如:
- 音频处理:FFT用于分析音频信号的频谱成分,以进行音频压缩、噪声消除等操作。
- 图像处理:通过FFT进行图像的频域处理,如滤波、边缘检测等。
- 通信:FFT在数字信号处理(DSP)中用于调制解调、信号分析等。
代码示例
以下是一个使用Python中的numpy
库计算FFT的示例:
import numpy as np
import matplotlib.pyplot as plt# 生成一个信号:包含两个不同频率的正弦波
fs = 1000 # 采样频率
t = np.arange(0, 1, 1/fs) # 时间序列
f1, f2 = 50, 120 # 信号频率
x = 0.6 * np.sin(2 * np.pi * f1 * t) + 0.4 * np.sin(2 * np.pi * f2 * t)# 计算FFT
X = np.fft.fft(x)
freqs = np.fft.fftfreq(len(X), 1/fs)# 绘制频谱
plt.figure()
plt.plot(freqs[:len(freqs)//2], np.abs(X)[:len(X)//2])
plt.xlabel('Frequency (Hz)')
plt.ylabel('Amplitude')
plt.title('Frequency Spectrum')
plt.show()
这个示例生成了一个包含50Hz和120Hz两个频率成分的信号,通过FFT计算频谱并绘制结果。