基于模板匹配的0-9数字语音识别(matlab)

 一、通过提取语音的MFCC参数,与提前制作好的语音模板进行DTW匹配,实现0-9数字语音识别,且识别率达到一定要求,可以区分0-9中数字以及鉴别非0-9数字语音
 二、对充足的模板进行聚类,找到聚类中心,可视化聚类结果,通过实验设定阈值,实现聚类方法的0-9数字语音识别。
(1)流程图:
在这里插入图片描述
(2)MFCC参数提取

  1. 语音预处理
    伪代码:
x←读入的语音;
fs←48000;                   %系统自己设置的
x← x变为浮点型/x的最大值    %归一化

端点检测:

帧长←256;
帧移←80;
短时能量高门限←20;       
短时能量低门限←2;    
过零率高门限←10;
过零率低门限←5;     
最长静音长度←8;
最短静音长度←15;  
状态←0静音状态;
语音长度←0;
静音长度←0;
tmp1←分帧(x(1:end-1), 帧长,帧移);
tmp2←分帧(x(2:end) , 帧长,帧移);
signs←(tmp1.*tmp2)<0;
diffs采样率←(tmp1 - tmp2)>0.02;
过零率←sum(signs.*diffs采样率,2);
短时能量←求和 ((绝对值(分帧(x, 帧长,帧移))2);
能量最高限←最小值(能量高门限, 最大值(短时能量)/4);
能量最低限←最小值(能量低门限, 最大值(短时能量)/8);
起始点←0
终止点←0
语音段数←0
所有语音段的起点←[]
所有语音段的终点←[]
for n←1:帧数
switch 状态
case 01%(静音或可能开始)
      if 短时能量(n)>能量最高限 then    
      语音起始点←最大值(n-语音长度-1,1);
      状态←2
静音长度←0
语音长度←语音长度+1;
elseif 短时能量(n) >能量最低限||过零率(n) >过零率最低限    then
      状态←1;
语音长度←语音长度+1;
else                                             
      状态←0;
      语音长度←0;
end	
case 2                     %(语音段)
     if 短时能量(n) > 能量最低限 ||过零率(n) > 过零率最低限   then    
  语音长度←语音长度+1;
     else                                
         静音长度←静音长度+1;
         if 静音长度←max静音长度            then
      语音长度←语音长度+1;
         elseif 语音长度 ← 最短静音长度       then
            静音状态←0;
            静音长度←0;
            语音长度←0;
   else                        
            状态←3;
   end
end
 case 3
语音段个数←语音段个数+1;
语音长度←语音长度-取整数(静音长度/2);
语音终点←语音起始点+语音长度-1;
所有语音段起点(1,语音段个数)←语音起始点*帧移;
所有语音段终点(1,语音段个数)←语音终点*帧移;
   end
end
x←x(所有语音段起点:所有语音段终点)             %端点检测结果

预加重:

加重系数←0.98
for i←2:x的长度
   y←x-x*加重系数
  1. 参数提取
    伪代码:
    24个滤波器设计:
最高语音频率←fs/2; 
耳朵响应频率←2595*log10(1+最高语音频率/700);
三角滤波器的个数←24;
帧长←向下取整(0.03*fs);
i←0:25;
  滤波器中心频率←700*(10.^(耳朵响应频率/2595*i/(三角滤波器的个数+1))-1);
滤波器←设置0矩阵(24,帧长);
 for m←1:24
     for k←1:帧长
         i←最高语音频率*k/帧长;
         if (滤波器中心频率(m)←i)&&(i←滤波器中心频率(m+1))
             滤波器(m,k)(i-滤波器中心频率(m))/(滤波器中心频率(m+1)-滤波器中心频率(m));
         else if (滤波器中心频率(m+1)←i)&&(i←滤波器中心频率(m+2))
             滤波器(m,k)(滤波器中心频率(m+2)-i)/(滤波器中心频率(m+2)-滤波器中心频率(m+1));
         		else
              	滤波器(m,k)0;
         		end
      	   end
      end
 end

MFCC参数求取(包括分帧、加窗):

离散余弦系数←设置零矩阵(12,24);
 for k←1:12
   n←1:24;
   离散余弦系数(k,:)cos((2*n-1)*k*pi/(2*24));
 end
汉明窗←hamming(帧长);
帧移←向下取整(0.25*帧长); 
帧数←向下取整((len-帧长)/帧移+1);
c1←设置零矩阵(帧数,12);          %储存MFCC参数
for i←1:帧数
     分帧后的音频←y(帧移*(i-1)+1:帧移*(i-1)+帧长);     %分帧
     w ← 分帧后的音频.* 汉明窗;
     Fx←绝对值(快速傅里叶变换(w));
     s←取对数(滤波器*Fx.^2);
     c1(i,:)(离散余弦变换系数*s)';  
 end

一阶差分运算:

差分参数←设置零矩阵(size(c1));
for i←3:size(c1,1)-2
   差分参数(i,:)-2*c1(i-2,:)-c1(i-1,:)+c1(i+1,:)+2*c1(i+2,:);
end
差分参数←差分参数/3;
mfcc←[c1 差分参数];         %合并mfcc参数和一阶差分mfcc参数
mfcc←mfcc(3:size(c1,1)-2,:);%去除首尾两帧,因为这两帧的一阶差分参数为0
  • 三角带通滤波器的主要目的:滤波器组对频谱进行平滑化,并消除谐波的作用,突显原先语音的共振峰。(因此一段语音的音调或音高,是不会呈现在 MFCC 参数内,换句话说,以 MFCC 为特征的语音辨识系统,并不会受到输入语音的音调不同而有所影响) 此外,还可以降低运算量。
  • mfcc即为最终提取的MFCC参数,由于提取的MFCC参数中含有24个滤波器滤波后的参数,以及滤波参数的一阶差分系数,因此提取的MFCC参数同时包含了语音的静态和动态信息,提高系统的识别性能。
    (3)模板选择
     本小组通过语音的MFCC参数与所有模板匹配,进行DTW运算取最小值对应模板为识别出的数字,因此模板的选择直接关系到识别的准确率。
     本小组成员录音0-9所有数字,每个数字10个录音,考虑到每个数字的语音长短、语音语调,甚至环境噪音等进行录音,一共100个录音文件生成100个MFCC矩阵作为模板,以供DTW模板匹配。对于0-9每个数字区分的准确率还是比较高的,但3和9识别率不是很高,这和模板与端点检测有关,通过多次试验,得到:
    在这里插入图片描述
    (4)阈值确定
     本次模板中只有0-9的数字,因此对于0-9以外的音频应该加以区分,本小组采用实验试凑法确定阈值。
     通过大量实验验证发现,在环境比较安静,录音比较纯正和正常的情况下,经DTW模板匹配后的距离大致在 ,为留有一定余量,最终确定阈值为 ,可以区分0-9数字和部分英文字母、我、他等的发音和多音节英文、数字的发音。实验中最初确定的是 ,但英文字母a一直会错认为1,如果取 ,则认为’a’是无法识别的非数字,同样,确定阈值后0-9数字识别率也会下降,最终准确率约为83%,准确率下降不多,可以接受。
    在这里插入图片描述
    (5)GUI界面
     GUI界面如下图所示,上面三个坐标显示框分别显示录音音频、端点检测后的音频、以及24个MEL滤波器组。下设功能按键,点开始录音,后出现信息提示框显示‘正在录音’,停止录音中包含端点检测过程,点停止录音后前两个坐标显示录音音频和端点检测后的音频,点识别后回在下方显示栏显示识别出的数字并在第三个坐标中显示24个MEL滤波器组。点击“拨号”前需服务机(接收数据电脑)先运行MATLAB程序,开启接收状态,再点击拨号,把目前所有已识别的数字(识别栏显示的数字)发送到服务机,服务机接收到数据后用电子音依次播报每个数据。
  • 通过全局变量I增加功能:
  • “播放”:播放识别出来的所有录音端点检测之后的结果。
  • “撤销”:撤销本次数字识别结果,坐标和数字显示栏均显示上次识别后的数字。
  • “清除”:清除已识别的所有数字,三个坐标回到原始状态——空白状态。
  • “关闭”:关闭界面,并清除缓存。
  • “保存录音”:保存本次录音,可自定义文件名
  • “打开文件”:打开本电脑里的音频文件,支持m4a、mp3、wav等音频格式,若未打开音频文件则显示对话框“未打开音频文件”,打开文件后相当于停止录音,前两个坐标同时显示原始音频和端点检测后的音频,可以直接识别。
    (拨号:涉及matlab信息发送,这里不提)在这里插入图片描述
    这里放上部分代码,后期会上传整个项目供参考:
    项目已免费开源:https://gitee.com/zhengzsj/automatic-speech-recognition–ars/tree/master
    点个赞和收藏吧~谢谢啦

端点检测:

global J;
J=J+1;
global msg;
global X0;
close(msg);
stop(handles.recObj); % 停止录音
% thehandles=handles;
handles.Sample=getaudiodata(handles.recObj);% 获取录音
guidata(hObject,handles);
X0{J,1}=handles.Sample;
plot(handles.axes1,cell2mat(X0(J,1)));
x=handles.Sample;
 %% ******************端点检测******************
x = double(x);
x = x / max(abs(x));
%常数设置
FrameLen = 256;%帧长为256点
FrameInc = 80;%帧移为80点
amp1 = 20;%初始短时能量高门限
amp2 = 2;%初始短时能量低门限
zcr1 = 10;%初始短时过零率高门限
zcr2 = 5;%初始短时过零率低门限
maxsilence = 8;  % 8*10ms  = 80ms
%语音段中允许的最大静音长度,如果语音段中的静音帧数未超过此值,则认为语音还没结束;如果超过了
%该值,则对语音段长度count进行判断,若count<minlen,则认为前面的语音段为噪音,舍弃,跳到静音
%状态0;若count>minlen,则认为语音段结束;
minlen  = 15;    % 15*10ms = 150ms
%语音段的最短长度,若语音段长度小于此值,则认为其为一段噪音
status  = 0;     %初始状态为静音状态
count   = 0;     %初始语音段长度为0
silence = 0;     %初始静音段长度为0
%计算过零率
x1=x(1:end-1);
x2=x(2:end);
%分帧
tmp1=enframe(x1,FrameLen,FrameInc);
tmp2=enframe(x2,FrameLen,FrameInc);
signs = (tmp1.*tmp2)<0;
diffs = (tmp1 -tmp2)>0.02;
zcr   = sum(signs.*diffs, 2);%一帧一个值
%计算短时能量
%一帧一个值
%amp = sum(abs(enframe(filter([1 -0.9375], 1, x), FrameLen, FrameInc)), 2);
amp = sum(abs(enframe(x, FrameLen, FrameInc)), 2);
%调整能量门限
amp1 = min(amp1, max(amp)/4);
amp2 = min(amp2, max(amp)/8);
%开始端点检测
%For循环,整个信号各帧比较
%根据各帧能量判断帧所处的阶段
x1 = 0;
x2 = 0;
v_num=0;%记录语音段数
v_Begin=[];%记录所有语音段的起点
v_End=[];%记录所有语音段的终点
%length(zcr)即为帧数
for n=1:length(zcr)
   goto = 0;
   switch status
   case {0,1}                   % 0 = 静音, 1 = 可能开始
      if amp(n) > amp1          % 确信进入语音段
         x1 = max(n-count-1,1);
%          '打印每个x1*FrameInc'
%          x1*FrameInc
         status  = 2;
         silence = 0;
         count   = count + 1;
      elseif amp(n) > amp2 | ... % 可能处于语音段
             zcr(n) > zcr2
         status = 1;
         count  = count + 1;
      else                       % 静音状态
         status  = 0;
         count   = 0;
      end
   case 2,                       % 2 = 语音段
      if amp(n) > amp2 | ...     % 保持在语音段
         zcr(n) > zcr2
         count = count + 1;
      else                       % 语音将结束
         silence = silence+1;
         if silence < maxsilence % 静音还不够长,尚未结束
            count  = count + 1;
         elseif count < minlen   % 语音长度太短,认为是噪声
            status  = 0;
            silence = 0;
            count   = 0;
         else                    % 语音结束
            status  = 3;
         end
      end
   case 3,
      %break;
      %记录当前语音段数据
      v_num=v_num+1;   %语音段个数加一
      count = count-silence/2;
      x2 = x1 + count -1;
      v_Begin(1,v_num)=x1*FrameInc; 
      v_End(1,v_num)=x2*FrameInc;
      %不跳出 数据归零继续往下查找下一段语音
      status  = 0;     %初始状态为静音状态
      count   = 0;     %初始语音段长度为0
      silence = 0;     %初始静音段长度为0
   end
end  

if length(v_End)==0
    x2 = x1 + count -1;
    v_Begin(1,1)=x1*FrameInc; 
    v_End(1,1)=x2*FrameInc;
end
lenafter=0;
for len=1:length(v_End)
    tmp=v_End(1,len)-v_Begin(1,len);
    lenafter=lenafter+tmp;
end
lenafter;
afterEndDet=zeros(lenafter,1);%返回去除静音段的语音信号
beginnum=0;
endnum=0; 
    for k=1:length(v_End)
        tmp=x(v_Begin(1,k):v_End(1,k));
        beginnum=endnum+1;
        endnum=beginnum+v_End(1,k)-v_Begin(1,k);
        afterEndDet(beginnum:endnum)=tmp; 
    end
  plot(handles.axes2,tmp);
   global X;
   X{J,1}=tmp;

语音识别

global X;
global J;
x=cell2mat(X(J,1));
fs=48000;
fh=fs/2; % fs=8000Hz,fh=4000Hz    语音信号的频率一般在300-3400Hz,所以一般情况下采样频率设为8000Hz即可。
max_melf=2595*log10(1+fh/700);%耳朵响应频率
M=24;%三角滤波器的个数
N=floor(0.03*fs);%设置帧长
i=0:25;
f=700*(10.^(max_melf/2595*i/(M+1))-1);%将mei频域中的 各滤波器的中心频率 转到实际频率
F=zeros(24,N);
 for m=1:24
     for k=1:N
         i=fh*k/N;
         if (f(m)<=i)&&(i<=f(m+1))
             F(m,k)=(i-f(m))/(f(m+1)-f(m));
         else if (f(m+1)<=i)&&(i<=f(m+2))
                 F(m,k)=(f(m+2)-i)/(f(m+2)-f(m+1));
             else
                 F(m,k)=0;
             end
         end
     end
 end
 axes(handles.axes3); 
 plot((1:N)*fh/N,F);
 %%%%%%%%%%%%%%%DCT系数%%%%%%%%%%%
dctcoef=zeros(12,24);
 for k=1:12
   n=1:24;
   dctcoef(k,:)=cos((2*n-1)*k*pi/(2*24));
 end

 %%%%%%%%%%%对语音信号进行预加重处理%%%%%%%%%%
len=length(x);
 alpha=0.98;
 y=zeros(len,1);
 for i=2:len
     y(i)=x(i)-alpha*x(i-1);
 end
 %%%%%%%%%%%%%%%MFCC特征参数的求取%%%%%%%%%%%%
h=hamming(N);%256*1
 num=floor(0.25*N); %帧移
 count=floor((len-N)/num+1);%帧数
 c1=zeros(count,12);
 for i=1:count
     x_frame=y(num*(i-1)+1:num*(i-1)+N);%256*1
     w = x_frame.* h;%
     Fx=abs(fft(w));%     Fx=abs(fft(x_frame));
     s=log(F*Fx.^2);%取对数
     c1(i,:)=(dctcoef*s)'; %离散余弦变换 
 end
 %%%%%%%%%%%%差分系数%%%%%%%%%%%
dtm = zeros(size(c1));
 for i=3:size(c1,1)-2
   dtm(i,:) = -2*c1(i-2,:) - c1(i-1,:) + c1(i+1,:) + 2*c1(i+2,:);
 end
 dtm = dtm / 3;
 %%%%合并mfcc参数和一阶差分mfcc参数%%%%%
ccc = [c1 dtm];
 %去除首尾两帧,因为这两帧的一阶差分参数为0
ccc = ccc(3:size(c1,1)-2,:);
%  ccc=ccc(:,2:20);
%  save('moban8','ccc');
fileFolder='模板\';
dirOutput=dir(strcat(fileFolder,'*'));
fileNames={dirOutput.name};
len = length(fileNames);
for I=3:len
    K_Trace = strcat(fileFolder, fileNames(I));
    eval(['y','=','load(K_Trace{1,1})',';']);
    Y{I-2,1}=cat(1,y.ccc);%按行读取
    D(I-2,1)=dtw(cell2mat(Y(I-2,1)),ccc);
end
min1=10^310;
k=-1;
for i=1:100
    if (D(i,1)<=min1)
        min1=D(i,1);
        k=i;
    end
end

global shu;
if min1>3*10^4
    msgbox('无法识别');
    J=J-1;
else
if k>0&&k<=10
    shu(J)=0;
elseif k>10&&k<=20
        shu(J)=1;
elseif k>20&&k<=30
        shu(J)=2;
elseif k>30&&k<=40
        shu(J)=3;
elseif k>40&&k<=50
        shu(J)=4;
elseif k>50&&k<=60
        shu(J)=5;
elseif k>60&&k<=70
        shu(J)=6;
elseif k>70&&k<=80
        shu(J)=7; 
elseif k>80&&k<=90
        shu(J)=8;        
elseif k>90&&k<=100
        shu(J)=9;         
end
c=num2str(shu(J));
n1=strcat(get(handles.edit1,'string')); % 获取数字号码
A=strcat(n1,c);  %连接每次识别出的号码
set(handles.edit1,'string',A); % 显示号码
end
  • 22
    点赞
  • 101
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
### 回答1: Matlab是一种强大的计算机软件,可以用于进行语音识别语音识别是一种将人类语音转换为计算机可理解的文本或命令的技术。 在Matlab中,我们可以使用不同的语音识别算法来实现0到9数字的识别。其中最常用的算法是基于隐马尔可夫模型(HMM)的语音识别方法。 HMM是一种统计模型,它描述了一个由各种状态和状态之间的转移概率组成的过程。对于语音识别,我们可以将每个数字的发音看作是一个状态序列,通过统计模型来进行识别。 在实现过程中,我们通常需要先进行语音信号的预处理,包括语音信号的采样和滤波处理等。然后,我们可以将这些预处理后的语音信号进行特征提取,常用的特征包括MFCC(Mel频率倒谱系数)或PLP(Perceptual Linear Prediction)等。 接下来,在Matlab中,我们可以使用HMM相关的函数和工具箱进行模型的训练和识别。通常,我们需要使用已知数字的语音样本来训练模型,然后使用训练好的模型来对新的语音进行识别。 在识别阶段,我们将经过预处理和特征提取的语音信号输入到训练好的HMM模型中,通过计算状态序列的概率进行识别判断。最后,我们可以将识别得到的数字输出为文本或命令,实现数字语音识别。 总而言之,通过Matlab可以实现0到9数字语音识别,借助HMM的统计模型和相关函数和工具箱,我们可以进行语音信号的预处理、特征提取、模型训练和识别等步骤,最终实现数字的语音转换。 ### 回答2: MATLAB语音识别0到9的过程可以分为几个步骤。首先,需要收集一组包含数字0到9的语音数据集,这些数据集可以是不同人的语音样本。接下来,需要对这些语音样本进行预处理。预处理包括音频信号的采样、去除噪声和提取特征等操作。 在预处理完成后,下一步是训练一个分类器来识别数字0到9。常用的分类器包括支持向量机、深度学习和随机森林等。训练分类器的过程中,使用已经处理好的语音样本作为输入,将对应的数字作为标签进行训练。 一旦分类器训练完成,就可以用它来预测新的语音样本所代表的数字。对于新的语音样本,同样需要进行预处理,然后将其输入到训练好的分类器进行分类。通过分类器的输出结果,就可以确定输入语音样本所代表的数字。 需要注意的是,语音识别是一个复杂的问题,需要考虑到不同语音的口音、噪声等因素对识别的影响。因此,在实际应用中,通常需要对模型进行调优和性能评估,以提高识别的准确率和鲁棒性。 以上就是MATLAB语音识别0到9的简要过程。通过预处理、训练分类器和识别预测的流程,可以实现对语音样本中数字的准确识别。 ### 回答3: Matlab是一种功能强大的编程语言和环境,它包含了许多音频处理的工具箱,可以用于语音识别。要实现0到9的语音识别,可以采用一种基于模板匹配的方法。 首先,我们需要采集一组包含0到9的已知语音样本作为模板。这些样本应该包含每个数字的不同说话人和不同语速的变化。我们可以使用Matlab提供的录音工具来进行样本采集,并将其保存为.wav文件。 接下来,对每个数字的样本进行预处理。我们可以使用信号处理函数来去除噪声和强化语音信号。一些常用的预处理技术包括滤波、归一化和谱平滑。 然后,通过特征提取从预处理的语音样本中获取有用的信息。常用的特征包括MFCC(梅尔频率倒谱系数)、过零率和短时能量。这些特征可以通过Matlab提供的音频处理工具箱来计算。 接下来,我们可以使用模板匹配算法识别语音。一种常用的算法是动态时间规整(DTW)。DTW可以测量两个语音序列之间的相似度,并找到最匹配的模板。可以使用Matlab中的DTW函数实现这个过程。 最后,我们可以将识别结果与真实的数字进行比较以验证准确性。根据识别的结果和设定的阈值,我们可以判断Matlab语音识别0到9的效果如何。 总结来说,使用Matlab进行语音识别需要采集样本、预处理、特征提取和模板匹配等步骤。通过这些步骤,我们可以实现对0到9的语音识别。但需要注意的是,语音识别是一个复杂的问题,可能会受到说话人、语速、环境噪声等多种因素的影响,因此准确性可能会有一定的限制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值