[英]Librosa's fft and Scipy's fft are different?
Librosa和Scipy都具有fft
功能,但是,即使在相同的信號輸入下,它們也為我提供了不同的頻譜圖輸出。
我正在嘗試使用以下代碼獲取頻譜圖
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()
現在,我嘗試使用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()
兩種頻譜圖明顯不同,特別是Librosa版本在一開始就受到了攻擊。 是什么導致差異? 我在Scipy和Librosa的文檔中看不到許多可以調整的參數。
原因是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')
中心:布爾
如果為True,則填充信號y,以使幀D [:, t]以y [t * hop_length]為中心。
如果為False,則D [:, t]從y [t * hop_length]開始
pad_mode:字符串
如果center = True,則為在信號邊緣使用的填充模式。 默認情況下,STFT使用反射填充。
像這樣調用STFT
X_libs = stft(X, n_fft=window_size, hop_length=stride,
center=False)
確實導致一條直線:
請注意,默認情況下,librosa的stft也使用Hann窗口函數 。 如果要避免這種情況,並使它更類似於Scipy stft實現,請使用僅包含一個的窗口來調用stft:
X_libs = stft(X, n_fft=window_size, hop_length=stride,
window=np.ones(window_size),
center=False)
您會注意到該行較細。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.