MFCC简介:
Mel频率是基于人耳听觉特性提出来的,它与Hz频率成非线性对应关系 。Mel频率倒谱系数(MFCC)则是利用它们之间的这种关系,计算得到的Hz频谱特征,MFCC已经广泛地应用在声纹识别和语音识别领域。由于Mel频率与Hz频率之间非线性的对应关系,使得MFCC随着频率的提高,其计算精度随之下降。因此,在应用中常常只使用低频MFCC,而丢弃中高频MFCC,MFCC的提取主要包括以下几个步骤:
1.预滤波:前端带宽为300-3400Hz的抗混叠滤波器。
2.A/D变换:8kHz的采样频率,12bit的线性量化精度。
3.预加重:通过一个一阶有限激励响应高通滤波器,使信号的频谱变得平坦,不易受到有限字长效应的影响。
4.分帧:为了方便对语音分析,可以将语音分成一个个小段,称之为:帧。先将N个采样点集合成一个观测单位,称为帧。通常情况下N的值为256或512,涵盖的时间约为20~30ms左右。为了避免相邻两帧的变化过大,因此会让两相邻帧之间有一段重叠区域,此重叠区域包含了M个取样点,通常M的值约为N的1/2或1/3。通常语音识别所采用语音信号的采样频率为8KHz或16KHz,以8KHz来说,若帧长度为256个采样点,则对应的时间长度是256/8000×1000=32ms。
5.加窗:采用哈明窗对一帧语音加窗,以减小吉布斯效应的影响。语音在长范围内是不停变动的,没有固定的特性无法做处理,所以将每一帧代入窗函数,窗外的值设定为0,其目的是消除各个帧两端可能会造成的信号不连续性。常用的窗函数有方窗、汉明窗和汉宁窗等,根据窗函数的频域特性,常采用汉明窗。将每一帧乘以汉明窗,以增加帧左端和右端的连续性
6.快速傅立叶变换(Fast Fourier Transformation, FFT): 由于信号在时域上的变换通常很难看出信号的特性,所以通常将它转换为频域上的能量分布来观察,不同的能量分布,就能代表不同语音的特性。所以在乘上汉明窗后,每帧还必须再经过快速傅里叶变换以得到在频谱上的能量分布。对分帧加窗后的各帧信号进行快速傅里叶变换得到各帧的频谱。并对语音信号的频谱取模平方得到语音信号的功率谱。
7.三角窗滤波: 用一组Mel频标上线性分布的三角窗滤波器(共24个三角窗滤波器),对信号的功率谱滤波,每一个三角窗滤波器覆盖的范围都近似于人耳的一个临界带宽,以此来模拟人耳的掩蔽效应。
8.求对数:三角窗滤波器组的输出求取对数,可以得到近似于同态变换的结果。
9.离散余弦变换(Discrete Cosine Transformation, DCT): 去除各维信号之间的相关性,将信号映射到低维空间。
10.谱加权:由于倒谱的低阶参数易受说话人特性、信道特性等的影响,而高阶参数的分辨能力比较低,所以需要进行谱加权,抑制其低阶和高阶参数。 倒谱均值减(Cepstrum Mean Subtraction, CMS):CMS可以有效地减小语音输入信道对特征参数的影响。
11.差分参数: 实验表明,在语音特征中加入表征语音动态特性的差分参数,能够提高系统的识别性能。
12.短时能量:语音的短时能量也是重要的特征参数,短时归一化对数能量及其一阶差分、二阶差分参数
Python代码说明
该示例代码调用的是 python_speech_features 包提取MFCC,MFCC基本维数是13维,将其与一阶差分、二阶差分组合,返回的是39维特征的MFCC。
python代码如下:
from python_speech_features import *
import numpy as np
import scipy.io.wavfile
from matplotlib import pyplot as plt
class WavtoMfcc(object):
def __init__(self, ul, num_wav, numc=13):
self.numc = numc
self.ul = ul
self.num_wav = num_wav
def get_mfcc(self, data, fs):
wav_feature = mfcc(data, fs, numcep=self.numc, winlen=0.025, winstep=0.01,
nfilt=26, nfft=512, lowfreq=0, highfreq=None, preemph=0.97)
'''
signal - 需要用来计算特征的音频信号,应该是一个N*1的数组
samplerate - 我们用来工作的信号的采样率
winlen - 分析窗口的长度,按秒计,默认0.025s(25ms)
winstep - 连续窗口之间的步长,按秒计,默认0.01s(10ms)
numcep - 倒频谱返回的数量,默认13
nfilt - 滤波器组的滤波器数量,默认26
nfft - FFT的大小,默认512
lowfreq - 梅尔滤波器的最低边缘,单位赫兹,默认为0
highfreq - 梅尔滤波器的最高边缘,单位赫兹,默认为采样率/2
preemph - 应用预加重过滤器和预加重过滤器的系数,0表示没有过滤器,默认0.97
ceplifter - 将升降器应用于最终的倒谱系数。 0没有升降机。默认值为22。
appendEnergy - 如果是true,则将第0个倒谱系数替换为总帧能量的对数。
'''
d_mfcc_feat = delta(wav_feature, 1)
d_mfcc_feat2 = delta(wav_feature, 2)
feature = np.hstack((wav_feature, d_mfcc_feat, d_mfcc_feat2))
return feature
def readwav(self):
total_mfcc = []
total_num, numk = [], []
m1 = 0
for i in range(1, 31):
sample_rate, signal = scipy.io.wavfile.read(self.ul + str(i) + '.wav')
mfcck = self.get_mfcc(signal, sample_rate)
m, n = mfcck.shape
total_mfcc.extend(mfcck)
m1 = m1 + m
numk.append(m)
total_num.append(m1)
total_mfcc = np.array(total_mfcc)
plt.figure()
plt.plot(signal)
plt.show()
return total_mfcc, total_num
if __name__ == '__main__':
ul = 'D:/PyWork/train_data/'
k = 30 # 读取音频数量
mfccdim = 13 # mfcc基本维数
getmfcc = WavtoMfcc(ul, k, mfccdim)
mfcc, numk = getmfcc.readwav()
print(mfcc.shape)
信号可视化