最近学习音乐自动标注的过程中,看到了有关使用MFCC提取音频特征的内容,特地在网上找到资料,学习了一下相关内容。此笔记大部分内容摘自博文 http://blog.csdn.net/zouxy09/article/details/9156785 有小部分标注和批改时我自己加上的,以便今后查阅。


语音信号处理之(四)梅尔频率倒谱系数(MFCC)

zouxy09@qq.com

http://blog.csdn.net/zouxy09

在任意一个Automatic speech recognition 系统中,第一步就是提取特征。换句话说,我们需要把音频信号中具有辨识性的成分提取出来,然后把其他的乱七八糟的信息扔掉,例如背景噪声啊,情绪啊等等。

搞清语音是怎么产生的对于我们理解语音有很大帮助。人通过声道产生声音,声道的shape(形状?)决定了发出怎样的声音。声道的shape包括舌头,牙齿等。如果我们可以准确的知道这个形状,那么我们就可以对产生的音素phoneme进行准确的描述。声道的形状在语音短时功率谱的包络中显示出来。而MFCCs就是一种准确描述这个包络的一种特征。

MFCCs(Mel Frequency Cepstral Coefficents)是一种在自动语音和说话人识别中广泛使用的特征。它是在1980年由Davis和Mermelstein搞出来的。从那时起。在语音识别领域,MFCCs在人工特征方面可谓是鹤立鸡群,一枝独秀,从未被超越啊(至于说Deep Learning的特征学习那是后话了)。

好,到这里,我们提到了一个很重要的关键词:声道的形状,然后知道它很重要,还知道它可以在语音短时功率谱的包络中显示出来。哎,那什么是功率谱?什么是包络?什么是MFCCs?它为什么有效?如何得到?下面咱们慢慢道来。

一、声谱图(Spectrogram)

我们处理的是语音信号,那么如何去描述它很重要。因为不同的描述方式放映它不同的信息。那怎样的描述方式才利于我们观测,利于我们理解呢?这里我们先来了解一个叫声谱图的东西。

这里,这段语音被分为很多帧,每帧语音都对应于一个频谱(通过短时FFT计算),频谱表示频率与能量的关系。在实际使用中,频谱图有三种,即线性振幅谱、对数振幅谱、自功率谱(对数振幅谱中各谱线的振幅都作了对数计算,所以其纵坐标的单位是dB(分贝)。这个变换的目的是使那些振幅较低的成分相对高振幅成分得以拉高,以便观察掩盖在低幅噪声中的周期信号)。

我们先将其中一帧语音的频谱通过坐标表示出来,如上图左。现在我们将左边的频谱旋转90度。得到中间的图。然后把这些幅度映射到一个灰度级表示(也可以理解为将连续的幅度量化为256个量化值?),0表示黑,255表示白色。幅度值越大,相应的区域越黑。这样就得到了最右边的图。那为什么要这样呢?为的是增加时间这个维度,这样就可以显示一段语音而不是一帧语音的频谱,而且可以直观的看到静态和动态的信息。优点稍后呈上。

这样我们会得到一个随着时间变化的频谱图,这个就是描述语音信号的spectrogram声谱图。

下图是一段语音的声谱图,很黑的地方就是频谱图中的峰值(共振峰formants)。

那我们为什么要在声谱图中表示语音呢?

首先,音素(Phones)的属性可以更好的在这里面观察出来。另外,通过观察共振峰和它们的转变可以更好的识别声音。隐马尔科夫模型(Hidden Markov Models)就是隐含地对声谱图进行建模以达到好的识别性能。还有一个作用就是它可以直观的评估TTS系统(text to speech)的好坏,直接对比合成的语音和自然的语音声谱图的匹配度即可。

  通过对语音进行分帧进行时频变换,得到每一帧的FFT频谱再将各帧频谱按照时间顺序排列起来,得到时间-频率-能量分布图。很直观的表现出语音信号随时间的频率中心的变化。

二、倒谱分析(Cepstrum Analysis)

下面是一个语音的频谱图。峰值就表示语音的主要频率成分,我们把这些峰值称为共振峰(formants),而共振峰就是携带了声音的辨识属性(就是个人身份证一样)。所以它特别重要。用它就可以识别不同的声音。

既然它那么重要,那我们就是需要把它提取出来!我们要提取的不仅仅是共振峰的位置,还得提取它们转变的过程。所以我们提取的是频谱的包络(Spectral Envelope)。这包络就是一条连接这些共振峰点的平滑曲线。

我们可以这么理解,将原始的频谱由两部分组成:包络和频谱的细节。这里用到的是对数频谱,所以单位是dB。那现在我们需要把这两部分分离开,这样我们就可以得到包络了。

那怎么把他们分离开呢?也就是,怎么在给定log X[k]的基础上,求得log H[k] 和 log E[k]以满足log X[k] = log H[k] + log E[k]呢?

为了达到这个目标,我们需要Play a Mathematical Trick。这个Trick是什么呢?就是对频谱做FFT。在频谱上做傅里叶变换就相当于逆傅里叶变换Inverse FFT (IFFT)。需要注意的一点是,我们是在频谱的对数域上面处理的,这也属于Trick的一部分。这时候,在对数频谱上面做IFFT就相当于在一个伪频率(pseudo-frequency)坐标轴上面描述信号。

由上面这个图我们可以看到,包络是主要是低频成分(这时候需要转变思维,这时候的横轴就不要看成是频率了,咱们可以看成时间),我们把它看成是一个每秒4个周期的正弦信号。这样我们在伪坐标轴上面的4Hz的地方给它一个峰值。而频谱的细节部分主要是高频。我们把它看成是一个每秒100个周期的正弦信号。这样我们在伪坐标轴上面的100Hz的地方给它一个峰值。

把它俩叠加起来就是原来的频谱信号了。

在实际中咱们已经知道log X[k],所以我们可以得到了x[k]。那么由图可以知道,h[k]是x[k]的低频部分,那么我们将x[k]通过一个低通滤波器就可以得到h[k]了!没错,到这里咱们就可以将它们分离开了,得到了我们想要的h[k],也就是频谱的包络。

x[k]实际上就是倒谱Cepstrum(这个是一个新造出来的词,把频谱的单词spectrum的前面四个字母顺序倒过来就是倒谱的单词了)。而我们所关心的h[k]就是倒谱的低频部分。h[k]描述了频谱的包络,它在语音识别中被广泛用于描述特征。

那现在总结下倒谱分析,它实际上是这样一个过程:

1)将原语音信号经过傅里叶变换得到频谱:X[k]=H[k]E[k];

  只考虑幅度就是:|X[k] |=|H[k]||E[k] |;

2)我们在两边取对数:log||X[k] ||= log ||H[k] ||+ log ||E[k] ||。

3)再在两边取逆傅里叶变换得到:x[k]=h[k]+e[k]。

这实际上有个专业的名字叫做同态信号处理。它的目的是将非线性问题转化为线性问题的处理方法。对应上面,原来的语音信号实际上是一个卷性信号(声道相当于一个线性时不变系统,声音的产生可以理解为一个激励通过这个系统),第一步通过卷积将其变成了乘性信号(时域的卷积相当于频域的乘积)。第二步通过取对数将乘性信号转化为加性信号,第三步进行逆变换,使其恢复为卷性信号。这时候,虽然前后均是时域序列,但它们所处的离散时域显然不同,所以后者称为倒谱频域

总结下,倒谱(cepstrum)就是一种信号的傅里叶变换经对数运算后再进行傅里叶反变换得到的谱。它的计算过程如下:

以下部分还未整理


三、Mel频率分析(Mel-Frequency Analysis) 

好了,到这里,我们先看看我们刚才做了什么?给我们一段语音,我们可以得到了它的频谱包络(连接所有共振峰值点的平滑曲线)了。但是,对于人类听觉感知的实验表明,人类听觉的感知只聚焦在某些特定的区域,而不是整个频谱包络。

Mel频率分析就是基于人类听觉感知实验的。实验观测发现人耳就像一个滤波器组一样,它只关注某些特定的频率分量(人的听觉对频率是有选择性的)。也就说,它只让某些频率的信号通过,而压根就直接无视它不想感知的某些频率信号。但是这些滤波器在频率坐标轴上却不是统一分布的,在低频区域有很多的滤波器,他们分布比较密集,但在高频区域,滤波器的数目就变得比较少,分布很稀疏。

人的听觉系统是一个特殊的非线性系统,它响应不同频率信号的灵敏度是不同的。在语音特征的提取上,人类听觉系统做得非常好,它不仅能提取出语义信息, 而且能提取出说话人的个人特征,这些都是现有的语音识别系统所望尘莫及的。如果在语音识别系统中能模拟人类听觉感知处理特点,就有可能提高语音的识别率。

梅尔频率倒谱系数(Mel Frequency Cepstrum Coefficient, MFCC)考虑到了人类的听觉特征,先将线性频谱映射到基于听觉感知的Mel非线性频谱中,然后转换到倒谱上。

将普通频率转化到Mel频率的公式是:
 
      由下图可以看到,它可以将不统一的频率转化为统一的频率,也就是统一的滤波器组。

在Mel频域内,人对音调的感知度为线性关系。举例来说,如果两段语音的Mel频率相差两倍,则人耳听起来两者的音调也相差两倍。

四、Mel频率倒谱系数(Mel-Frequency Cepstral Coefficients) 

我们将频谱通过一组Mel滤波器就得到Mel频谱。公式表述就是:log X[k] = log (Mel-Spectrum)。这时候我们在log X[k]上进行倒谱分析:

1)取对数:log X[k] = log H[k] + log E[k]。

2)进行逆变换:x[k] = h[k] + e[k]。

在Mel频谱上面获得的倒谱系数h[k]就称为Mel频率倒谱系数,简称MFCC

现在咱们来总结下提取MFCC特征的过程:(具体的数学过程网上太多了,这里就不想贴了)

1)先对语音进行预加重、分帧和加窗;(加强语音信号性能(信噪比,处理精度等)的一些预处理)

2)对每一个短时分析窗,通过FFT得到对应的频谱;(获得分布在时间轴上不同时间窗内的频谱)

3)将上面的频谱通过Mel滤波器组得到Mel频谱;(通过Mel频谱,将线形的自然频谱转换为体现人类听觉特性的Mel频谱)

4)在Mel频谱上面进行倒谱分析(取对数,做逆变换,实际逆变换一般是通过DCT离散余弦变换来实现,取DCT后的第2个到第13个系数作为MFCC系数),获得Mel频率倒谱系数MFCC,这个MFCC就是这帧语音的特征;(倒谱分析,获得MFCC作为语音特征)

这时候,语音就可以通过一系列的倒谱向量来描述了,每个向量就是每帧的MFCC特征向量。

这样就可以通过这些倒谱向量对语音分类器进行训练和识别了。

五、参考文献

[1]这里面还有一个比较好的教程:

http://practicalcryptography.com/miscellaneous/machine-learning/guide-mel-frequency-cepstral-coefficients-mfccs/

[2]本文主要参考:cmu的教程:

http://www.speech.cs.cmu.edu/15-492/slides/03_mfcc.pdf

[3] C library for computing Mel Frequency Cepstral Coefficients (MFCC)

http://code.google.com/p/libmfcc/

梅尔频率倒谱系数(MFCC) 学习笔记的更多相关文章

  1. 语音信号的梅尔频率倒谱系数(MFCC)的原理讲解及python实现

    梅尔倒谱系数(MFCC) 梅尔倒谱系数(Mel-scale FrequencyCepstral Coefficients,简称MFCC).依据人的听觉实验结果来分析语音的频谱, MFCC分析依据的听觉 ...

  2. 语音频谱语音信号处理之(四)梅尔频率倒谱系数(MFCC)

    今天一直在查找语音频谱之类的问题,今天正好有机会和大家共享一下. 语音信号处置之(四)梅尔频率倒谱系数(MFCC) zouxy09@qq.com http://blog.csdn.net/zouxy0 ...

  3. 【VS开发】【智能语音处理】语音信号处理之(四)梅尔频率倒谱系数(MFCC)

    语音信号处理之(四)梅尔频率倒谱系数(MFCC) zouxy09@qq.com http://blog.csdn.net/zouxy09 这学期有<语音信号处理>这门课,快考试了,所以也要 ...

  4. 学习笔记TF059:自然语言处理、智能聊天机器人

    自然语言处理,语音处理.文本处理.语音识别(speech recognition),让计算机能够"听懂"人类语音,语音的文字信息"提取". 日本富国生命保险公司 ...

  5. Mel倒谱系数

    Mel倒谱系数:MFCC Mel频率倒谱系数(Mel Frequency Cepstrum Coefficient)的缩写是MFCC,Mel频率是基于人耳听觉特性提出来的,它与Hz频率成非线性对应关系 ...

  6. 转载: GMM-HMM学习笔记

    转载地址:http://blog.csdn.net/davidie/article/details/46929269 最近几天钻研了语音处理中的GMM-HMM模型,阅读了一些技术博客和学术论文,总算是 ...

  7. OpenCV之Python学习笔记

    OpenCV之Python学习笔记 直都在用Python+OpenCV做一些算法的原型.本来想留下发布一些文章的,可是整理一下就有点无奈了,都是写零散不成系统的小片段.现在看 到一本国外的新书< ...

  8. [学习笔记] 多项式与快速傅里叶变换(FFT)基础

    引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积, 而代码量却非常小. 博主一年半前曾经因COGS的一 ...

  9. 我的Android进阶之旅------>Android中编解码学习笔记

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...

随机推荐

  1. Dubbo源码导入Eclipse遇到的问题

    1.怎么将Dubbo源码导入到Eclipse 方法一: 打开Eclipse,File-->Import-->maven-->Exsting Maven Projects,选择dubb ...

  2. jdbc批处理

    批量处理允许将相关的SQL语句分组到批处理中,并通过对数据库的一次调用来提交它们,一次执行完成与数据库之间的交互. 一次向数据库发送多个SQL语句时,可以减少通信开销,从而提高性能. 不需要JDBC驱 ...

  3. 【markdown】使用 js 实现自己得markdown 网页编辑器

    首先从这里下载其浏览器版: https://github.com/evilstreak/markdown-js/releases 解压缩后在其js文件同目录下新建一个网页进行测试,代码如下: < ...

  4. java框架---->Xstream的使用(一)

    Xstream可以轻易的将Java对象和xml文档相互转换,而且可以修改某个特定的属性和节点名称.今天我们就简单的学习一下xstream的用法. Xstream的简单实例 项目的结构如下,设计到三个类 ...

  5. MQTT的学习研究(三)moquette-mqtt 的使用之mqtt服务发布主题信息

    接着上一篇的moquette-mqtt 的使用之broker启动之后,我们需要启动moquette-mqtt 的服务端发布消息. 在moquette-mqtt 的mqtt-client中三种方式实现发 ...

  6. Java虚拟机原理图解

    具体详情参考: http://blog.csdn.net/luanlouis/article/details/41046443 http://blog.csdn.net/luanlouis/artic ...

  7. office2010如何使用excel冻结窗格

    当我们在制作一个Excel表格时,如果列数较多,行数也较多时,一旦向下滚屏,则上面的标题行也跟着滚动,在处理数据时往往难以分清各列数据对应的标题,事实上利用"冻结窗格"功能可以很好 ...

  8. Android 判断当前是否在跑monkey测试

    /**     * Returns true if Monkey is running.     */    public static boolean isMonkeyRunning() {     ...

  9. CRUX下实现进程隐藏(1)

    想必能找到这里的都是被吴一民的操作系统大作业坑过的学弟学妹了,当初我也是千辛万苦才把这个作业完成了,本着服务后辈的宗旨,尽量让学弟学妹少走弯路,我会把实现的大概思路记录下来.本系列一共三篇文章,分别实 ...

  10. Minix2.0操作系统公用头文件说明

    以下头文件均在目录include/下: ansi.h: 用来检测编译器是否遵循标准C,如果是的话,_ANSI就被定义为31415,如果不是的,则_ANSI未定义.通过这个宏来诊测. limits.h: ...