频域分析是信号处理的核心手段,它将时域的信号(随时间变化的波形)转换为频域的频谱(频率-幅值/相位分布),帮你看清信号的频率组成、谐波成分、噪声特征。MATLAB凭借强大的fft、psd等函数,是频域分析的首选工具,本文从基础原理到实战案例,手把手教你掌握MATLAB频域分析的全流程。
一、频域分析核心原理:新手也能懂的基础
1.1 时域vs频域:直观理解
- 时域:描述信号“随时间变化的幅度”,比如麦克风采集的声音波形、传感器的振动曲线;
- 频域:描述信号“由哪些频率的正弦波组成”,比如音乐的低音(低频)、高音(高频),电机振动的50Hz工频噪声。
核心转换工具:傅里叶变换(FFT) ——把时域的非周期信号分解为不同频率的正弦波叠加,是MATLAB频域分析的核心。
1.2 关键概念(避坑必备)
| 概念 | 定义 |
|---|---|
采样频率Fs |
每秒采集的样本数(单位Hz),比如采集音频时Fs=44100Hz(每秒采44100个点); |
采样点数N |
采集的总样本数,比如采集1秒信号,Fs=1000Hz,则N=1000; |
频率分辨率df |
频域中每个频率点的间隔,df = Fs/N,N越大,分辨率越高; |
| 奈奎斯特频率 | Fs/2,频域分析的最大有效频率(超过则出现混叠,结果失真); |
二、MATLAB频域分析基础环境与核心函数
2.1 无需额外安装
MATLAB自带信号处理工具箱(Signal Processing Toolbox),默认包含fft、fftshift、pwelch等核心函数,无需额外配置。
2.2 核心函数速查
| 函数名 | 功能 |
|---|---|
fft(x) |
对时域信号x做快速傅里叶变换,返回复数形式的频域结果; |
fftshift(x) |
将fft结果的零频点移到中心,便于可视化; |
abs(x) |
计算复数的幅值(频域分析中用于提取幅值谱); |
angle(x) |
计算复数的相位(提取相位谱); |
pwelch(x) |
计算功率谱密度(PSD),适合分析非平稳信号、含噪声信号; |
fspecial |
生成窗函数(如汉宁窗、汉明窗,减少频谱泄漏); |
三、实战1:基础FFT分析——纯正弦波的频域转换
3.1 需求
生成一个50Hz的正弦波(时域),用FFT转换为频域,验证50Hz的频率峰值。
3.2 完整代码(可直接复制运行)
%% 步骤1:生成时域正弦波信号
Fs = 1000; % 采样频率1000Hz
t = 0:1/Fs:1-1/Fs; % 时间轴(0到1秒,步长1/Fs)
f0 = 50; % 信号频率50Hz
x = sin(2*pi*f0*t); % 生成50Hz正弦波% 可视化时域信号
figure(1)
plot(t, x)
title('50Hz正弦波时域波形')
xlabel('时间t (s)')
ylabel('幅值')
grid on;%% 步骤2:FFT频域转换
N = length(x); % 采样点数N=1000
X = fft(x); % 做FFT变换(复数结果)
X_amp = abs(X)/N * 2; % 计算幅值谱(除以N×2,还原真实幅值)
f = (0:N-1)*Fs/N; % 频率轴(0到Fs)% 只取0~Fs/2的有效频率(奈奎斯特频率内)
f_valid = f(1:N/2);
X_amp_valid = X_amp(1:N/2);%% 步骤3:可视化频域幅值谱
figure(2)
plot(f_valid, X_amp_valid)
title('50Hz正弦波频域幅值谱')
xlabel('频率f (Hz)')
ylabel('幅值')
grid on;
xlim([0 100]); % 只显示0~100Hz,聚焦50Hz峰值
3.3 结果解读
- 时域图:标准的50Hz正弦波,周期性波动;
- 频域图:在50Hz处出现明显峰值,幅值≈1(与正弦波幅值一致),其他频率幅值接近0,验证FFT转换的正确性。
3.4 关键代码说明
X_amp = abs(X)/N * 2:FFT结果的幅值需要归一化——除以采样点数N,乘以2(仅针对0~Fs/2的有效频率),才能还原信号的真实幅值;- 若信号包含直流分量(常数),直流分量的幅值只需除以N(无需×2)。
四、实战2:进阶FFT分析——含噪声+多频率信号
4.1 需求
生成包含50Hz+120Hz的混合正弦波,叠加随机噪声,用FFT提取真实频率成分(模拟实际传感器采集的含噪信号)。
4.2 完整代码
%% 步骤1:生成含噪多频率信号
Fs = 1000;
t = 0:1/Fs:2-1/Fs; % 采集2秒,N=2000
f1 = 50; % 第一个频率
f2 = 120; % 第二个频率
x = 2*sin(2*pi*f1*t) + 1*sin(2*pi*f2*t) + 0.5*randn(size(t)); % 叠加0.5倍随机噪声% 时域可视化
figure(1)
plot(t, x)
title('含噪多频率信号时域波形')
xlabel('时间t (s)')
ylabel('幅值')
grid on;%% 步骤2:加窗函数(减少频谱泄漏)
win = hanning(N); % 汉宁窗(常用窗函数,避免频谱扩散)
x_win = x .* win; % 信号乘窗函数%% 步骤3:FFT转换+幅值谱计算
N = length(x);
X = fft(x_win);
X_amp = abs(X)/N * 2;
f = (0:N-1)*Fs/N;
f_valid = f(1:N/2);
X_amp_valid = X_amp(1:N/2);%% 步骤4:频域可视化
figure(2)
plot(f_valid, X_amp_valid)
title('含噪多频率信号频域幅值谱(加汉宁窗)')
xlabel('频率f (Hz)')
ylabel('幅值')
grid on;
xlim([0 200]); % 聚焦0~200Hz
4.3 关键知识点
1. 窗函数的作用
不加窗时,非整周期采样的信号会出现“频谱泄漏”——50Hz/120Hz的峰值会扩散到相邻频率,加汉宁窗/汉明窗可大幅减少泄漏,让峰值更尖锐。
常用窗函数对比:
- 汉宁窗(
hanning()):频谱泄漏小,分辨率适中(最常用); - 汉明窗(
hamming()):主瓣更窄,适合频率密集的信号; - 矩形窗(默认,无窗):频谱泄漏大,仅适合整周期采样的信号。
2. 结果解读
频域图中能清晰看到50Hz(幅值≈2)、120Hz(幅值≈1)的峰值,噪声被压制,说明FFT能有效提取含噪信号的核心频率。
五、实战3:功率谱密度(PSD)分析——非平稳信号
5.1 需求
分析非平稳信号(频率随时间变化)的功率分布,用pwelch函数计算功率谱密度(PSD),比FFT更适合含噪、非平稳信号。
5.2 完整代码
%% 步骤1:生成调频信号(非平稳)
Fs = 1000;
t = 0:1/Fs:5-1/Fs;
f_start = 20; % 起始频率20Hz
f_end = 80; % 结束频率80Hz
% 生成线性调频信号(频率从20Hz渐变到80Hz)
x = chirp(t, f_start, max(t), f_end) + 0.3*randn(size(t));%% 步骤2:用pwelch计算功率谱密度
% pwelch参数:信号、窗长、重叠长度、FFT点数、采样频率
[Pxx, f] = pwelch(x, hanning(256), 128, 1024, Fs);%% 步骤3:可视化PSD
figure(1)
plot(f, 10*log10(Pxx)) % 转换为分贝(dB),更易观察
title('调频信号功率谱密度(PSD)')
xlabel('频率f (Hz)')
ylabel('功率谱密度 (dB/Hz)')
grid on;
xlim([0 100]);
5.3 结果解读
PSD图中,20~80Hz范围内有明显的功率峰值,对应调频信号的频率变化范围;分贝刻度能放大微弱的功率信号,适合分析噪声背景下的有用信号。
六、频域分析常见坑与避坑技巧
6.1 频谱泄漏(最常见)
- 问题:信号采样不是整周期,导致频率峰值扩散;
- 解决:加窗函数(汉宁窗/汉明窗),或增加采样点数N。
6.2 频率混叠
- 问题:采样频率
Fs小于2倍信号最高频率,导致高频信号被错误显示为低频; - 解决:采样前用低通滤波器滤波,或提高采样频率
Fs(至少为信号最高频率的2.5~3倍)。
6.3 幅值归一化错误
- 问题:FFT幅值未除以N×2,导致幅值结果远大于真实值;
- 解决:严格执行
X_amp = abs(X)/N * 2(有效频率段)。
6.4 频率轴设置错误
- 问题:频率轴超出奈奎斯特频率(Fs/2),显示无效频率;
- 解决:只取
f(1:N/2)作为有效频率轴。
七、MATLAB频域分析进阶方向
- 二维频域分析:对图像做FFT(
fft2函数),分析图像的频率特征(如边缘对应高频,背景对应低频); - 短时傅里叶变换(STFT):用
stft函数分析时变频率信号(如语音、雷达信号),得到“时间-频率-幅值”三维谱; - 小波变换:比FFT更适合分析非平稳信号,用
wavedec函数实现; - 频谱分析自动化:编写脚本自动提取峰值频率、计算谐波失真、生成分析报告。