语音识别-过零率和短时能量-端点检测

端点检测

个人理解

能量与过零数的端点检测算法步骤

  1. 语音信号x(n)进行分帧处理
  2. 计算每一帧的短时能量,得到语音的短时帧能量
  3. 计算每一帧语音的过零数,得到短时帧过零数
  4. 考擦语音的平均能量设置一个较高的门限T1,用以确定语音的开始,然后根据背景噪声的平均能量确定一个稍低的门限T2,用以确定第一级语音结束点。第二级判决同样根据背景噪声平均过零,设置一个门限T3,判断语音前段清音和后端尾音。

我直接根据幅度来设置门限

a. 语音信号分帧处理

filedir=[];%设置路径
filename='D:\matlab\music\zj3.wav';
file=[filedir filename];
[x,Fs]=audioread(file);%得到语音信号的数据

wlen=200;%帧长
inc=100;%帧移
win=hamming(wlen);%海明窗
N=length(x);%信号长度
time=(0:N-1)/Fs;%计算出信号的时间刻度

X=enframe(x,win,inc)'; %分帧,一列是一帧
fn=size(X,2);%帧数
frameTime=frame2time(fn,wlen,inc,Fs);  %求出每帧对应的时间
%这个公式得再看一下

b.

 %短时能量
  for i=1:fn
          y=X(:,i);%每一帧数据
          b=0;
          for m=1:1:200 %这是根据帧长定的
          b=b+y(m).^2;   
          end
          E(i)=b;
  end
  
  %%参考-更简单点-尚未理解
  
  fn=size(X,2);              % 求出帧数
time=(0:N-1)/Fs;           % 计算出信号的时间刻度
for i=1 : fn
    u=X(:,i);              % 取出一帧
    u2=u.*u;               % 求出能量
    En(i)=sum(u2);         % 对一帧累加求和
end

c. 短时帧过零数

 %短时过零率
   Z=zeros(1,fn);                 % 初始化
  for i=1:fn
          y=X(:,i);%每一帧数据
          b=0;
          for m=1:1:199  %根据帧长来定的
          if y(m)*y(m+1)<0;
              b=b+1;
          end
          Z(i)=b;
          end
  end
  
  %%更简单点-尚未理解
  fn=size(X,2);                     % 获取帧数
zcr1=zeros(1,fn);                 % 初始化
for i=1:fn
    z=X(:,i);                     % 取得一帧数据
    for j=1: (wlen- 1) ;          % 在一帧内寻找过零点
         if z(j)* z(j+1)< 0       % 判断是否为过零点
             zcr1(i)=zcr1(i)+1;   % 是过零点,记录1次
         end
    end
end

d.根据平均能量来设置门限

平均能量的结果:

[外链图片转存失败(img-Ciy7MbEu-1563959907473)(D:\matlab\语音信号处理实验教程-自己\assets\短时能量.jpg)]

E共有818个数据

T1设置为0.01,即当找到大于0.1标记。语音的开始

T2设置为0.001,即当找到小于0.001标记。语音的结束

找到了点,但是编程有点问题。就是要只显示端点而不是全部显示

[外链图片转存失败(img-2wWpu6Tz-1563959907475)(assets/找到了点-1但是没找到端点.jpg)]
语音识别-过零率和短时能量-端点检测_第1张图片

经修改

[外链图片转存失败(img-SRvXb1fn-1563959907476)(assets/找到点-有点问题.jpg)]
语音识别-过零率和短时能量-端点检测_第2张图片

过零率端点找得有点问题

%能量与过零数的端点检测算法1
clear all;
clc;
filedir=[];%设置路径
filename='D:\matlab\music\zs.wav';
file=[filedir filename];
[x,Fs]=audioread(file);
xmax=max(abs(x));
x=x/xmax';%归一化

x=filter([1 -0.98],[1],x);%预加重

wlen=200;%帧长
inc=100;%帧移
win=hamming(wlen);%海明窗
N=length(x);%信号长度
time=(0:N-1)/Fs;%计算出信号的时间刻度

X=enframe(x,win,inc)'; %分帧,一列是一帧
% Xmax=max(abs(X));%矩阵归一化,这个还不行
% X=X/Xmax;
fn=size(X,2)';%帧数
frameTime=frame2time(fn,wlen,inc,Fs);  %求出每帧对应的时间
%这个公式得再看一下

%短时能量
for i=1:fn
    y=X(:,i);%每一帧数据
    b=0;
    for m=1:1:200%一帧中的数据
        b=b+y(m).^2;
    end
    E(i)=b;
end


%短时过零率
Z=zeros(1,fn);                 % 初始化,fn之前用过
for i=1:fn
    y=X(:,i);%每一帧数据
    b=0;
    for m=1:1:199
        if y(m)*y(m+1)<0;
            b=b+1;
        end
        Z(i)=b;
    end
end

%找短时能量的门限来确定语音的开始和结束
zeros(i);
q=[];%存储开始语音界限的位置
i1=1;
while (i10.1
            q=[q i1-1];
            i1=i1+1;
            for i2=i1:length(E)
                e=E(i2);
                if e<0.1
                    q=[q i2+1];
                    i1=i2+1;
                    break
                end               
            end
            break
        end
    end
end

%过零率
i1=1;
w=[];%存储结束语音界限位置
while (i1120
           w=[w i1];
            i1=i1+1;
            for i2=i1:length(Z)
                e=Z(i2);
                if e<50
                    w=[w i2+1];
                    i1=i2+1;
                    break
                end               
            end
            break
        end
    end
end

    %画图
    subplot(311)
    plot(time,x);
    title('原始信号')
    xlabel('时间');ylabel('幅度');
    subplot(312)
    plot(frameTime(q),E(q),'or');
    hold on
    plot(frameTime,E);
      title('短时能量')
    xlabel('时间');ylabel('幅度');
    subplot(313)
    plot(frameTime(w),Z(w),'or');
    hold on
    plot(frameTime,Z);
      title('过零率')
    xlabel('时间');ylabel('次数'); 

最终结果

语音识别-过零率和短时能量-端点检测_第3张图片
问题:因为判断方式不同,书上的判断更准确。
根据幅度来判断变化比较大,且还得根据音频来切换幅度。

你可能感兴趣的:(matlab)