MATLAB的pwelch与Python SciPy的welch方法输出缩放差异问题咨询
welch与pwelch恒定缩放差异成因说明
核心原因:单位归一化约定不同
二者输出的恒定34dB差完全来自功率谱密度的单位定义差异:
- 你调用MATLAB的
pwelch时未传入采样频率fs参数,此时MATLAB默认输出角频率归一化功率谱密度,单位为「功率/(rad/采样)」,频率轴归一化到实信号单边区间[0, π]。 - 你调用scipy的
signal.welch时传入了fs=16000,输出的是物理频率功率谱密度,单位为「功率/Hz」,频率轴范围为实信号单边区间[0, 8000]。
二者的单位转换系数为 fs/(2π),代入fs=16000计算得 16000/(2π) ≈ 2546,对应分贝值为 10*log10(2546) ≈ 34dB,和你观测的恒定差值完全匹配。
其他微小差异来源
MATLAB的pwelch默认会对每个信号段做去直流处理(对应参数detrend='constant'),而你的Python代码中设置了detrend=False,如果输入信号存在直流分量,会导致直流频点的计算结果存在差异,但不会影响整体的缩放比例。
结果对齐方案
方案1:统一输出物理频率PSD(工程常用)
修改MATLAB调用代码,传入采样频率参数即可,修改后二者输出误差在数值精度范围内:
pxx_matlab = pwelch(w_in,4096,0.5*4096,4096,16000);
方案2:统一输出归一化频率PSD
修改Python代码,将scipy输出的PSD做单位转换,即可对齐MATLAB默认输出:
from scipy import signal import numpy as np f, pxx = signal.welch(w_in, fs=16000, window='hamming', nperseg=4096, noverlap=2048, nfft=4096, detrend=False) # 转换为和MATLAB默认一致的归一化PSD pxx_normalized = pxx * 2 * np.pi / 16000
内容的提问来源于stack exchange,提问作者Triceratops
相关产品推荐
相关产品推荐

