Python Scipy 语谱图

1 投票
1 回答
45 浏览
提问于 2025-04-13 03:02

我正在尝试绘制一些 .wav 文件的声谱图。

我最开始是在 Matlab 中实现的,效果很好。

这是 Matlab 的代码:

sound = audioread(x); 
[S, F, T] = spectrogram(sound(:,1),1000,500,1000,48000); %get channel 1
S_dB = mag2db(abs(S));
%disp(S_dB)


%play sound
[y, fs] = audioread(x);
player = audioplayer(y, fs);
play(player);

%plot figure
figure;
imagesc(T, F, S_dB);
axis xy;
title(x,'Spectrogram');
xlabel('Time (s)');
ylabel('Frequency (Hz)');
colorbar;

这是 Matlab 绘制的图:

matlab spectrogram plot

现在我想把代码转到 Python,所以我在用 scipy。我写了以下代码:


    rate, data = wavfile.read(file)
    #from Matlab: spectrogram(X = sound(:,1), WINDOW = 1000, NOVERLAP = 500,F = 1000,Fs = 48000)
    f, t, Sxx = signal.spectrogram(data, fs=48000, window=('hamming'), nperseg=1000, noverlap=500, nfft=1000, detrend = 'constant', return_onesided=True, scaling='density', axis=-1, mode='psd')
    dB = control.mag2db(np.abs(Sxx)) #get magnitude of signal and convert to dB
    plt.pcolormesh(t, f, dB, shading='gouraud')
    plt.ylabel('Frequency [Hz]')
    plt.xlabel('Time [sec]')
    plt.colorbar()
    plt.title(file) #V up, V down, H up, H down
    plt.show()

但是在 Python 中绘制出来的图是这样的: Python Spectrogram plot

我是在一个录音机上录制的这些声音,最大分贝是 -0 dB,所以我知道 Matlab 的结果是对的。我不太确定该如何在 Python 中修复这个问题。

在 Matlab 中返回的 S 是由复数构成的,而在 Python 中返回的 Sxx 是实数(这些实数和 Matlab 中的实数部分不同)。我不明白这些数字为什么差别这么大?任何建议都很有帮助,谢谢!

1 个回答

0

如果你把 mode='psd' 设置上,那么 scipy.signal.spectrogram 返回的就是幅度的平方。所以 Sxx 应该等于 abs(S) 的平方。

撰写回答