如何利用Python编程实现mfcc()函数来提取音频语音特征
1. 什么是MFCC?
MFCC(Mel Frequency Cepstral Coefficients)是一种常用的音频语音特征提取方法。它将音频波形图转化为频谱图,并计算出频谱图的能量分布,然后针对能量分布进行梅尔滤波器组的频率划分,最后再进行离散余弦变换(DCT)得到最终的MFCC系数。
2. MFCC函数的实现及使用例子
下面是一个利用Python编程实现MFCC函数的示例代码,并给出了一个使用例子。
import numpy as np
import scipy.io.wavfile as wav
from scipy.fftpack import dct
# 计算MFCC
def mfcc(signal, sample_rate=16000, num_filters=26, num_ceps=13, low_freq=0, high_freq=None):
# 1. 预处理: 加窗
frame_size = 0.025
frame_stride = 0.01
window = np.hamming(int(frame_size * sample_rate))
signal_length = len(signal)
frame_length = int(frame_size * sample_rate)
frame_step = int(frame_stride * sample_rate)
num_frames = int(np.ceil(float(np.abs(signal_length - frame_length)) / frame_step))
pad_signal_length = num_frames * frame_step + frame_length
z = np.zeros((pad_signal_length - signal_length))
pad_signal = np.append(signal, z)
indices = np.tile(np.arange(0, frame_length), (num_frames, 1)) + np.tile(
np.arange(0, num_frames * frame_step, frame_step), (frame_length, 1)).T
frames = pad_signal[indices.astype(np.int32, copy=False)]
# 2. 计算能量谱
frames *= window
mag_frames = np.absolute(np.fft.rfft(frames, num_filters)) # 快速傅里叶变化(FFT)
pow_frames = ((1.0 / num_filters) * (mag_frames ** 2))
# 3. 梅尔刻度滤波器组
low_freq_mel = 0
high_freq_mel = (2595 * np.log10(1 + (sample_rate / 2) / 700))
mel_points = np.linspace(low_freq_mel, high_freq_mel, num_filters + 2)
hz_points = (700 * (10 ** (mel_points / 2595) - 1))
bin = np.floor((frame_length + 1) * hz_points / sample_rate).astype(int)
filters = np.zeros((num_filters, int(np.floor(frame_length / 2 + 1))))
for m in range(1, num_filters + 1):
filters[m - 1, bin[m - 1]:bin[m]] = (hz_points[m] - hz_points[m - 1]) / (bin[m] - bin[m - 1])
filters[m - 1, bin[m]:bin[m + 1]] = (hz_points[m + 1] - hz_points[m]) / (bin[m + 1] - bin[m])
# 4. 应用滤波器组,计算离散余弦变换(DCT)
filter_banks = np.dot(pow_frames, filters.T)
filter_banks = np.where(filter_banks == 0, np.finfo(float).eps, filter_banks)
filter_banks = 20 * np.log10(filter_banks) # dB
dct_type = 2 # 选择DCT的类型
cepstral_coefficents = dct(filter_banks, type=dct_type, axis=1, norm='ortho')[:, :num_ceps]
# 5. 能量归一化
lifter = 22
(nframes, ncoeff) = cepstral_coefficents.shape
n = np.arange(ncoeff)
lift = 1 + (lifter / 2) * np.sin(np.pi * n / lifter)
cepstral_coefficents *= lift
# 6. 去除第0个系数
cepstral_coefficents[:, 0] = 0
return cepstral_coefficents
# 使用MFCC函数提取音频特征
sample_rate, signal = wav.read('speech.wav')
mfcc_features = mfcc(signal, sample_rate)
print(mfcc_features.shape)
首先,导入需要的库,包括numpy、scipy.io.wavfile(用于读取.wav音频文件)和scipy.fftpack.dct(用于计算离散余弦变换)。
然后,定义了一个mfcc()函数,该函数的参数包括音频信号(signal)、采样率(sample_rate)、滤波器组数量(num_filters)、mfcc系数数量(num_ceps)、低频率(low_freq)和高频率(high_freq)。
函数中的代码主要分为六个步骤:
1. 预处理:对音频信号进行加窗处理,将音频信号切分为帧,并用零填充音频信号长度。
2. 计算能量谱:对每个帧应用快速傅里叶变换(FFT),并计算能量谱。
3. 梅尔刻度滤波器组:计算梅尔刻度的频率范围,并将频率映射到滤波器组中的相应位置。
4. 应用滤波器组和离散余弦变换(DCT):将能量谱通过滤波器组进行滤波,并应用离散余弦变换。
5. 能量归一化:对MFCC系数进行能量归一化,以减小对能量变化的敏感性。
6. 去除第0个系数:去除第0个MFCC系数,因为该系数代表总能量,不包含有关声音的信息。
在使用例子中,我们使用wav.read()函数读取名为“speech.wav”的音频文件,得到采样率和音频信号。然后,调用mfcc()函数提取特征,并打印出特征的形状。
注意:在运行代码之前,请确保已安装所需的库,并将音频文件"speech.wav"放在同一目录下。
参考资料:
1. 原始代码及解释:https://digitalsoundandmusic.com/2019/07/25/how-to-extract-audio-features-like-mfcc-are-used-for-speech-recognition-in-python/
2. Mel频率: https://en.wikipedia.org/wiki/Mel_scale
3. DCT: https://en.wikipedia.org/wiki/Discrete_cosine_transform
