python - Librosa 的 fft 和 Scipy 的 fft 不一样?
问题描述
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 的文档中,我没有看到很多可以调整的参数。
解决方案
The reason for this is the argument center
for librosa's stft. By default it's True
(along with pad_mode = 'reflect'
).
From the docs:
librosa.core.stft(y, n_fft=2048, hop_length=None, win_length=None, window='hann', center=True, dtype=, pad_mode='reflect')
center:boolean
If True, the signal y is padded so that frame D[:, t] is centered at y[t * hop_length].
If False, then D[:, t] begins at y[t * hop_length]
pad_mode:string
If center=True, the padding mode to use at the edges of the signal. By default, STFT uses reflection padding.
Calling the STFT like this
X_libs = stft(X, n_fft=window_size, hop_length=stride,
center=False)
does lead to a straight line:
Note that librosa's stft also uses the Hann window function by default. If you want to avoid this and make it more like your Scipy stft implementation, call the stft with a window consisting only of ones:
X_libs = stft(X, n_fft=window_size, hop_length=stride,
window=np.ones(window_size),
center=False)
You'll notice that the line is thinner.
推荐阅读
- tensorflow - 使用 cuda 9.1、cudnn 7.1 在 debian 10 上构建
- php - 请求 blob 类型时显示响应错误文本
- php - vichuploadbundle 和 KnpLabs/DoctrineBehaviors(可翻译)[Symfony]
- java - Ant Junit 任务抛出 java.lang.ClassNotFoundException
- php - in_array 从不存在的值返回 True
- keras - Auto-Keras 中的 ImageClassifier 类中的 fit() 函数运行不佳
- r - R XPATH 字符串包含列表中的元素
- android - 无法在单个 dex 文件中容纳请求的类。尝试提供一个 main-dex 列表。# 方法:66029 > 65536
- php - 使用 php 预览 doc、docx、pdf、xlxs 文件
- facebook-graph-api - 使用 API 在 facebook 上发布到我的墙上获得 403