Librosa的英尺和Scipy的英尺不同?

时间:2019-05-24 05:55:11

标签: python python-3.x scipy spectrogram librosa

Librosa和Scipy都具有fft功能,即使在相同的信号输入下,它们也为我提供了不同的频谱图输出。

Scipy

我正在尝试使用以下代码获取频谱图

import numpy as np                                       # fast vectors and matrices
import matplotlib.pyplot as plt                          # plotting
from scipy import fft      

X = np.sin(np.linspace(0,1e10,5*44100))

fs = 44100          # assumed sample frequency in Hz
window_size = 2048  # 2048-sample fourier windows
stride = 512        # 512 samples between windows
wps = fs/float(512) # ~86 windows/second
Xs = np.empty([int(2*wps),2048])

for i in range(Xs.shape[0]):
    Xs[i] = np.abs(fft(X[i*stride:i*stride+window_size]))

fig = plt.figure(figsize=(20,7))
plt.imshow(Xs.T[0:150],aspect='auto')
plt.gca().invert_yaxis()
fig.axes[0].set_xlabel('windows (~86Hz)')
fig.axes[0].set_ylabel('frequency')
plt.show()

然后我得到以下频谱图 enter image description here

Librosa

现在我尝试使用Librosa获得相同的频谱图

from librosa import stft

X_libs = stft(X, n_fft=window_size, hop_length=stride)
X_libs = np.abs(X_libs)[:,:int(2*wps)]

fig = plt.figure(figsize=(20,7))
plt.imshow(X_libs[0:150],aspect='auto')
plt.gca().invert_yaxis()
fig.axes[0].set_xlabel('windows (~86Hz)')
fig.axes[0].set_ylabel('frequency')
plt.show()

enter image description here

问题

这两个频谱图明显不同,特别是Librosa版本在一开始就受到了攻击。 是什么导致差异?我在Scipy和Librosa的文档中看不到许多可以调整的参数。

1 个答案:

答案 0 :(得分:1)

这样做的原因是librosa的stft的参数center。默认情况下,它是True(以及pad_mode = 'reflect')。

从文档中

  

librosa.core.stft(y,n_fft = 2048,hop_length = None,win_length = None,window ='hann',center = True,dtype =,pad_mode ='reflect') < / p>      

中心:布尔值

     

如果为True,则填充信号y,以使帧D [:, t]以y [t * hop_length]为中心。

     

如果为False,则D [:, t]从y [t * hop_length]开始

     

pad_mode:string

     

如果center = True,则为在信号边缘使用的填充模式。默认情况下,STFT使用反射填充。

像这样呼叫STFT

X_libs = stft(X, n_fft=window_size, hop_length=stride,
              center=False)

导致一条直线:

librosa.stft with center = False

请注意,默认情况下,librosa的stft也使用Hann window function。如果要避免这种情况,并使它更像Scipy stft实现,请使用仅包含一个的窗口来调用stft:

X_libs = stft(X, n_fft=window_size, hop_length=stride,
              window=np.ones(window_size),
              center=False)

librosa.stft with center = False and no window function

您会注意到这条线更细。