功率谱密度(PSD)是频域分析中针对含噪信号、非平稳信号的核心分析方法,能量化信号在不同频率上的功率分布,比基础FFT更适合实际工程场景(如振动监测、音频分析、传感器信号处理)。MATLAB中最常用的PSD分析函数是pwelch(基于Welch法),本文从基础用法、完整实战、参数优化三个维度,手把手教你落地PSD分析,代码可直接复制运行。
一、核心前提:理解PSD与Welch法
1.1 PSD的核心价值
- 基础FFT适合分析平稳、无噪的纯正弦信号,但实际采集的信号(如电机振动、环境音频)多含噪声、频率随时间变化;
- PSD通过“分段加窗+重叠平均”的方式,降低噪声干扰,平滑频谱曲线,清晰提取信号的核心频率功率特征。
1.2 无需额外配置
MATLAB自带Signal Processing Toolbox,pwelch函数默认可用,无需额外安装。
二、基础用法:3步完成PSD分析
步骤1:准备时域信号(含采样频率)
PSD分析的前提是明确采样频率Fs(每秒采集的样本数)和时域信号数据,以下为模拟含噪信号示例:
% 1. 定义采样参数
Fs = 1000; % 采样频率1000Hz
t = 0:1/Fs:5-1/Fs; % 时间轴:0~5秒,步长1/Fs
N = length(t); % 采样点数:5000
% 2. 生成含噪信号(50Hz+120Hz正弦波叠加随机噪声)
f1 = 50; f2 = 120; % 核心频率
x = 2*sin(2*pi*f1*t) + 1*sin(2*pi*f2*t) + 0.5*randn(size(t));
% 可视化原始时域信号
figure(1)
plot(t, x)
title('含噪多频率信号时域波形')
xlabel('时间 t (s)')
ylabel('幅值')
grid on;
xlim([0 1]); % 只显示前1秒,便于观察波形
步骤2:调用pwelch计算PSD(最简版)
pwelch的核心语法:[Pxx, f] = pwelch(x, window, noverlap, nfft, Fs);
% 最简调用(使用默认参数)
[Pxx, f] = pwelch(x, [], [], [], Fs);
% 可视化PSD结果(转换为分贝dB,更易观察)
figure(2)
plot(f, 10*log10(Pxx)) % 10*log10(Pxx)将功率转换为分贝刻度
title('PSD分析结果(默认参数)')
xlabel('频率 f (Hz)')
ylabel('功率谱密度 (dB/Hz)')
grid on;
xlim([0 200]); % 聚焦0~200Hz,查看50/120Hz峰值
步骤3:结果解读
- 横轴:频率(0~Fs/2,符合奈奎斯特采样定理);
- 纵轴:功率谱密度(dB/Hz),数值越高表示该频率的功率越大;
- 图中会清晰看到50Hz和120Hz的功率峰值,噪声被有效压制,对比基础FFT更平滑。
三、进阶实战:自定义参数优化PSD分析
pwelch的默认参数适合通用场景,但实际分析中需根据信号特征调整参数,核心参数包括:窗函数、重叠长度、FFT点数,以下为优化后的完整代码:
3.1 完整代码(可直接运行)
%% 步骤1:准备信号(同基础用法)
Fs = 1000;
t = 0:1/Fs:5-1/Fs;
f1 = 50; f2 = 120;
x = 2*sin(2*pi*f1*t) + 1*sin(2*pi*f2*t) + 0.5*randn(size(t));
%% 步骤2:自定义PSD分析参数
win_len = 256; % 窗长(每段信号的长度,建议为2的幂次)
window = hanning(win_len); % 汉宁窗(减少频谱泄漏,常用:hanning/hamming/blackman)
noverlap = win_len/2; % 重叠长度(通常为窗长的50%,提升平滑度)
nfft = 1024; % FFT点数(越大频率分辨率越高,建议≥窗长)
%% 步骤3:计算PSD
[Pxx, f] = pwelch(x, window, noverlap, nfft, Fs);
%% 步骤4:可视化+峰值提取
figure(3)
plot(f, 10*log10(Pxx))
title('优化参数后的PSD分析结果(汉宁窗+50%重叠)')
xlabel('频率 f (Hz)')
ylabel('功率谱密度 (dB/Hz)')
grid on;
xlim([0 200]);
% 提取峰值频率(进阶:自动识别核心频率)
[max_pow, idx] = findpeaks(10*log10(Pxx), f, 'MinPeakHeight', 10); % 峰值阈值10dB
hold on;
plot(f(idx), max_pow, 'ro', 'MarkerSize', 8, 'DisplayName', '峰值频率');
legend('PSD曲线', '峰值频率');
hold off;
% 输出峰值频率
fprintf('核心峰值频率:');
for i = 1:length(idx)
fprintf('%.1fHz ', f(idx(i)));
end
3.2 核心参数说明(避坑必备)
| 参数 | 作用与设置建议 |
|---|---|
window | 窗函数: - 汉宁窗( hanning):频谱泄漏小,最常用;- 汉明窗( hamming):主瓣更窄,适合频率密集信号;- 窗长建议取2的幂次(如128/256/512),兼顾计算效率和分辨率。 |
noverlap | 重叠长度:通常设为窗长的50%(如窗长256则重叠128),增加分段数量,让PSD曲线更平滑。 |
nfft | FFT点数:≥窗长即可,越大频率分辨率越高(df=Fs/nfft),如Fs=1000、nfft=1024时,分辨率≈0.977Hz。 |
3.3 输出结果示例
核心峰值频率:50.0Hz 120.1Hz
图中红色圆点会精准标记50Hz和120Hz的功率峰值,直观提取信号核心频率。
四、特殊场景:非平稳信号的PSD分析(时频联合分析)
对于频率随时间变化的信号(如调频音频、电机启动过程的振动信号),可结合spectrogram函数(短时傅里叶变换)实现“时间-频率-功率”三维PSD分析:
%% 生成调频信号(频率从20Hz渐变到80Hz)
Fs = 1000;
t = 0:1/Fs:5-1/Fs;
x = chirp(t, 20, max(t), 80) + 0.3*randn(size(t)); % 线性调频信号+噪声
%% 短时傅里叶变换(时频PSD)
window = hanning(256);
noverlap = 128;
nfft = 1024;
spectrogram(x, window, noverlap, nfft, Fs, 'yaxis');
title('调频信号时频PSD图谱');
colorbar; % 颜色越深表示该时间-频率点的功率越大
结果解读
- 横轴:时间,纵轴:频率,颜色:功率密度;
- 可清晰看到频率从20Hz随时间线性上升到80Hz的轨迹,适合分析时变信号的功率分布。
五、常见坑与避坑技巧
5.1 PSD曲线噪声大、峰值不明显
- 原因:窗长过小、重叠率低,分段平均效果差;
- 解决:增大窗长(如从128改为256)、将重叠率提高到75%(
noverlap=win_len*0.75)。
5.2 频率分辨率不足,峰值频率模糊
- 原因:nfft过小,频率间隔
df太大; - 解决:增大nfft(如从512改为1024/2048),或提高采样频率Fs。
5.3 频谱泄漏导致峰值扩散
- 原因:未加窗函数或窗函数选择不当;
- 解决:优先使用汉宁窗/汉明窗,避免使用矩形窗(默认无窗)。
5.4 功率值解读错误
- 注意:PSD的单位是
V²/Hz(电压信号)或g²/Hz(振动信号),转换为分贝(10*log10(Pxx))仅为可视化方便,不改变频率特征。