首页 > 解决方案 > 使用 librosa 计算光谱质心

问题描述

我发现了以下两种计算光谱质心的方法,但它们不会返回相同的值。

哪个是正确的版本,两者有何不同?

1.

def spectral_centroid(x, samplerate=44100):
    magnitudes = np.abs(np.fft.rfft(x)) # magnitudes of positive frequencies
    length = len(x)
    freqs = np.abs(np.fft.fftfreq(length, 1.0/samplerate)[:length//2+1]) # positive frequencies
    return np.sum(magnitudes*freqs) / np.sum(magnitudes)

2.

cent = librosa.feature.spectral_centroid(y=y, sr=sr)
print(np.mean(cent.T, axis=0))

标签: pythonsignal-processinglibrosa

解决方案


如果您遵循正确的公式,那么两者都应该是正确的。不过我会选择librosa实现,因为我相信它背后的开发团队。显然,如果它在您的用例中提供优势,您也可以使用您的方法。

现在让我们解决为什么结果不同?这是因为您的方法使用了numpy.fft.rfft中实现的离散傅里叶变换 (DFT),而librosa.feature.spectral_centroid方法使用的是短时傅里叶变换 (STFT)。您可以通过查看以下 librosa 链接来验证这一点:spectral-centroid & spectrum

STFT 和 DFT 具有不同的优势,因此由于 STFT 是时间相关的,并且不会丢失时间变化的信息,因此它比 DFT 计算量更大且速度更慢。


推荐阅读