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');
運行結果