【语音识别】之梅尔频率倒谱系数(mfcc)及Python实现

  • 一、mel滤波器
  • 二、mfcc特征
  • Python实现

语音识别系统的第一步是进行特征提取,mfcc是描述短时功率谱包络的一种特征,在语音识别系统中被广泛应用。

一、mel滤波器

每一段语音信号被分为多帧,每帧信号都对应一个频谱(通过FFT变换实现),频谱表示频率与信号能量之间的关系。mel滤波器是指多个带通滤波器,在mel频率中带通滤波器的通带是等宽的,但在赫兹(Hertz)频谱内mel滤波器在低频处较密集切通带较窄,高频处较稀疏且通带较宽,旨在通过在较低频率处更具辨别性并且在较高频率处较少辨别性来模拟非线性人类耳朵对声音的感知。
赫兹频率和梅尔频率之间的关系为:
Fmel=1125ln⁡(1+f/700){F_{mel}} = 1125\ln (1 + f/700)Fmel​=1125ln(1+f/700)

f=700(eF/1125−1)f = 700\left( {{e^{F/1125}} - 1} \right)f=700(eF/1125−1)
假设在梅尔频谱内,有MMM个带通滤波器Hm(k),0≤m&lt;M{H_m}\left( k \right),0 \le m &lt; MHm​(k),0≤m<M,每个带通滤波器的中心频率为F(m)F(m)F(m)每个带通滤波器的传递函数为:
Hm(k)={0,k&lt;F(m−1)k−F(m−1)F(m)−F(m−1),F(m−1)≤k≤F(m)F(m+1)−kF(m+1)−F(m),F(m)≤k≤F(m+1)0,k&gt;F(m+1){H_m}\left( k \right) = \left\{ {\begin{matrix} {0,k &lt; F\left( {m - 1} \right)}\\ {\frac{{k - F\left( {m - 1} \right)}}{{F(m) - F(m - 1)}},F(m - 1) \le k \le F(m)}\\ {\frac{{F\left( {m + 1} \right) - k}}{{F(m + 1) - F(m)}},F(m) \le k \le F(m + 1)}\\ {0,k &gt; F(m + 1)} \end{matrix}} \right.Hm​(k)=⎩⎪⎪⎪⎨⎪⎪⎪⎧​0,k<F(m−1)F(m)−F(m−1)k−F(m−1)​,F(m−1)≤k≤F(m)F(m+1)−F(m)F(m+1)−k​,F(m)≤k≤F(m+1)0,k>F(m+1)​
下图为赫兹频率内的mel滤波器,带通滤波器个数为24:

二、mfcc特征

MFCC系数提取步骤:
(1)语音信号分帧处理
(2)每一帧傅里叶变换---->功率谱
(3)将短时功率谱通过mel滤波器
(4)滤波器组系数取对数
(5)将滤波器组系数的对数进行离散余弦变换(DCT)
(6)一般将第2到底13个倒谱系数保留作为短时语音信号的特征

Python实现

import wave
import numpy as np
import math
import matplotlib.pyplot as plt
from scipy.fftpack import dctdef read(data_path):'''读取语音信号'''wavepath = data_pathf = wave.open(wavepath,'rb')params = f.getparams()nchannels,sampwidth,framerate,nframes = params[:4] #声道数、量化位数、采样频率、采样点数str_data = f.readframes(nframes) #读取音频,字符串格式f.close()wavedata = np.fromstring(str_data,dtype = np.short) #将字符串转化为浮点型数据wavedata = wavedata * 1.0 / (max(abs(wavedata))) #wave幅值归一化return wavedata,nframes,frameratedef enframe(data,win,inc):'''对语音数据进行分帧处理input:data(一维array):语音信号wlen(int):滑动窗长inc(int):窗口每次移动的长度output:f(二维array)每次滑动窗内的数据组成的二维array'''nx = len(data) #语音信号的长度try:nwin = len(win)except Exception as err:nwin = 1    if nwin == 1:wlen = winelse:wlen = nwinnf = int(np.fix((nx - wlen) / inc) + 1) #窗口移动的次数f = np.zeros((nf,wlen))  #初始化二维数组indf = [inc * j for j in range(nf)]indf = (np.mat(indf)).Tinds = np.mat(range(wlen))indf_tile = np.tile(indf,wlen)inds_tile = np.tile(inds,(nf,1))mix_tile = indf_tile + inds_tilef = np.zeros((nf,wlen))for i in range(nf):for j in range(wlen):f[i,j] = data[mix_tile[i,j]]return fdef point_check(wavedata,win,inc):'''语音信号端点检测input:wavedata(一维array):原始语音信号output:StartPoint(int):起始端点EndPoint(int):终止端点'''#1.计算短时过零率FrameTemp1 = enframe(wavedata[0:-1],win,inc)FrameTemp2 = enframe(wavedata[1:],win,inc)signs = np.sign(np.multiply(FrameTemp1,FrameTemp2)) # 计算每一位与其相邻的数据是否异号,异号则过零signs = list(map(lambda x:[[i,0] [i>0] for i in x],signs))signs = list(map(lambda x:[[i,1] [i<0] for i in x], signs))diffs = np.sign(abs(FrameTemp1 - FrameTemp2)-0.01)diffs = list(map(lambda x:[[i,0] [i<0] for i in x], diffs))zcr = list((np.multiply(signs, diffs)).sum(axis = 1))#2.计算短时能量amp = list((abs(enframe(wavedata,win,inc))).sum(axis = 1))
#    # 设置门限
#    print('设置门限')ZcrLow = max([round(np.mean(zcr)*0.1),3])#过零率低门限ZcrHigh = max([round(max(zcr)*0.1),5])#过零率高门限AmpLow = min([min(amp)*10,np.mean(amp)*0.2,max(amp)*0.1])#能量低门限AmpHigh = max([min(amp)*10,np.mean(amp)*0.2,max(amp)*0.1])#能量高门限# 端点检测MaxSilence = 8 #最长语音间隙时间MinAudio = 16 #最短语音时间Status = 0 #状态0:静音段,1:过渡段,2:语音段,3:结束段HoldTime = 0 #语音持续时间SilenceTime = 0 #语音间隙时间print('开始端点检测')StartPoint = 0for n in range(len(zcr)):if Status ==0 or Status == 1:if amp[n] > AmpHigh or zcr[n] > ZcrHigh:StartPoint = n - HoldTimeStatus = 2HoldTime = HoldTime + 1SilenceTime = 0elif amp[n] > AmpLow or zcr[n] > ZcrLow:Status = 1HoldTime = HoldTime + 1else:Status = 0HoldTime = 0elif Status == 2:if amp[n] > AmpLow or zcr[n] > ZcrLow:HoldTime = HoldTime + 1else:SilenceTime = SilenceTime + 1if SilenceTime < MaxSilence:HoldTime = HoldTime + 1elif (HoldTime - SilenceTime) < MinAudio:Status = 0HoldTime = 0SilenceTime = 0else:Status = 3elif Status == 3:breakif Status == 3:breakHoldTime = HoldTime - SilenceTimeEndPoint = StartPoint + HoldTimereturn FrameTemp1[StartPoint:EndPoint]def mfcc(FrameK,framerate,win):'''提取mfcc参数 input:FrameK(二维array):二维分帧语音信号framerate:语音采样频率win:分帧窗长(FFT点数)output:'''#mel滤波器mel_bank,w2 = mel_filter(24,win,framerate,0,0.5)FrameK = FrameK.T#计算功率谱S = abs(np.fft.fft(FrameK,axis = 0)) ** 2#将功率谱通过滤波器P = np.dot(mel_bank,S[0:w2,:])#取对数logP = np.log(P)#计算DCT系数
#    rDCT = 12
#    cDCT = 24
#    dctcoef = []
#    for i in range(1,rDCT+1):
#        tmp = [np.cos((2*j+1)*i*math.pi*1.0/(2.0*cDCT)) for j in range(cDCT)]
#        dctcoef.append(tmp)
#    #取对数后做余弦变换
#    D = np.dot(dctcoef,logP)num_ceps = 12D = dct(logP,type = 2,axis = 0,norm = 'ortho')[1:(num_ceps+1),:]return S,mel_bank,P,logP,Ddef mel_filter(M,N,fs,l,h):'''mel滤波器input:M(int):滤波器个数N(int):FFT点数fs(int):采样频率l(float):低频系数h(float):高频系数output:melbank(二维array):mel滤波器'''fl = fs * l #滤波器范围的最低频率fh = fs * h #滤波器范围的最高频率bl = 1125 * np.log(1 + fl / 700) #将频率转换为mel频率bh = 1125 * np.log(1 + fh /700) B = bh - bl #频带宽度y = np.linspace(0,B,M+2) #将mel刻度等间距print('mel间隔',y)Fb = 700 * (np.exp(y / 1125) - 1) #将mel变为HZprint(Fb)w2 = int(N / 2 + 1)df = fs / Nfreq = [] #采样频率值for n in range(0,w2):freqs = int(n * df)freq.append(freqs)melbank = np.zeros((M,w2))print(freq)for k in range(1,M+1):f1 = Fb[k - 1]f2 = Fb[k + 1]f0 = Fb[k]n1 = np.floor(f1/df)n2 = np.floor(f2/df)n0 = np.floor(f0/df)for i in range(1,w2):if i >= n1 and i <= n0:melbank[k-1,i] = (i-n1)/(n0-n1)if i >= n0 and i <= n2:melbank[k-1,i] = (n2-i)/(n2-n0)plt.plot(freq,melbank[k-1,:])plt.show()return melbank,w2if __name__ == '__main__':data_path = 'audio_data.wav'win = 256inc = 80wavedata,nframes,framerate = read(data_path)FrameK = point_check(wavedata,win,inc)S,mel_bank,P,logP,D = mfcc(FrameK,framerate,win)

【语音识别】之梅尔频率倒谱系数(mfcc)及Python实现相关推荐

  1. 声音处理之-梅尔频率倒谱系数(MFCC)

    声音处理之-梅尔频率倒谱系数(MFCC) 梅尔(Mel)频率分析 在语音识别(SpeechRecognition)和话者识别(SpeakerRecognition)方面,最常用到的语音特征就是梅尔倒谱 ...

  2. 梅尔频率倒谱系数MFCC总结

    一.听觉特性. 人们不能完全搞清楚人耳的内部构造,这就不能利用状态空间的方法来分析人耳的听觉特性.但是,可以把人耳当成黑匣子,声音作为激励,人类的反应作为响应,利用信号与系统的经典分析方法,把声音作用 ...

  3. 语音信号的梅尔频率倒谱系数(MFCC)的原理讲解及python实现

    梅尔倒谱系数(MFCC) 梅尔倒谱系数(Mel-scale FrequencyCepstral Coefficients,简称MFCC).依据人的听觉实验结果来分析语音的频谱, MFCC分析依据的听觉 ...

  4. MFCC梅尔频率倒谱系数

    MFCC梅尔频率倒谱系数原理及python实现 文章目录 MFCC梅尔频率倒谱系数原理及python实现 MFCC梅尔频率倒谱系数的原理 计算MFCC的步骤 1.音频信号文件读取及预加重 2.信号分帧 ...

  5. 语音信号处理之(四)梅尔频率倒谱系数(MFCC)

    在任意一个Automatic speech recognition 系统中,第一步就是提取特征.换句话说,我们需要把音频信号中具有辨识性的成分提取出来,然后把其他的乱七八糟的信息扔掉,例如背景噪声啊, ...

  6. Mel频率倒谱系数-MFCC

    MFCC:Mel频率倒谱系数的缩写. 目的:模拟人耳对不同频率语音的感知 Mel频率和Hz频率的关系 人类对不同频率语音有不同的感知能力: 1kHz以下,与频率成线性关系. 1kHz以上,与频率成对数 ...

  7. 深入理解MFCC(梅尔频率倒谱系数)

    从倒谱图出发 MFCC是Mel Frequency Cepstral Coefficient的简称,要理解MFCC特征,就需要先明白这里引入的一个新的概念--Cepstral,这个形容词的名词形式为C ...

  8. 梅尔频率倒谱系数(MFCC)资源

    总结一些关于MFCC写的比较好的资源: 1.MFCC提取过程讲解的非常详细,形象(图表多): http://blog.csdn.net/zouxy09/article/details/9156785 ...

  9. 音频特征-梅尔频率倒谱系数(MFCC)详解

    总结一些关于MFCC写的比较好的资源: 1. MFCC提取过程讲解的非常详细,形象(图表多): http://blog.csdn.net/zouxy09/article/details/9156785 ...

最新文章

  1. iterm2 ssh 乱码_【已解决】Mac中iTerm2通过SSH连接远程服务器
  2. 编辑器Sublime Text 2
  3. 校长回应8名考生放弃清华北大:不喜欢学医才去其他
  4. python和c#交互_python与C#的互相调用
  5. bootstrap 复选框及单选按钮
  6. java.lang.ClassNotFoundException: net.sf.json.JSONObject
  7. cad手机看图 android,CAD手机看图
  8. oracle导出建表语句sql语句,关于导出oracle多个表的建表语句DLL,生成.sql语句。...
  9. c语言实验编码sdut,C语言实验一(1)
  10. html 文件怎么改类型,怎么更改文件类型
  11. Latex 温度单位命令
  12. 让你5分钟明白美国金融危机爆发的原因!
  13. Error in acquiring locks: Locks on the underlying objects cannot be acquired. retry after some time
  14. awl多线程SYN***
  15. shiro权限控制登陆成功页面跳转问题
  16. 如何读到一个文件的最后更新日期和时间
  17. powershell导入脚本失败,禁止运行脚本,无法远程连接服务器
  18. TC264 DMA相关部分代码
  19. Not live in vain——Leo关于生与死的感悟
  20. shell基础正则表达式

热门文章

  1. 释放vmware磁盘空间
  2. MLT-type渲染算法review
  3. 《深度学习》 --李宏毅学习导图总结
  4. 物联网卡不能使用的情况有哪些
  5. MySQL存储过程-循环遍历查询到的结果集
  6. python报表自动化系列 - 计算某年某个月的天数
  7. 抖音昵称html,抖音名字600个
  8. mysql 直方图_MySQL直方图
  9. AcWing 890. 能被整除的数(容斥原理)
  10. linux of命令,Linux命令(30):isof