c++ 提取傅里叶描述子_AI大语音(四)——MFCC特征提取(深度解析)

5b294bc2ecb7da54d367b11a70d74542.png

1 特征提取流程

在语音识别和话者识别方面,最常用到的语音特征就是梅尔倒谱系数(Mel-scaleFrequency Cepstral Coefficients,简称MFCC)。

MFCC提取过程包括预处理、快速傅里叶变换、Mei滤波器组、对数运算、离散余弦变换、动态特征提取等步骤。

d64c8b19be1a33b464234c5706710009.png

f7179a17751d1026e889812b1e071d64.png

2 快速傅里叶变换

快速傅里叶变换即利用计算机计算离散傅里叶变换(DFT)的高效、快速计算方法的统称,简称FFT。

FFT不是Fast FT,而是Fast DFT

FT的种类很多,以最简单的基于2的FFT为例。

FFT实际上一种分治算法。FFT将长度为

的信号分解成两个长度为
信号进行处理,这样分解一直到最后,每一次的分解都会减少计算的次数。理解FFT分以下三个步骤进行:

74c72b37cffe6df302e3468f74c327ab.png

步骤1:将信号

分解成两个子信号

偶数样本点信号:

奇数样本点信号:

步骤2:将两个求和项理解成两个长度为

的DFT

步骤3:FFT的具体计算过程

对于任意

都要进行
次加法操作,所以DFT共有
次乘法操作。

对于任意
都要进行
次加法操作,DFT共有
次加法操作。

FFT共有
次乘法操作和
次加法操作。

语音信号是有限长的离散信号。

预处理后的语音信号:

53cb94b18d585dc543ab6d3aac43d8d1.png

FFT后效果:

d3a0b990d4c77ea1f57c21f5c0890da3.png

3 Mel滤波器组

将能量谱通过一组Mel尺度的三角形滤波器组,定义一个有M个滤波器的滤波器组(滤波器的个数和临界带的个数相近),采用的滤波器为三角滤波器,中心频率为 。M通常取22-26。各f(m)之间的间隔随着m值的减小而缩小,随着m值的增大而增宽,如图所示:

cd04418f0fcb42927bc7d6d1cf3768ab.png

三角带通滤波器有两个主要目的:

(1)三角形是低频密、高频疏的,这可以模仿人耳在低频处分辨率高的特性;

(2)对频谱进行平滑化,并消除谐波的作用,突显原先语音的共振峰。频谱有包络和精细结构,分别对应音色与音高。对于语音识别来讲,音色是主要的有用信息,音高一般没有用。在每个三角形内积分,就可以消除精细结构,只保留音色的信息。

(3)傅里叶变换得到的序列很长(一般为几百到几千个点),把它变换成每个三角形下的能量,可以减少数据量

Mel频率和频率f的对应关系:

ede8351e03427735f79c82221be05040.png

或者

4ef3f6b4e32c7ac35c257fbe4226dc81.png

989778f70341358f2202909de645299a.png

82a43cc4fd0d0e60b2e2f0357e4200c1.png

Mel滤波器实现过程:

(1)确定最低频率(0HZ),最高频率(fs/2),Mel滤波器个数M(23);

(2)转换最低频率和最高频率的Mel(f);

(3)计算相连两个Mel滤波器中心Mel频率的距离,在Mel频率上,两两之间的中心频率是等间距的;

ca7551f9dccf1b7b0251238e56972872.png

(4)将各种中心Mel频率转化为频率f(非等间距);
(5)计算频率所对应的FFT中点的下标;

e37c02b7f2be1c4787ff0f09adf326a6.png

31a0954e519bd929e82f1e7a9339b72d.png

4be40b909bafb21abf52919858e248a0.png

灵魂的拷问:为什么有些Mel滤波器组不等高,我设计的是等高的?这样有影响吗?有优势吗?

AI大语音:不等高的原因是乘了一个递减的系数,就是实现上一些细节的差别,保证了每个滤波器的能量和一样。横轴指的频率,低频的系数高,就是对低频更加的关注 。没有太大的影响,一般主要用等高的。

经过梅尔滤波器组后的Fbank特征:

cc4a84370a90241bf347affee57ac087.png

9e5a4281140c35445405dfd426cd306b.png

4 对数运算

将原语音信号经过傅里叶变换得到频谱:

X[k]=H[k]E[k]

只考虑幅度就是:

|X[k] |=|H[k]||E[k] |

两边取对数:

log||X[k] ||= log ||H[k] ||+ log ||E[k] ||

再在两边取逆傅里叶变换得到:

x[k]=h[k]+e[k]

灵魂的拷问:为什么要进行对数运算?它在干嘛?

对数运算包括取绝对值和log运算。取绝对值是仅使用幅度值,忽略相位的影响,因为相位信息在语音识别中作用不大。

log运算是为了分别包络和细节,包络代表音色,细节带包音高,显然语音识别就是为了识别音色。另外,人的感知与频率的对数成正比,正好使用log模拟。

FFT变换后,卷积变成了乘法,取对数后,乘法变成了加法,把卷积信号转换成加性信号。

c84a8c5448d11b3e2cdbc6ab08801e95.png

5 离散余弦变换(DCT)

再在两边取逆傅里叶变换得到:

x[k]=h[k]+e[k]

在上一步中,我们成功地把基音信息与声道信息变成了加性的。那么如何分离呢?它们有如下性质:

频谱图中(注意是一帧FFT变换内)

(1)基音信息在频域是快速变化的。

(2)声道信息在频域是缓慢变化的。

因此再做一次DCT可以将其分离。我们称之为"倒谱域"。因此倒谱域的低频部分刻画了声道信息,高频部分刻画了基音信息。

8f3ddd7036f1db83cf1c084d8c953f43.png

由此得到12维的MFCC特征:

8622ca1468ba212ff38741487f53797d.png

42d5a99947b0c742f6466b99100ead0f.png

由于许多要处理的信号都是实信号,在使用DFT时由于傅里叶变换时由于实信号傅立叶变换的共轭对称性导致DFT后在频域中有一半的数据冗余。
将DFT式子拆开,抽出实数部分:

9e8902fba4301a19e2a1c6e3e3549759.png

则实数部分:

c672812c50fcead9e3e231fde0bb9fea.png

虚数部分:

b045a9455b6026370f8f8341da526710.png

又有:

81befa505ffa7a7ffc39eb1e9b438fba.png

而当x[n]是实偶信号时:

0df23948ddbd60417258b1de8e5dd713.png

把DFT写成:

6a53c173a6fd92b6ee2dd46ded7e8a49.png

但是实际中并没有那么多实偶信号,我们就认为造出来。将信号长度扩大成原来的两倍,并变成2N,又为了让造出来的信号关于0对称,把整个延拓的信号向右平移 0.5 个单位,最终DCT变换公式:

df22fbedac58c511be2bc3410c136bd0.png

6 动态特征提取

标准的倒谱参数MFCC只反映了语音参数的静态特性,语音的动态特性可以用这些静态特征的差分谱来描述。实验证明:把动、静态特征结合起来才能有效提高系统的识别性能。差分参数的计算可以采用下面的公式:

bc22ef70922b615a0141c96b1b4fb509.png

式中,dt表示第t个一阶差分,Ct表示第t个倒谱系数,Q表示倒谱系数的阶数,K表示一阶导数的时间差,可取1或2。将上式的结果再代入就可以得到二阶差分的参数。

因此,MFCC的全部组成其实是由: N维MFCC参数(N/3 MFCC系数+ N/3 一阶差分参数+ N/3 二阶差分参数)+帧能量(此项可根据需求替换)。

这里的帧能量是指一帧的音量(即能量),也是语音的重要特征。

d_mfcc_feat = delta(wav_feature, 1) d_mfcc_feat2 = delta(wav_feature, 2)

feature = np.hstack((wav_feature, d_mfcc_feat, d_mfcc_feat2))

最终39维MFCC图:

89a1f7c3bc5a1d3cd395f280d3b42f8b.png

附录(魔鬼写手)

03ddcd0eb1173fae2c17482ccbbe8bbb.png

98083c7bb26f1518946b6ac9f35eb458.png

546c78c254df11474a1378a8cf40a261.png

0a05725593c5ff4a88d6e40b61d7768f.png

f8026d8eb679e35dcc6fc1c4479e8918.png

——————

浅谈则止,细致入微AI大道理

扫描下方“AI大道理”,选择“关注”公众号

37c126efe8b4a454565dafcda638323f.png

欢迎加入!

e28fea8645f8efcae8554e3e1a53191b.png

▼下期预告▼

AI大语音(五)——声学模型

▼往期精彩回顾▼

AI大语音(一)——语音识别基础

AI大语音(二)——语音预处理

AI大语音(三)——傅里叶变换家族

留你心,言你想

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334515.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 命令之 grep -- 强大的文本搜索工具/正则表达式搜索

文章目录一、命令介绍二、grep 的三种形式三、常用选项四、正则表达式五、参考示例在指定的文件中查找指定的关键词查看指定文件中含有特定关键词的文本行查看指定文件中所有包含数字的行在指定的目录下递归搜索指定的字符串,将符合的文本行及其文件名输出在指定文件…

java me基础教程 pdf_Java ME手机应用开发技术与案例详解 PDF

资源名称:Java ME手机应用开发技术与案例详解 PDFJava ME手机应用开发技术与案例详解基于Java ME,系统描述了Java ME手机应用开发的各个方面。全书按照Java ME程序的开发流程合理编排内容,分成3个部分依次讲述。第1部分包括第1章-第5章&#…

cli parser_Java命令行界面(第27部分):cli-parser

cli parserCLI Parser最初托管在Google Code上,现在已存档在Google Code上 ,现在可以在GitHub上使用 。 Google Code项目档案页面将CLI Parser描述为“使用非常简单,非常小的依赖项”,它使用注释“使非常简洁的主要方法不需要知道…

写一个sql实现以下查询结果_书写高质量SQL的30条建议

以下文章来源:后端程序员必备:书写高质量SQL的30条建议1、查询SQL尽量不要使用select *,而是select具体字段。反例子:select * from employee;正例子:select id,name from employee;理由:只取需…

Linux 命令之 sed -- 功能强大的流式文本编辑器

文章目录一、命令介绍二、命令格式三、常用选项四、sed 子命令五、sed 替换标记六、sed 元字符集七、命令示例(一)用指定的字符串替换掉指定的字符串(二)删除文档中的空白行(三)删除文档中的注释&#xff0…

flatmap_flatMap()与concatMap()与concatMapEager()– RxJava常见问题解答

flatmapRxJava 2.x中共有三个无缝相似的运算符&#xff1a; flatMap() &#xff0c; concatMap()和concatMapEager() 。 它们都接受相同的参数-从原始流的单个项目到任意类型的&#xff08;子&#xff09;流的函数。 换句话说&#xff0c;如果您有Flowable<T>则可以为任意…

java 中的点_java————形参中的点点点 | 学步园

转自:http://zhidao.baidu.com/question/149668626.htmlmain方法的签名其实可以这样写:public static void main(String... args)//方法1它也可以运行.并且,如果同时还存在public static void main(String[] args)//方法2会报已经存在重复的方法的错误.由此可见,String... args…

sendkeys.send 始终输出英文._PLC的三种输出方式,你知道有哪些吗?

电工技术维修学习网&#xff1a;www.dgjswx.com关注电工技术维修学习网官方微信公众号《电工维修学习》收获更多电工经验知识和提升实战技能电工技术&#xff0c;电气知识&#xff0c;电工基础知识&#xff0c;电工入门知识&#xff0c;电工资料&#xff0c;电工软件&#xff0…

Linux 命令之 echo -- 输出指定的字符串或者变量的值

文章目录一、命令介绍二、命令选项三、命令示例&#xff08;一&#xff09;输出变量的值&#xff08;二&#xff09;合并上下单元格内容&#xff08;三&#xff09;查看一行第一栏&#xff08;四&#xff09;查看一行的第一和第三栏&#xff08;五&#xff09;结合输出重定向符…

java 死循环排查_java应用死循环排查方法或查找程序消耗资源的线程方法(面试)...

今天遇到一个面试&#xff0c;怎么在一堆线程中查找一个死循环&#xff1f;如果遇到线上应用cpu飙升&#xff0c;并出现OutOfMemery怎么办&#xff1f;首先线上应用的jvm配置要养成良好的习惯&#xff0c;增加一下配置则可以在jvm发生 oom的时候自动dump日志了 -XX:HeapDumpOn…

jw摄像_Java命令行界面(第17部分):jw-options

jw摄像JavaWorld的文章“ 用Java处理命令行参数”&#xff1a; Matthias Laux博士关闭的案例介绍了一个简单的基于Java的库&#xff0c;用于处理命令行参数 &#xff0c;我在本文中将其称为jw-options 。 被引用的文章提供了有关为何在构造Options类时做出某些设计决策的背景信…

pixel和毫米怎么换算_压力传感器相关压力单位换算

压力传感器的应用已经很普遍了&#xff0c;压力传感器各个单间之间应该怎么换算呢&#xff0c;这个问题困扰着很多的客户&#xff0c;今天呢我们就来说一下它们之间的换算。在实际的工程应用中&#xff0c;压强单位常被当作压力单位。比较常见的压力单位包括&#xff1a;bar、K…

Linux 命令之 lsof -- 列出当前系统已打开的文件列表

文章目录命令介绍常用选项字段说明文件类型文件描述符文件状态模式锁模式参考示例&#xff08;一&#xff09;查看打开指定文件的所有进程&#xff08;二&#xff09;列出由某个 PID 对应的进程打开的所有文件&#xff08;三&#xff09;查看指定名称的进程所打开的文件列表&am…

mongodb json_在MongoDB和Spring Batch中将XML转换为JSON和原始使用

mongodb json总览 为什么将XML转换为JSON以在MongoDB中原始使用&#xff1f; 由于MongoDB使用JSON文档存储记录&#xff0c;就像表和行将记录存储在关系数据库中一样&#xff0c;我们自然需要将XML转换为JSON。 某些应用程序可能需要存储原始&#xff08;未修改的&#xff09;…

java串口发送16进制数据_MFC串口通信发送16进制数据的方法

本文实例为大家分享了MFC串口通信发送16进制数据的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下MFC串口通信会使用m_mscomm控件。发送数据一般是在edit control 里输入自己想发送的内容&#xff0c;然后点击send button。如果直接发送字符串内容&#xff0c;通过下…

Linux 命令之 du -- 显示每个文件和目录的磁盘使用空间/所占用的磁盘空间大小/所使用的磁盘空间大小/查看文件和目录的大小

文章目录命令介绍常用选项参考示例&#xff08;一&#xff09;显示当前目录下的所有子目录和文件所占空间&#xff08;二&#xff09;查看指定文件所占空间的大小&#xff08;三&#xff09;查看指定目录的所占空间&#xff08;四&#xff09;查看多个文件所占空间&#xff08;…

vue 侦听器侦听对象属性_Spring中的异步和事务性事件侦听器

vue 侦听器侦听对象属性内置的事件发布功能从Spring的早期版本开始存在&#xff0c;并且对于处理同一应用程序上下文中Spring组件之间的基本通信仍然有用。 通常&#xff0c;应用程序可以生成应用程序事件&#xff08;可以是任意对象&#xff09;并监听它们。 整个机制非常简单…

mac tomcat java_Mac下配置Java开发环境(JDK1.8)和Tomcat服务器

平时做PHP,装的有nginx,mysql这儿就不多说了&#xff0c;可以看前面的相关文章&#xff0c;用的brew配置的&#xff0c;超简单。 今天介绍一下Java相关的配置 Java官网下载&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/index.html 我这儿下载的是Java…

python集合和字典的区别_Python中的字典和集合

导语&#xff1a;本文章记录了本人在学习Python基础之数据结构篇的重点知识及个人心得&#xff0c;打算入门Python的朋友们可以来一起学习并交流。 本文重点&#xff1a; 1、掌握常见的字典创建&#xff0c;查询&#xff0c;判别方法&#xff1b; 2、了解字典中的defaultdict、…

Linux 命令之 df -- 显示磁盘空间使用情况

文章目录命令介绍常用选项大小格式参考示例&#xff08;一&#xff09;查看系统磁盘设备的使用情况&#xff08;二&#xff09;显示指定文件所在分区的磁盘使用情况&#xff08;三&#xff09;显示文件类型为ext4的磁盘使用情况命令介绍 df 命令的英文全称即“Disk Free”&…