【基于pyAudioKits的Python音频信号处理(七)】端点检测和语音识别

您所在的位置:网站首页 python语音电话 【基于pyAudioKits的Python音频信号处理(七)】端点检测和语音识别

【基于pyAudioKits的Python音频信号处理(七)】端点检测和语音识别

2023-08-24 05:26| 来源: 网络整理| 查看: 265

pyAudioKits是基于librosa和其他库的强大Python音频工作流支持。

API速查手册

通过pip安装:

pip install pyAudioKits

本项目的GitHub地址,如果这个项目帮助到了你,请为它点上一颗star,谢谢你的支持!如果你在使用过程中有任何问题,请在评论区留言或在GitHub上提issue,我将持续对该项目进行维护。

import pyAudioKits.audio as ak import numpy as np import pyAudioKits.analyse as aly

在介绍完通用音频后,本节进一步开始对语音信号进行研究。通用音频的理论和分析方法均适用于语音信号,而语音信号又有更多进一步的属性和分析方法,以及一些特有的任务。本节将主要对语音的端点检测和语音的特征提取和识别用pyAudioKits的实现方法进行演示。其中端点检测使用双门限法,而特征提取和识别使用MFCC+DTW方法。

语音构成

语音信号由三种成分构成。

浊音:具有周期性或准周期性,其频率被称为基频( F 0 F_0 F0​)或音调。近似乐音。

F 0 F_0 F0​ avg (Hz) F 0 F_0 F0​ min (Hz) F 0 F_0 F0​ max (Hz)男性12580200女性225150350儿童300200500

清音:没有周期性,没有固定的音高。近似噪音。

静音:依然存在背景噪音。

这里的三种成分在时间上互斥,而并非是叠加的,因此语音信号可以按时间顺序进行切分,并归类到上述三种类别中。

语音的建模

语音是通过上节提到过的线性时不变系统产生的,即 Y ( z ) = H ( z ) X ( z ) Y(z)=H(z)X(z) Y(z)=H(z)X(z),其中 y y y是生成的语音, x x x是产生语音所需的激励,而 h h h则是我们的声道和嘴唇形成的系统。

浊音是通过迫使空气通过声门而产生的,这种情况下声门会振动,产生准周期性的气流刺激声道。这种激励有基波和多次谐波,类似于乐音。清音则是通过沿着声道的某个点形成一个收缩,迫使空气通过收缩产生紊流而产生的。浊音和清音的激励都是随机的,因此均属于随机信号。

具体的发音则由声道的共振决定,声道的共振由声门能量激发。声道可以被看作一个横截面积均匀的直管,在声门端闭合,在嘴唇处打开。当声道的形状改变时,共振也随之改变。一般存在两个共振峰,它们是发音的特征。

对于浊音来说,声门被建模为双极点系统,空气激励与双极点系统卷积产生浊音的激励;清音不通过声门,紊流直接作为激励。

产生共振峰的声道被建模为10极点系统,而嘴唇被建模为单零点系统。它们与激励卷积产生最终的语音。

声门、声道和嘴唇的动作将会使得系统零点和极点的位置随时间改变,使得发音的特性随时间改变,使得语音能够传递信息。因此,语音信号往往不满足平稳随机过程。

语音的属性

语音也是音频信号,因此能量、功率、自相关函数、频谱、功率谱密度等属性均适用于语音。由于语音信号往往不是平稳的,分帧加窗是语音信号分析的必经之路。

除此之外,语音信号还有两个属性过零率和谱熵,分别定义在时域和频域。过零率是音频强度曲线穿过0的频率,可以反映信号中强度最大的那些成分的频率;而谱熵表示了一段短时信号的信息量,谱熵越大信息量越小。

为了进行语音信号分析,我们首先录制一小段音频。演示所用的音频为"sample_audio/zero_to_nine(Chinese).wav"(请在GitHub项目链接中查看),它是0-9九个阿拉伯数字的中文读音。

record = ak.read_Audio("sample_audio/zero_to_nine(Chinese).wav") record.plot()

请添加图片描述

可以看见信号集中在10处位置有显著大于0的振幅,这就是存在语音的位置,其余位置为静音。

其中“三”、“四”、“七”和“九”的开头存在清音,其余部分为浊音。

record_framed = record.framing(window="hamming")

录制的采样率为44100Hz,而人声基频一般分布在100-500Hz之间。绘制语谱图时,我们需要压缩高频的分辨率、提高低频的分辨率。其做法是在绘制时使用梅尔(mel)尺度频率轴坐标。梅尔尺度的理论基础是人耳感知的声音频率和声音的实际频率并不是线性相关的,梅尔尺度为频率区间赋予了和人儿听觉分辨率相当的分辨率。从真实频率 f f f转换为梅尔频率的公式为 f m e l = 2595 log ⁡ 10 ( 1 + f / 700 ) f_{mel}=2595\log_{10}(1+f/700) fmel​=2595log10​(1+f/700)。

此外,对于语音幅度谱的绘制,我们还使用增益的形式。

aly.FFT(record_framed).plot(plot_type="dB",freq_scale="mel")

请添加图片描述

浊音部分的语谱呈现纵向堆叠的横向条纹,且越高频的部分条纹颜色越冷,说明强度越低。这说明了浊音是基波和谐波的叠加,而其基波决定了其音高。

清音部分则是单条纵向条纹,其频率成分分布在整个频率范围内,因此近似于白噪音。

静音部分依然存在噪音,这些噪音频率成分主要集中在低频部分。

统计短时谱熵,其计算公式为 H [ k ] = − ∑ m = k − N + 1 N / 2 p [ k , m ] log ⁡ 2 p [ k , m ] w [ n − m ] H[k]=\displaystyle-\sum_{m=k-N+1}^{N/2}p[k,m]\log_2p[k,m]w[n-m] H[k]=−m=k−N+1∑N/2​p[k,m]log2​p[k,m]w[n−m],其中 p [ k , m ] = Y [ k , n ] ∑ l = 0 N 2 Y [ k , l ] p[k,m]=\frac{\displaystyle Y[k,n]}{\displaystyle\sum_{l=0}^{\frac{N}{2}}Y[k,l]} p[k,m]=l=0∑2N​​Y[k,l]Y[k,n]​,而 Y [ k , n ] = X [ k , n ] X ∗ [ k , n ] Y[k,n]=X[k,n]X^*[k,n] Y[k,n]=X[k,n]X∗[k,n], X [ k , n ] X[k,n] X[k,n]为第 k k k帧的短时频谱。

aly.specEntropy(record_framed).plot(), record.plot()

请添加图片描述 请添加图片描述

静音的谱熵中等,清音的谱熵最大,而浊音的谱熵最小。

进行短时过零率的统计。

aly.zerocrossing(record_framed).plot(), record.plot()

请添加图片描述 请添加图片描述

静音的过零率中等,清音的过零率最大,而浊音的过零率最小。

再进行短时能量的统计。

aly.energy(record_framed).plot(), record.plot()

请添加图片描述 请添加图片描述

静音的能量几乎为0,而浊音和清音具有较高的能量。

语音的端点检测

鉴于静音部分和语音部分,以及清音部分和浊音部分,在短时能量、短时过零率和谱熵等属性上有统计意义上的区别,我们可以借助这一区别对语音进行端点检测。端点检测的目标是在一段音频信号中检测出每段语音的起始点和终止点,并在每段语音中区分出清音和浊音。

端点检测常用的方法是双门限法:

计算短时能量和短时过零率。

设置一个短时能量阈值和一个短时过零率阈值。

计算短时能量上穿短时能量阈值的点作为语音起始点,下穿短时能量阈值的点作为语音结束点。

从语音起始点开始往左,寻找短时过零率大于短时过零率阈值的最后一个点作为新的语音起始点;从语音结束点开始往右,寻找短时过零率大于短时过零率阈值的第一个点作为新的语音结束点。这样就可以区分语音和静音。

在语音段内再设置一个较高的短时能量阈值。

在每段语音段内,计算短时能量上穿短时能量阈值的点作为浊音起始点,下穿短时能量阈值的点作为浊音结束点。

从浊音起始点开始往左,寻找短时过零率小于短时过零率阈值的最后一个点作为新的浊音起始点;从浊音结束点开始往右,寻找短时过零率小于短时过零率阈值的第一个点作为新的浊音结束点。这样就可以区分浊音和清音。

import seaborn as sns sns.distplot(aly.zerocrossing(record_framed).samples)

请添加图片描述

aly.energy(record_framed).plot(ylim=(0,0.5))

请添加图片描述

通过绘制短时过零率的直方图可以帮助我们选择短时过零率阈值。短时能量阈值则要通过观察短时能量图像后,不断调节来确定。

vad_result = alg.VAD(record, 0.05, 0.5, 400) #对录音进行端点检测,设置较低的短时能量阈值为0.05、较高的短时能量阈值为0.5、短时过零率阈值为400 vad_result.plot()

请添加图片描述

可以看到我们成功区分出了10段语音,并且区分出了“三”、“四”、“七”和“九”前的清音。

语音识别

语音识别是语音信号处理的任务之一。最基本的有监督语音识别需要一个训练集,里面包含了很多段语音的特征及其对应文本的标签,用于训练模型。对于新得到的语音,我们希望机器能够识别该语音对应的文本,因此将新得到的语音作为测试集,并提取特征,将其通过模型得到标签,从而知道测试集上语音对应的文本。

MFCC

为了能够进行语音识别,需要先对语音特征进行提取。语音的语谱就是可用的语音特征之一,若使用每帧内的全部样本点来进行傅里叶变换,则语谱含有语音的所有信息。但语谱是非常巨大的,对于K帧、每帧内有N个样本点的语音信号,若采用 N N N点傅里叶变换,则其语谱尺寸为 K × N 2 K\times \frac{N}{2} K×2N​,若分帧的重叠率为0,则其尺寸就等于样本总数的一半。如果我们用于语音识别的算法较为简单,可以提取一些较为轻量而最大程度保持语音有用信息的特征。

梅尔倒谱系数(Mel-scale FrequencyCepstral Coefficients,简称MFCC)是依据人的听觉实验结果来分析语音的频谱,其理论基础包括梅尔尺度和第二临界带。其中梅尔尺度我们已经介绍过。第二临界带则是把进入人耳的声音频率用临界带进行划分,将语音在频域上就被划分成一系列的频率群,组成了滤波器组,即梅尔滤波器组。根据用梅尔尺度定义的分辨率,从低频到高频内按临界带宽的大小由密到疏安排一组带通滤波器,对输入信号进行滤波,将每个带通滤波器输出的信号能量作为信号的基本特征,对此特征经过进一步处理后就可以作为语音的输入特征。

在提取MFCC特征前,首先要对音频进行预加重,其方法是将音频通过一个系统函数为 H ( z ) = 1 − 0.97 z − 1 H(z)=1-0.97z^{-1} H(z)=1−0.97z−1的高通滤波器以补偿高频部分的损失(这是因为介质作为声能量的载体,在声源尺寸一定的情况下,频率越高,介质对声能量的损耗越严重)。然后对音频进行分帧加窗。再在频谱上加上梅尔滤波器组,其频率响应定义为: H m [ k ] = { 0 , k < f ( m − 1 )   o r   k ≥ f ( m − 1 ) 2 ( k − f ( m − 1 ) ) ( f ( m + 1 ) − f ( m − 1 ) ) ( f ( m ) − f ( m − 1 ) ) , f ( m − 1 ) ≤ k ≤ f ( m ) 2 ( f ( m + 1 ) − k ) ( f ( m + 1 ) − f ( m − 1 ) ) ( f ( m ) − f ( m − 1 ) ) , f ( m ) ≤ k ≤ f ( m + 1 ) H_m[k]=\begin{cases}0,&k



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3