如何从复杂计算的 STFT 计算 PSD?

信息处理 功率谱密度 频谱图 stft scipy
2022-02-05 13:01:57

我用 scipy python 库计算了 STFT:

f_spec, t_spec, Spectro= sc.signal.spectrogram(My_Signal, fs=1.0, window='hamming', nperseg=180,
                        noverlap=None, nfft=2048, detrend=False, return_onesided=False, scaling='density',
                        axis=-1, mode='complex')

我想得到与 MATLAB 的频谱图函数相同的结果,现在我想以 dB 为单位计算它的 PSD。事实上,我在互联网上找到了几种表达方式,例如:

PSD=Spectro^2

或者 :

PSD = 10*log10(abs(Spectro))

我不知道用什么可以帮助我吗?

2个回答

一般来说,如果您有复杂的频谱并且需要以 dB 为单位的 PSD,则数学方程为

Pxx=20log10|Xx|,
其中是您的 PSD,以 dB 为单位,是您的复杂 STFT 频谱(在您的情况下是可变的)。PxxXxSpectro

scipy.signal.spectrogram的 SciPy 文档中提到,您可以计算具有不同模式('psd'、'complex'、'magnitude'、'angle'、'phase')的频谱图。您选择了mode='complex',它返回复杂的 STFT,因此您应该从上面的等式中获得 PSD。如果您选择了mode='psd'您将首先获得 PSD 例如在您的情况下)并将其转换为 dB,您的等式是SxxSpectro

Pxx=10log10Sxx.

但是,如果您想绘制与 MATLAB 相同的频谱图,我会选择等效的matplotlib.pyplot.specgram,它非常相似,您可以使用此工具以 dB 为单位绘制 PSD。

我通常使用 Welch 方法来计算和绘制信号的 PSD。

signal_f, signal_psd = sp.welch(signal, sampling_frequency, return_onesided=False, nperseg=256)
signal_f = np.fft.fftshift(signal_f)
signal_psd = np.fft.fftshift(signal_psd)

plt.semilogy(signal_f, signal_psd, label = 'PSD')

也许它可以帮助你!