语音特征提取实战:梅尔频谱(MFCC)在语音识别中的原理与实现
时间:2026-05-20 来源:华清远见
当你的手机听懂“嘿 Siri”,或是智能音箱准确回应你的点歌请求时,背后是一套复杂的语音识别系统在运作。而让机器“听懂”人话的第一步,也是最关键的一步,就是将声音这种连续的波形信号,转换成一串机器能够理解和处理的数字特征。在众多特征中,梅尔频率倒谱系数 历经数十年考验,依然是语音识别领域最经典、最常用的“通用语”。

图:MFCC特征提取完整流程图,展示了从原始语音到最终特征的每一步关键转换
为什么我们需要 MFCC?
原始音频波形是一个高维、冗余且包含大量噪声的信号。直接将其输入模型,计算量巨大且效果不佳。想象一下,你要向一个从未听过声音的外星人描述“你好”这个词。你是会直接播放一段复杂的声波,还是提炼出几个关键特征,比如音调的高低变化、能量的集中区域?MFCC 做的就是后者。
它的核心价值在于:
•降维:将数千个采样点的波形压缩为几十个关键系数。
•去相关:提取的特征之间相互独立性高,有利于模型学习。
•仿生:其设计模拟了人耳对声音的感知特性,对频率的敏感度更接近人类。
MFCC 提取全流程拆解
MFCC 的提取过程可以看作一条精密的流水线,每一步都至关重要。下面我们结合 Python 代码(使用 librosa 库)来逐步拆解。
1. 预加重
声音信号,尤其是元音,在高频部分的能量通常较弱。预加重是一个高通滤波器,其目的是提升高频分量,使信号的频谱变得更加平坦,便于后续处理。
import librosa
import numpy as np
# 读取音频文件
y, sr = librosa.load('speech.wav', sr=None)
# 预加重,系数通常取 0.97
pre_emphasis = 0.97
emphasized_signal = np.append(y[0], y[1:] - pre_emphasis * y[:-1])
简单来说,这一步就像在音频编辑软件里拉高了"高音"滑块,让声音更清晰。
2. 分帧
语音信号是短时平稳的,即在短时间内(如 20-40 毫秒),其特性基本不变。因此,我们需要将连续的信号切分成一帧一帧的小段来处理。
frame_size = 0.025 # 25 毫秒
frame_stride = 0.01 # 10 毫秒重叠
frame_length, frame_step = frame_size * sr, frame_stride * sr
signal_length = len(emphasized_signal)
frame_length = int(round(frame_length))
frame_step = int(round(frame_step))
num_frames = int(np.ceil(float(np.abs(signal_length - frame_length)) / frame_step))
# 填充信号以确保最后一帧有足够长度
pad_signal_length = num_frames * frame_step + frame_length
z = np.zeros((pad_signal_length - signal_length))
pad_signal = np.append(emphasized_signal, z)
indices = np.tile(np.arange(0, frame_length), (num_frames, 1)) + np.tile(np.arange(0, num_frames * frame_step, frame_step), (frame_length, 1)).T
frames = pad_signal[indices.astype(np.int32, copy=False)]
3. 加窗
由于分帧是直接截断,会在帧的两端引入不连续性,导致频谱分析时产生"频谱泄漏"。加窗就是给每一帧乘上一个窗函数(如汉明窗),使帧两端平滑地衰减到零。
frames *= np.hamming(frame_length)
# 通常使用汉明窗 (Hamming Window)
这好比透过一个柔光镜去看一束强光,边缘变得柔和,让我们能更清晰地看到光的核心特征。
4. 快速傅里叶变换与功率谱
这一步将每一帧信号从时域变换到频域,得到频谱。然后计算功率谱,它代表了信号在不同频率成分上的能量分布。
# 计算 FFT 点数,通常为 256 或 512
NFFT = 512
mag_frames = np.absolute(np.fft.rfft(frames, NFFT))
pow_frames = ((1.0 / NFFT) * (mag_frames ** 2))
5. 梅尔滤波器组
这是 MFCC 的"灵魂"所在。人耳对频率的感知并非线性,在 1000Hz 以下大致呈线性,在 1000Hz 以上则呈对数关系。梅尔尺度就是一种模拟人耳感知的心理声学尺度。
梅尔滤波器组是一组三角形的滤波器,通常有 40 个,它们在梅尔尺度上均匀分布,但在线性频率尺度上则低频部分密集、高频部分稀疏。
# 使用 librosa 创建梅尔滤波器组
nfilt = 40 # 滤波器数量
mel_fbanks = librosa.filters.mel(sr=sr, n_fft=NFFT, n_mels=nfilt)
# 将功率谱通过滤波器组
filter_banks = np.dot(pow_frames, mel_fbanks.T)
filter_banks = np.where(filter_banks == 0, np.finfo(float).eps, filter_banks) # 避免 log(0)
filter_banks = 20 * np.log10(filter_banks) # 转换为 dB 单位
这个过程相当于用一套符合人耳听觉的"筛子"去过滤频谱,只留下我们关心的频带能量。
6. 离散余弦变换
经过梅尔滤波器组得到的谱图,其各个频带之间还存在相关性。离散余弦变换 可以将其压缩和去相关,得到倒谱域的特征。我们保留变换后的前 12-13 个系数,因为它们包含了频谱的包络信息(与声道形状相关),而更高的系数代表细节(与激励源相关),通常被丢弃。
# 取前 13 个系数
num_ceps = 13
mfcc = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=num_ceps, n_fft=NFFT, hop_length=frame_step)
# 或者手动从 filter_banks 计算
mfcc = scipy.fftpack.dct(filter_banks, type=2, axis=1, norm='ortho')[:, 1 : (num_ceps + 1)]
通常,我们还会加上一阶和二阶差分(又称 Delta 和 Delta-Delta)系数,以捕捉特征的动态变化(如音量的变化速度),这对于识别语音的动态特性至关重要。
# 计算一阶差分 (Delta)
delta_mfcc = librosa.feature.delta(mfcc)
# 计算二阶差分 (Delta-Delta)
delta2_mfcc = librosa.feature.delta(mfcc, order=2)
最终,对于每一帧,我们得到 39 维的特征向量(13个基本系数 + 13个一阶差分 + 13个二阶差分)。
实战:使用 Librosa 一键提取
在实际应用中,我们无需手动实现上述所有步骤。像 librosa 这样的库提供了高度优化的函数。
import librosa
# 加载音频
y, sr = librosa.load('your_audio.wav', sr=16000) # 重采样至 16kHz
# 一键提取 MFCC 特征 (包含预加重、分帧、加窗、FFT、梅尔滤波、DCT等所有步骤)
# 返回形状为 (n_mfcc, t) 的特征矩阵
mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13, hop_length=256, n_fft=512)
# 同时计算差分特征
mfcc_delta = librosa.feature.delta(mfccs)
mfcc_delta2 = librosa.feature.delta(mfccs, order=2)
# 组合成完整的 39 维特征
mfcc_feature = np.vstack([mfccs, mfcc_delta, mfcc_delta2])
print("MFCC 特征矩阵形状:", mfcc_feature.shape) # 例如 (39, 时间帧数)
MFCC 的局限与新发展
尽管 MFCC 非常强大,但它并非完美:
•信息丢失:丢弃相位信息,且对噪声比较敏感。
•静态特征:虽然后续加了差分,但本质上仍是手工设计的静态特征。
随着深度学习的发展,尤其是端到端模型的出现,梅尔频谱图 本身(即进行到第 5 步的结果,不进行 DCT)成为了更受欢迎的特征。它将原始音频转换为图像般的二维表示,直接输入卷积神经网络进行训练,让模型自动学习最有效的特征表示。
# 提取梅尔频谱图,作为深度学习模型的输入
mel_spectrogram = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128, fmax=8000)
log_mel_spectrogram = librosa.power_to_db(mel_spectrogram, ref=np.max)
总结与行动建议
MFCC 通过模仿人耳听觉机理,将语音信号压缩为一组稳定、有区分度的低维特征。其核心流程包括预加重、分帧、加窗、FFT、梅尔滤波和 DCT,每一步都旨在让机器能像人一样"抓住"语音的关键。
行动建议
1.入门实践:使用 librosa 库对一段你自己的录音提取 MFCC 特征,并可视化它,直观感受不同元音(如/a/、/i/)的 MFCC 图案差异。
2.项目升级:如果你正在
C语言内存管理避坑指南mallocfree与嵌入式堆栈(HeapSt
I2C 设备组网常见问题排查:从硬件到寄存器的全流程
Python迭代器与生成器深度解析
FreeRTOS 队列(Queue)使用与排错指南
时序预测技术对比: DNN/RNN/LSTM 在风电 功率预测中
STM32位域(bit-field)在寄存器映射中的高效应用与跨平
从Encoder-Decoder到GPT大模型的底层实现
DMA 传输配置指南:从串口、ADC 到 SPI 的高速数据吞
注意力机制深度拆解:从 Soft-Attention 到 Self-Atte
深入剖析:FreeRTOS信号量在设备通信中的工程细节
