欢迎访问宙启技术站
智能推送

如何利用Python编程实现mfcc()函数来提取音频语音特征

发布时间:2023-12-24 06:51:52

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