能否直接将spectrogram转换为MFCC?求对应的Python实现脚本
语谱图(Spectrogram)转MFCC实现方案
首先确认:存在直接转换的可行方案,前提是你手头的语谱图为线性幅度谱(即STFT计算后取模得到的原始结果,未经过对数压缩),如果是对数压缩后的语谱图也可以调整步骤适配。
转换核心逻辑
- 对输入的线性幅度谱做梅尔滤波组加权,得到梅尔频谱
- 对梅尔频谱做对数变换,得到对数梅尔频谱
- 对对数梅尔频谱做离散余弦变换(DCT),取前N个系数即为MFCC
- 可按需添加MFCC均值归一化、差分计算等后处理步骤
Python实现代码
依赖库:librosa、numpy,可通过pip install librosa numpy安装
import numpy as np import librosa def spec_to_mfcc(spectrogram, sr, n_mfcc=13, n_fft=2048, hop_length=512, fmin=0, fmax=None): """ 线性幅度谱转MFCC 参数说明: spectrogram: 输入线性幅度谱,形状为 (n_fft//2 + 1, 时间帧数) sr: 原始音频采样率 n_mfcc: 输出MFCC的系数数量,常规取13/20 n_fft: 生成输入语谱图时使用的FFT点数,需和生成时的参数一致 hop_length: 生成输入语谱图时使用的帧移长度,需和生成时的参数一致 fmin: 梅尔滤波组最低频率,默认0 fmax: 梅尔滤波组最高频率,默认取采样率的1/2 返回值: mfcc: 输出MFCC特征,形状为 (n_mfcc, 时间帧数) """ # 构建梅尔滤波矩阵 mel_basis = librosa.filters.mel(sr=sr, n_fft=n_fft, fmin=fmin, fmax=fmax) # 计算梅尔频谱 mel_spectrogram = np.dot(mel_basis, spectrogram) # 转换为对数刻度 log_mel_spectrogram = librosa.power_to_db(mel_spectrogram, ref=np.max) # DCT变换得到MFCC mfcc = librosa.feature.mfcc(S=log_mel_spectrogram, n_mfcc=n_mfcc) return mfcc # 示例调用 if __name__ == "__main__": # 模拟生成语谱图,实际使用时替换为你自己的语谱图即可 y, sr = librosa.load(librosa.ex('trumpet'), sr=16000) stft_output = librosa.stft(y, n_fft=2048, hop_length=512) input_spec = np.abs(stft_output) # 线性幅度谱即为转换输入 # 转换为MFCC output_mfcc = spec_to_mfcc(input_spec, sr=sr, n_mfcc=13, n_fft=2048, hop_length=512) print(f"输入语谱图形状:{input_spec.shape}") print(f"输出MFCC形状:{output_mfcc.shape}")
注意事项
如果你手头的语谱图已经经过对数压缩,需要先逆变换回线性谱再走上述流程,否则得到的MFCC会有偏差;如果输入是功率谱(幅度谱的平方),只需调整
librosa.power_to_db的参数适配即可。
内容的提问来源于stack exchange,提问作者Priyazeet257
相关产品推荐
相关产品推荐

