在音频分析中绘制频谱图

plotting spectrogram in audio analysis

我正在使用神经网络进行语音识别。为此,我需要获取那些训练音频文件 (.wav) 的频谱图。如何在 python 中获取这些频谱图?

有很多方法可以做到这一点。最简单的是查看Kernels on Kaggle competition TensorFlow Speech Recognition Challenge (just sort by most voted). This one中提出的方法,特别清晰简单,包含以下功能。输入是从 wav 文件中提取的样本的数字向量、采样率、以毫秒为单位的帧大小、以毫秒为单位的步长(跨步或跳过)大小和一个小的偏移量。

from scipy.io import wavfile
from scipy import signal
import numpy as np

sample_rate, audio = wavfile.read(path_to_wav_file)

def log_specgram(audio, sample_rate, window_size=20,
                 step_size=10, eps=1e-10):
    nperseg = int(round(window_size * sample_rate / 1e3))
    noverlap = int(round(step_size * sample_rate / 1e3))
    freqs, times, spec = signal.spectrogram(audio,
                                    fs=sample_rate,
                                    window='hann',
                                    nperseg=nperseg,
                                    noverlap=noverlap,
                                    detrend=False)
    return freqs, times, np.log(spec.T.astype(np.float32) + eps)

输出在 SciPy manual 中定义,但使用单调函数 (Log()) 重新缩放频谱图除外,它比较小的值更能抑制较大的值,同时保留较大的值大于较小的值。这样,spec 中的极值将不会主导计算。或者,可以将值限制在某个分位数,但首选对数(甚至平方根)。还有许多其他方法可以标准化频谱图的高度,即防止 "bullying" 输出中的极值 :)

freq (f) : ndarray, Array of sample frequencies.
times (t) : ndarray, Array of segment times.
spec (Sxx) : ndarray, Spectrogram of x. By default, the last axis of Sxx corresponds to the segment times.

或者,您可以查看 github repo from the Tensorflow example on audio recognition 上的 train.py 和 models.py 代码。

Here is another thread 解释并给出了在 Python.

中构建频谱图的代码

您可以使用NumPySciPymatplotlib包来制作频谱图。请参阅以下 post。 http://www.frank-zalkow.de/en/code-snippets/create-audio-spectrograms-with-python.html

Scipy就是为了这个目的。

import scipy
# Read the .wav file
sample_rate, data = scipy.io.wavfile.read('directory_path/file_name.wav')

# Spectrogram of .wav file
sample_freq, segment_time, spec_data = signal.spectrogram(data, sample_rate)  
# Note sample_rate and sampling frequency values are same but theoretically they are different measures

使用 matplot 库可视化频谱图

import matplotlib.pyplot as plt
plt.pcolormesh(segment_time, sample_freq, spec_data )
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
plt.show()