语音识别系统的第一步是进行特征提取,mfcc是描述短时功率谱包络的一种特征,在语音识别系统中被广泛应用。
一、mel滤波器
每一段语音信号被分为多帧,每帧信号都对应一个频谱(通过FFT变换实现),频谱表示频率与信号能量之间的关系。mel滤波器是指多个带通滤波器,在mel频率中带通滤波器的通带是等宽的,但在赫兹(Hertz)频谱内mel滤波器在低频处较密集切通带较窄,高频处较稀疏且通带较宽,旨在通过在较低频率处更具辨别性并且在较高频率处较少辨别性来模拟非线性人类耳朵对声音的感知。
赫兹频率和梅尔频率之间的关系为:
假设在梅尔频谱内,有M 个带通滤波器Hm (k),0≤m
下图为赫兹频率内的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 dct def read(data_path): '''读取语音信号 ''' wavepath = data_path f = 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,framerate def 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 = win else: wlen = nwin nf = int(np.fix((nx - wlen) / inc) + 1) #窗口移动的次数 f = np.zeros((nf,wlen)) #初始化二维数组 indf = [inc * j for j in range(nf)] indf = (np.mat(indf)).T inds = np.mat(range(wlen)) indf_tile = np.tile(indf,wlen) inds_tile = np.tile(inds,(nf,1)) mix_tile = indf_tile + inds_tile f = np.zeros((nf,wlen)) for i in range(nf): for j in range(wlen): f[i,j] = data[mix_tile[i,j]] return f def 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 AmpHigh or zcr[n] > ZcrHigh: StartPoint = n - HoldTime Status = 2 HoldTime = HoldTime + 1 SilenceTime = 0 elif amp[n] > AmpLow or zcr[n] > ZcrLow: Status = 1 HoldTime = HoldTime + 1 else: Status = 0 HoldTime = 0 elif Status == 2: if amp[n] > AmpLow or zcr[n] > ZcrLow: HoldTime = HoldTime + 1 else: SilenceTime = SilenceTime + 1 if SilenceTime = n1 and i = n0 and i
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自学php网。
查看更多关于梅尔频率倒谱系数(mfcc)及Python实现的详细内容...