频域特征-Fbank

摘要:
Fbank是一种前端处理方法,以类似人类耳朵的方式处理音频,可以提高语音识别的性能。fbank的计算过程与谱图的计算过程相似。唯一的区别是添加了Mel滤波器,以使获得的特征更接近人类的耳朵特征。您可以参考Mel过滤器的相关内容https://mp.weixin.qq.com/s/pGwO_27x8ddQF55wTSQlmA 。 接下来,我们将介绍fbank的计算过程。

Fbank是一种前端处理方法,以类似人耳的方式对音频进行处理,可以提高语音识别的性能。fbank的计算流程与语谱图类似,唯一的区别就在于加了个Mel滤波器,从而使得得到的特征更逼近人耳特性。有关于Mel滤波器的相关内容可以查阅https://mp.weixin.qq.com/s/pGwO_27x8ddQF55wTSQlmA。接下来就介绍一下fbank的求取过程。
• 预加重
因为语音信号的功率谱随频率的增加而减小,因此导致语音的大部分能量都集中在低频部分,从而导致高频部分的信噪比很低。因此一般使用一阶高通滤波器去提升信号在高频部分的信噪比。

def preemphasis(signal, coeff=0.95):
    return np.append(signal[1], signal[1:] - coeff * signal[:-1])

• 分帧及加窗
有关分帧的具体原理可以参见https://mp.weixin.qq.com/s/PKBZgFXicNHghb39iyPfow。

def frame_sig(sig, frame_len, frame_step, win_func):
    '''
    :param sig: 输入的语音信号
    :param frame_len: 帧长
    :param frame_step: 帧移
    :param win_func: 窗函数
    :return: array of frames, num_frame * frame_len
    '''
    slen = len(sig)
    if slen <= frame_len:
        num_frames = 1
    else:
        # np.ceil(), 向上取整
        num_frames = 1 + int(np.ceil((slen - frame_len) / frame_step))
    padlen = int( (num_frames - 1) * frame_step + frame_len)
    # 将信号补长,使得(slen - frame_len) /frame_step整除
    zeros = np.zeros((padlen - slen,))
    padSig = np.concatenate((sig, zeros))
    indices = np.tile(np.arange(0, frame_len), (num_frames, 1)) + np.tile(np.arange(0, num_frames*frame_step, frame_step), (frame_len, 1)).T
    indices = np.array(indices, dtype=np.int32)
    frames = padSig[indices]
    win = np.tile(win_func(frame_len), (num_frames, 1))
    return frames * win

• FFT
对提取出来的帧信号进行傅里叶变换

complex_spec = np.fft.rfft(frames, NFFT)

• 幅值平方

np.square(np.abs(complex_spec))

• Mel滤波器
在先前的章节中,已经介绍了Mel滤波器的求法,在此不再赘述。具体可参考https://mp.weixin.qq.com/s/pGwO_27x8ddQF55wTSQlmA。

def filterbank(nfilt=40, nfft=512, samplerate=16000, lowfreq=20, highfreq=None):
    low_freq = lowfreq
    if highfreq is None:
        highfreq = samplerate // 2
    low_mel = hz2mel(low_freq)
    high_mel = hz2mel(highfreq)
    mel_points = np.linspace(low_mel, high_mel, nfilt + 2)
    binf = np.floor((nfft + 1) * mel2hz(mel_points) / samplerate)
    fbank = np.zeros([nfilt, int(nfft / 2 + 1)])
    for indexj in range(0, nfilt):
        left = binf[indexj]
        center = binf[indexj + 1]
        right = binf[indexj + 2]
        for indexi in range(int(left), int(center)):
            fbank[indexj, indexi] = (indexi - left) / ( center - left)
        for indexi in range(int(center), int(right)):
            fbank[indexj, indexi] = (right - indexi) / ( right -center)
    return fbank

• 对数功率

librosa.power_to_db(feature.T)

然后就能得到fbank特征。完整的代码如下

import numpy as np
import soundfile as sf
import python_speech_features as psf
import librosa
import librosa.display
import matplotlib.pyplot as plt
def frame_sig(sig, frame_len, frame_step, win_func):
    '''
    :param sig: 输入的语音信号
    :param frame_len: 帧长
    :param frame_step: 帧移
    :param win_func: 窗函数
    :return: array of frames, num_frame * frame_len
    '''
    slen = len(sig)
    if slen <= frame_len:
        num_frames = 1
    else:
        # np.ceil(), 向上取整
        num_frames = 1 + int(np.ceil((slen - frame_len) / frame_step))
    padlen = int( (num_frames - 1) * frame_step + frame_len)
    # 将信号补长,使得(slen - frame_len) /frame_step整除
    zeros = np.zeros((padlen - slen,))
    padSig = np.concatenate((sig, zeros))
    indices = np.tile(np.arange(0, frame_len), (num_frames, 1)) + np.tile(np.arange(0, num_frames*frame_step, frame_step), (frame_len, 1)).T
    indices = np.array(indices, dtype=np.int32)
    frames = padSig[indices]
    win = np.tile(win_func(frame_len), (num_frames, 1))
    return frames * win
def preemphasis(signal, coeff=0.95):
    return np.append(signal[1], signal[1:] - coeff * signal[:-1])
def pow_spec(frames, NFFT):
    complex_spec = np.fft.rfft(frames, NFFT)
    return 1 / NFFT * np.square(np.abs(complex_spec))
def hz2mel(hz):
    return 2595 * np.log10(1 + hz / 700.)
def mel2hz(mel):
    return 700 * (10 ** (mel / 2595.0) - 1)
def filterbank(nfilt=40, nfft=512, samplerate=16000, lowfreq=20, highfreq=None):
    low_freq = lowfreq
    if highfreq is None:
        highfreq = samplerate // 2
    low_mel = hz2mel(low_freq)
    high_mel = hz2mel(highfreq)
    mel_points = np.linspace(low_mel, high_mel, nfilt + 2)
    binf = np.floor((nfft + 1) * mel2hz(mel_points) / samplerate)
    fbank = np.zeros([nfilt, int(nfft / 2 + 1)])
    for indexj in range(0, nfilt):
        left = binf[indexj]
        center = binf[indexj + 1]
        right = binf[indexj + 2]
        for indexi in range(int(left), int(center)):
            fbank[indexj, indexi] = (indexi - left) / ( center - left)
        for indexi in range(int(center), int(right)):
            fbank[indexj, indexi] = (right - indexi) / ( right -center)
    return fbank
y, sr = sf.read('q1.wav')
'预加重'
y = preemphasis(y, coeff=0.98)
'分帧'
frames = frame_sig(y, frame_len=2048, frame_step= 512, win_func=np.hanning)
features = pow_spec(frames, NFFT=2048)
nfilt = 26
nfft = 2048
fb = filterbank(nfilt, nfft, sr, lowfreq=20, highfreq=sr // 2)
feature = np.dot(features, fb.T)
librosa.display.specshow(librosa.power_to_db(feature.T),sr=sr, x_axis='time', y_axis='linear')
plt.title('Spectrogram')
plt.colorbar(format='%+2.0f dB')
plt.tight_layout()
plt.show()

频域特征-Fbank第1张

免责声明:文章转载自《频域特征-Fbank》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇润乾报表之参数调用为什么阿里规定需要在事务注解@Transactional中指定rollbackFor?下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

整体二分

关于整体二分的学习其实只是了解了普通二分之后自然就懂了整体二分了。没有很难但是基于整体二分是基于时间和值域的分治。 比CDQ要更强一点。因为可以在一些离线的题目当中代替树套树什么的。 同时也非常的好写 。至少代码好懂。 首先是值域上的二分 这个二分是分离不同的值毕竟不同的值在不同的区间之内。我们可以将其二分。但是单次二分也是可以得到整体的信息的不妨把所有的...

cjson库的使用以及源码阅读

cjson是一个用c语言开发的json解析库,免费开源只有一个c文件和一个h文件。json和xml功能相似,可以用来传输数据,存储数据以及表达程序当前的状态。 1、下载cjson的源码         https://github.com/DaveGamble/cJSON 2、阅读readme文件可以大概的了解一下cjson的介绍以及使用方法,我尝试着把...

MySQL基础

一、MySQL概述 1、什么是数据库 ?答:数据的仓库,如:在ATM的示例中我们创建了一个 db 目录,称其为数据库 2、什么是 MySQL、Oracle、SQLite、Access、MS SQL Server等 ?答:他们均是一个软件,都有两个主要的功能: a. 将数据保存到文件或内存b. 接收特定的命令,然后对文件进行相应的操作3、什么是SQL ?答:...

幸运拼系统代码幸运拼团系统源码分享

幸运拼系统逻辑描述 以下内容是分享的幸运拼团系统的模式逻辑流程和部分核心代码,为了让大家便于理解,系统核心代码已为分享给大家,大家可以自行分析,幸运拼团系统开发技术微信交流:15889726201,欢迎探讨 一,拼团产品区  幸运拼系统的后台可以设置多个拼团产品,并根据拼团产品的价格设置价格专区,每个专区都有多种产品,会员可以根据自己的需求选择不同的商品进...

react 实现圆环进度条

import React, { useState, useEffect } from "react" import { css } from "emotion" //num是从父级传来的百分比数值 export default function({ num }) { let rightTrnas = css` transform: rotate(0deg)...

Python 基础入门 10_3 进程线程和协程

"""线程一共有5个状态:创建,就绪/可运行状态,运行,阻塞/等待,完成/死亡当线程创建出来后,就进入了可运行状态,等线程启动后,便到了运行阶段,运行完后,便会完成销毁或者运行的过程中异常导致中途退出Semaphore()和Barrier()的实现:上述代码我们同时创建了5个线程并启动,这5个线程执行函数时,遇到了Semaphore或Barrier的函数,...