天天看点

#语音信号处理基础(十一)——梅尔倒谱系数的提取

文章目录

    • 1.Mel频率倒谱系数(Mel-Frequency Cepstral Coefficients)
    • 2.梅尔参数的提取

1.Mel频率倒谱系数(Mel-Frequency Cepstral Coefficients)

我们将频谱通过一组Mel滤波器得到Mel频谱。
   公式表述就是:log X[k] = log (Mel-Spectrum)。这时候我们在log X[k]上进行倒谱分析:
           

1)取对数:log X[k] = log H[k] + log E[k]。

2)进行逆变换:x[k] = h[k] + e[k]。

在Mel频谱上面获得的倒谱系数h[k]就称为Mel频率倒谱系数,简称MFCC。
           
#语音信号处理基础(十一)——梅尔倒谱系数的提取

2.梅尔参数的提取

现在咱们来总结下提取MFCC特征的过程:

1)先对语音进行预加重、分帧和加窗;

2)对每一个短时分析窗,通过FFT得到对应的频谱;

3)将上面的频谱通过Mel滤波器组得到Mel频谱;

4)在Mel频谱上面进行倒谱分析(取对数,做逆变换,实际逆变换一般是通过DCT离散余弦变换来实现,取DCT后的第2个到第13个系数作为MFCC系数),获得Mel频率倒谱系数MFCC,这个MFCC就是这帧语音的特征;

#语音信号处理基础(十一)——梅尔倒谱系数的提取

这时候,语音就可以通过一系列的倒谱向量来描述了,每个向量就是每帧的MFCC特征向量。

#语音信号处理基础(十一)——梅尔倒谱系数的提取

这样就可以通过这些倒谱向量对语音分类器进行训练和识别了。

参考:https://blog.csdn.net/zouxy09/article/details/9156785

1)预加重

预加重的目的是提升高频部分,使信号的频谱变得平坦,保持在低频到高频的整个频带中,能用同样的信噪比求频谱。同时,也是为了消除发生过程中声带和嘴唇的效应,来补偿语音信号受到发音系统所抑制的高频部分,也为了突出高频的共振峰。

实现代码

%MFCC参数提取
clear all; clc; close all;
[x,Fs]=audioread('bluesky3.wav');

%对输入的语音序列x进行MFCC参数的提取,返回MFCC参数和一阶
%差分MFCC参数,Mel滤波器的阶数为24
%fft变换的长度为256,采样频率为8000Hz,对x 256点分为一帧

%Mel滤波
fs = 8000;    %采样频率
fl = 0;       %fl是设计滤波器的最低频率
fh = fs / 2;  %fh是设计滤波器的最高频率
bl = 1125 * log(1 + fl/700);    %最低频率对应的Mel频率
bh = 1125 * log(1 + fh/700);    %最高频率对应的Mel频率
p = 24;       %在fl和fh之间设计Mel滤波器的个数
N = 256;      %FFT点数,N越大,频率分辨率越高,误差越小
MelF = linspace(0, bh-bl, p+2);    %在0至bh-bl的Mel频率范围内产生p+2个Mel频率值
F = 700 * (exp(MelF/1125) - 1);    %将上一步产生的p+2个Mel频率值转化为p+2个实际频率值
df = fs / N;      %计算频率分辨率
n = N/2 + 1;      %计算fs/2内对应的FFT点数
f = (0:n-1) * df; %计算频率序列,共有n个频率点
bank = zeros(24, n);    %生成24行n列的全零矩阵
for m1 = 2:p+1     %循环起始数为2,因为下方语句中用到m-1的值,其中m-1必须为正整数,所以m为大于等于2的正整数
    
    %F为实际频率,分别找到三角滤波器左中右对应的频率
    F_left = F(m1-1);
    F_mid = F(m1); 
    F_right = F(m1+1);
    
    %使用ceil()函数向上取整,计算实际频率对应的FFT点数
    n_left = ceil(F_left / df);   %频率F_left对应的FFT点数
    n_mid = ceil(F_mid / df);     %频率F_mid对应的FFT点数
    n_right = ceil(F_right / df); %频率F_right对应的FFT点数
    
    %用三角窗的频率响应函数作图
    for k = 1:n    %根据FFT点数画三角窗
        if k>=n_left & k<=n_mid
            bank(m1-1,k) = (k-n_left)/(n_mid-n_left);    %画第m-1个滤波器的左半部分
        elseif k>n_mid & k<=n_right
            bank(m1-1,k) = (n_right-k)/(n_right-n_mid);  %画第m-1个滤波器的右半部分
        end
    end
end
% 归一化mel滤波器组系数
bank=full(bank);
bank=bank/max(bank(:));

% DCT系数,12*24
for k=1:12
  n=0:23;
  dctcoef(k,:)=cos((2*n+1)*k*pi/(2*24));
end

% 归一化倒谱提升窗口
%乘以倒谱提升窗口,目的是对MFCC系数中某些谱线增强
w = 1 + 6 * sin(pi * [1:12] ./ 12);
w = w/max(w);

% 预加重滤波器
xx=double(x);
xx=filter([1 -0.9375],1,xx);

% 语音信号分帧
xx=enframe(xx,256,80);

% 计算每帧的MFCC参数
for i=1:size(xx,1)
  y = xx(i,:);
  s = y' .* hamming(256);
  t = abs(fft(s));         %快速傅里叶变换
  t = t.^2;                %计算谱线能量
  c1=dctcoef * log(bank * t(1:129));
  c2 = c1.*w';%乘以倒谱提升窗口,目的是对MFCC系数中某些谱线增强
  m(i,:)=c2';
end

%差分系数
%差量倒频谱参数(Delta cepstrum):虽然已经求出 13 个特征参数,
%然而在实际应用于语音识别时,我们通常会再加上差量倒频谱参数,
%以显示倒频谱参数对时间的变化。它的意义为倒频谱参数相对于时间的斜率,
%也就是代表倒频谱参数在时间上的动态变化,
%公式如下: △Cm(t) = [St=-MMCm(t+t)t] /[St=-MMt2] 这里 M 的值一般是取 2 或 3。
%因此,如果加上差量运算,就会产生 26 维的特征向量;如果再加上差差量运算,就会产生 39 维的特征向量。
%一般我们在 PC 上进行的语音识别,就是使用 39 维的特征向量。
dtm = zeros(size(m));
for i=3:size(m,1)-2
  dtm(i,:) = -2*m(i-2,:) - m(i-1,:) + m(i+1,:) + 2*m(i+2,:);
end
dtm = dtm / 3;

%合并mfcc参数和一阶差分mfcc参数
ccc = [m dtm];
%去除首尾两帧,因为这两帧的一阶差分参数为0
ccc = ccc(3:size(m,1)-2,:);

ccc_1=ccc(:,1);
ccc_2=ccc(:,13);
figure(1)
plot(x);                                      %画出原始语音的信号波形
title('原始波形');
figure(2)
plot(ccc_1);ylabel('幅值');     %画出第1列数据经过差分后的MFCC
hold on;
plot(ccc_2,'m');title('经过差分后的MFCC');ylabel('幅值'); %画出第13列数据经过差分后的MFCC
legend('第1列数据','第2列数据');                %显示图例
figure(3)
plot(m(:,1));								  %画出不经过差分之前得到的第一列数据MFCC
title('不经过差分之前得到的第一列数据MFCC');
           

运行结果

#语音信号处理基础(十一)——梅尔倒谱系数的提取
#语音信号处理基础(十一)——梅尔倒谱系数的提取
#语音信号处理基础(十一)——梅尔倒谱系数的提取

继续阅读