MATLAB - 快速傅里叶变换
MATLAB - 快速傅里叶变换 (FFT) 实践
Section titled “MATLAB - 快速傅里叶变换 (FFT) 实践”快速傅里叶变换(FFT)是信号处理中的一个关键算法。其主要目的是将信号从其原始域(通常是时间)分解为其组成频率。实质上,FFT 告诉你信号中存在哪些频率以及它们的幅度是多少。
MATLAB 的 fft() 函数提供了该算法的高效实现。有效使用它的关键不仅仅是调用函数,还在于理解其输出以及如何针对有意义的频率轴正确地绘制它。
一个完整、实用的例子:分析含噪信号
Section titled “一个完整、实用的例子:分析含噪信号”让我们逐步讲解一个完整、真实的例子。我们将创建一个包含两个不同正弦波的信号,添加一些随机噪声,然后使用 FFT 来识别原始频率。
步骤 1:创建时域信号
Section titled “步骤 1:创建时域信号”% 信号参数Fs = 1000; % 采样频率 (Hz)T = 1/Fs; % 采样周期 (s)L = 1500; % 信号长度t = (0:L-1)*T; % 时间向量
% 创建一个包含 50 Hz 和 120 Hz 正弦波的信号S = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);
% 向信号添加零均值随机噪声X = S + 2*randn(size(t));
% 为了可视化我们的含噪信号,我们可以绘制它:% plot(1000*t(1:50), X(1:50))% title('含噪时域信号(前 50 毫秒)')% xlabel('t (毫秒)')% ylabel('X(t)')此时,仅凭观察时域图,将很难识别出 50 Hz 和 120 Hz 的分量。
步骤 2:计算 FFT
Section titled “步骤 2:计算 FFT”现在,我们将 fft 函数应用于我们的含噪信号 X。
Y = fft(X);步骤 3:计算频谱
Section titled “步骤 3:计算频谱”FFT 的输出 Y 是一个复值向量。为了获得幅度,我们取其绝对值。FFT 的结果对于实值输入也是对称的。我们通常只对频谱的前半部分(即单边频谱)感兴趣。
% 计算双边频谱 P2。P2 = abs(Y/L);
% 基于 P2 和偶数值的信号长度 L 计算单边频谱 P1。P1 = P2(1:L/2+1);P1(2:end-1) = 2*P1(2:end-1);这里,我们除以 L 来归一化幅度。然后我们取前半部分的点,并将除了第一个(直流分量,DC)和最后一个(奈奎斯特频率,Nyquist)分量之外的所有分量乘以 2,以守恒信号的能量。
步骤 4:定义频率轴并绘图
Section titled “步骤 4:定义频率轴并绘图”为了使图表有意义,我们需要创建一个与频谱 P1 中的点相对应的频率向量。
% 定义频域 ff = Fs*(0:(L/2))/L;
% 绘制单边幅度频谱 P1plot(f, P1)title('Single-Sided Amplitude Spectrum of X(t)')xlabel('f (Hz)')ylabel('|P1(f)|')axis([0 200 0 1.2]) % 将视图聚焦在我们感兴趣的频率上预期输出描述:生成的图表将显示一个从 0 Hz 开始的频率轴。尽管原始信号中存在严重的噪声,你仍将看到两个清晰、尖锐的峰值。一个位于 50 Hz,幅度约为 0.7;另一个位于 120 Hz,幅度约为 1.0,这成功识别了我们原始信号 S 的分量。
其他 fft 语法
Section titled “其他 fft 语法”指定长度 (n) 的 FFT
Section titled “指定长度 (n) 的 FFT”Y = fft(X, n) 计算 n 点 FFT。如果 X 的点数少于 n,它将用零填充。如果点数多于 n,它将被截断。零填充是一种提高 FFT 频率分辨率的常用技术,使其更容易精确定位峰值频率。
% 使用我们的原始信号 X(长度 1500)% 计算 2048 点 FFT(零填充)Y_padded = fft(X, 2048);沿特定维度的 FFT
Section titled “沿特定维度的 FFT”Y = fft(X, n, dim) 沿维度 dim 计算 FFT。这对于处理存储在矩阵的列或行中的多个信号非常有用。
% 创建一个以 2 个信号作为列的矩阵signal1 = sin(2*pi*50*t)';signal2 = sin(2*pi*150*t)';X_matrix = [signal1, signal2];
% 计算每列的 FFT(dim=1 是默认值)Y_matrix = fft(X_matrix);
% 要计算每行的 FFT,你可以使用:% Y_matrix_rows = fft(X_matrix, [], 2);- 逆 FFT (
ifft):要将信号从频域转换回时域,请使用ifft函数。 fftshift:fft的原始输出将零频率(直流,DC)分量放在数组的开头。对于某些类型的分析和可视化,将直流分量置于中心会很有用。fftshift函数可以实现这一点。- 频谱泄漏和加窗:当信号在测量窗口内不是周期性时,会导致其能量“泄漏”到相邻的频率分箱中,模糊峰值。为了缓解这种情况,你可以在执行 FFT 之前将信号乘以一个窗函数(例如
hann或hamming)。这是专业频谱分析中的关键一步。