【语音识别】语音端点检测及Python实现

  • 一、语音信号的分帧处理
  • 二、端点检测方法
    • 2.1、短时能量
    • 2.2、短时过零率
  • 三、Python实现

从接收的语音信号中准确检测出人声开始和结束的端点是进行语音识别的前提。本博文介绍基于短时过零率和短时能量的基本语音端点检测方法及Python实现。如图所示为语音信号,红色方框内为人声:

一、语音信号的分帧处理

语音信号是时序信号,其具有长时随机性和短时平稳性。长时随机性指语音信号随时间变化是一个随机过程,短时平稳性指在短时间内其特性基本不变,因为人说话是肌肉具有惯性,从一个状态到另一个状态不可能瞬时完成。语音通常在10-30ms之间相对平稳,因此语音信号处理的第一步基本都是对语音信号进行分帧处理,帧长度一般取10-30ms。
语音信号的分帧处理通常采用滑动窗的方式,窗口可以采用直角窗、Hamming窗等。窗口长度决定每一帧信号中包含原始语音信号中信息的数量,窗口每次的滑动距离等于窗口长度时,每一帧信息没有重叠,当窗口滑动距离小于窗口长度时帧信息有重合。本博文采用直角窗进行语音信号的分帧处理:

直角窗:
h(n)={1,0≤n≤N−10,other{\rm{h}}(n) = \left\{ {\begin{matrix} {1, 0\le n \le N - 1}\\ {0,{\rm{other}}} \end{matrix}} \right.h(n)={1,0≤n≤N−10,other​

二、端点检测方法

端点检测是指找出人声开始和结束的端点。利用人声信号短时特性与非人声信号短时特性的差异可以有效地找出人声开始和结束的端点,本博文介绍短时能量和短时过零率结合进行端点检测的方法。

2.1、短时能量

第n帧信号的短时平均能量定义为:
En=∑m=n−N+1n[x(m)w(n−m)]2{E_n} = \sum\limits_{m = n - N + 1}^n {{{\left[ {x\left( m \right)w\left( {n - m} \right)} \right]}^2}}En​=m=n−N+1∑n​[x(m)w(n−m)]2
包含人声信号的帧的短时平均能量大于非人声信号的帧。

2.2、短时过零率

过零信号指通过零值,相邻取样值改变符号即过零,过零数是样本改变符号的数量。
第n帧信号的平均短时过零数为:
Zn=∑m=n−N+1n∣sgn[x(m)]−sgn[x(m−1)]∣w(n−m){Z_n} = \sum\limits_{m = n - N + 1}^n {\left| {{\mathop{\rm sgn}} \left[ {x\left( m \right)} \right] - {\mathop{\rm sgn}} \left[ {x\left( {m - 1} \right)} \right]} \right|w\left( {n - m} \right)}Zn​=m=n−N+1∑n​∣sgn[x(m)]−sgn[x(m−1)]∣w(n−m)

w(n)={1/(2N),0≤n≤N−10,otherw\left( n \right) = \left\{ {\begin{matrix} {1/\left( {2N} \right),0 \le n \le N - 1}\\ {0,other} \end{matrix}} \right.w(n)={1/(2N),0≤n≤N−10,other​

三、Python实现

import wave
import numpy as np
import matplotlib.pyplot as pltdef read(data_path):'''读取语音信号'''wavepath = data_pathf = 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,frameratedef plot(data,time):plt.plot(time,data)plt.grid('on')plt.show()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 = winelse:wlen = nwinnf = int(np.fix((nx - wlen) / inc) + 1) #窗口移动的次数f = np.zeros((nf,wlen))  #初始化二维数组indf = [inc * j for j in range(nf)]indf = (np.mat(indf)).Tinds = np.mat(range(wlen))indf_tile = np.tile(indf,wlen)inds_tile = np.tile(inds,(nf,1))mix_tile = indf_tile + inds_tilef = np.zeros((nf,wlen))for i in range(nf):for j in range(wlen):f[i,j] = data[mix_tile[i,j]]return fdef 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<0] for i in x], signs))diffs = np.sign(abs(FrameTemp1 - FrameTemp2)-0.01)diffs = list(map(lambda x:[[i,0] [i<0] for i in x], diffs))zcr = list((np.multiply(signs, diffs)).sum(axis = 1))#2.计算短时能量amp = list((abs(enframe(wavedata,win,inc))).sum(axis = 1))
#    # 设置门限
#    print('设置门限')ZcrLow = max([round(np.mean(zcr)*0.1),3])#过零率低门限ZcrHigh = max([round(max(zcr)*0.1),5])#过零率高门限AmpLow = min([min(amp)*10,np.mean(amp)*0.2,max(amp)*0.1])#能量低门限AmpHigh = max([min(amp)*10,np.mean(amp)*0.2,max(amp)*0.1])#能量高门限# 端点检测MaxSilence = 8 #最长语音间隙时间MinAudio = 16 #最短语音时间Status = 0 #状态0:静音段,1:过渡段,2:语音段,3:结束段HoldTime = 0 #语音持续时间SilenceTime = 0 #语音间隙时间print('开始端点检测')StartPoint = 0for n in range(len(zcr)):if Status ==0 or Status == 1:if amp[n] > AmpHigh or zcr[n] > ZcrHigh:StartPoint = n - HoldTimeStatus = 2HoldTime = HoldTime + 1SilenceTime = 0elif amp[n] > AmpLow or zcr[n] > ZcrLow:Status = 1HoldTime = HoldTime + 1else:Status = 0HoldTime = 0elif Status == 2:if amp[n] > AmpLow or zcr[n] > ZcrLow:HoldTime = HoldTime + 1else:SilenceTime = SilenceTime + 1if SilenceTime < MaxSilence:HoldTime = HoldTime + 1elif (HoldTime - SilenceTime) < MinAudio:Status = 0HoldTime = 0SilenceTime = 0else:Status = 3elif Status == 3:breakif Status == 3:breakHoldTime = HoldTime - SilenceTimeEndPoint = StartPoint + HoldTimereturn StartPoint,EndPoint,FrameTemp1if __name__ == '__main__':data_path = 'audio_data.wav'win = 240inc = 80wavedata,nframes,framerate = read(data_path)time_list = np.array(range(0,nframes)) * (1.0 / framerate)plot(wavedata,time_list)StartPoint,EndPoint,FrameTemp = point_check(wavedata,win,inc)checkdata,Framecheck = check_signal(StartPoint,EndPoint,FrameTemp,win,inc)

端点检测结果:

【语音识别】语音端点检测及Python实现相关推荐

  1. 双门限法语音端点检测(Python实现)

    写在前面 花了几天时间写完了第一个视听觉信号处理的实验,其实还挺简单的,在这里分享一下. 本文介绍一下利用双门限法进行语音端点检测的方法,该方法主要利用了语音的短时能量和短时过零率,关于这两个语音特征 ...

  2. python分割语音端点检测_python的webrtc库如何实现语音端点检测 科大讯飞输入法PC体验版下载:语音+手写+...

    python的webrtc库如何实现语音端点检测 科大讯飞输入法PC体验版下载:语音+手写+ 2018-03-05 出处:网络 整理:zhishizhan.net 延伸:科大讯飞输入法PC体验版下载: ...

  3. python分割语音端点检测_如何实现语音端点检测

    跪CSS布局HTML小编今天和大家分享一篇毕业论文 题目<语音端点检测与分割研究方欢迎来到CSS布局HTML的.你要的相关资料我有啊. 我给你发到了附件中. 楼上的复制的我的回答没有把实际的东西 ...

  4. C# 语音端点检测(VAD)实现过程分析

    前言: 早期的方法大多是基于声学特征的提取, 在时域上, 1975年, Rabiner 等人提出了基于短时能量和过零率的语音端点检测方法, 这是第一个系统而完整的语音端点检测算法.该方法共有三个门限值 ...

  5. MATLAB语音端点检测

    第一章 绪论 Matlab是矩阵实验室(Matrix Laboratory)的简称,是美国MathWorks公司出品的商业数学软件,用于算法开发.数据可视化.数据分析以及数值计算的高级技术计算语言和交 ...

  6. 语音端点检测 php,几种语音端点检测方法简介

    几种语音端点检测方法简介 2011年第11期福建电脑 67 几种语音端点检测方法简介 邢亚从 (苏州市职业大学江苏苏州215000) [摘要]:语音的端点检测在语音的编码.语音识别.语音增强.说话人识 ...

  7. 语音端点检测c语言,语音端点检测的方法.ppt

    语音端点检测的方法 语音端点检测的方法 演讲者:刘德体 语音端点检测的目的和意义 基于短时能量和短时平均过零率的端点检测 基于倒谱特征的端点检测 基于熵的端点检测 基于复杂性的端点检测(KC复杂性和C ...

  8. 基于双门限法的语音端点检测及语音分割

    voice_activity_detection Audio Split 基于双门限法的语音端点检测及语音分割 代码在我的github上voice_activity_detection 如果您觉得有一 ...

  9. 【数字语音处理】Part3 语音信号的短时时域分析:短时平均、短时自相关、语音端点检测、基音周期估值

    Part3 语音信号的短时时域分析 一.帧和加窗的概念 二.短时平均能量 三.短时平均幅度函数 四.短时平均过零率 五.短时自相关分析 六.基于能量和过零率的语音端点检测 七.基音周期估值 八.总结 ...

最新文章

  1. java怎么创建二进制文件_Java:如何编写二进制文件?
  2. PHP Cookbook读书笔记 – 第16章互联网服务
  3. 计算机控制 重修,计算机控制技术重修复习提纲.doc
  4. 华为手机多久可以摆脱美国技术依赖?任正非放出豪言!
  5. ios 图片裁剪框架_iOS 图片裁剪与修改
  6. C++中指针优点与线程中指针变量访问
  7. 一款用来下载pdf word zip img各种文件的js插件
  8. 飞凌课堂丨揭开影响RS485通讯因素的面纱
  9. VMware安装及使用详细教程
  10. 图音80系列车载导航/DVD分体机安装DSA
  11. 思维导图一定要用计算机来完成吗,程序猿不仅可以用电脑敲代码,还可以用来制作思维导图...
  12. Battleship!
  13. idea激活到2100年
  14. supersu二进制更新安装失败_supersu二进制更新失败怎么办及解决方法
  15. 培养良好习惯的7个正确方法
  16. Error 0x80240017: Failed to execute MSU package.
  17. VARIANT数据类型详解
  18. 微信小程序使用video组件时的一些坑
  19. java oop6_Java oop代码6(原创方法):5道用上extends继承,子类,父类的题
  20. Mybatis-Plus入门学习

热门文章

  1. opencv绘制基本形状的二值图像
  2. 个人三观的东西(1)
  3. 深度学习网络模型实战
  4. Java-HashMap实现原理
  5. java aqs原理_Java并发之AQS详解
  6. 一米机器人解绑再绑定_安顿问答027:安顿APP里的角色绑定错了,可以更改吗?...
  7. AcWing 1922. 懒惰的牛(前缀和 or 双指针)
  8. awd赛题的flag是什么意思_写在新年伊始——由新年Flag所想到的
  9. 数据库oracle有哪些函数,Oracle函数大全
  10. Spark(Hive)对字符串数值的排序