什么是语谱图

语谱图(Spectrogam)是表示语音频谱随时间变化的图形,其实是一个二维的图像,但却能表示三个维度的信息,横坐标表示时间,纵坐标表示频率,颜色的深浅来映射能量的大小。任一给定频率成分在给定时刻的强弱用相应点的灰度或色调的浓淡来表示。颜色深,表示该点的语音能量越强,反之表示该点语音能量较弱。

绘制语谱图首先需要对载入的音频进行分帧和加窗处理,然后进行傅里叶变化,然后求出每一帧所对应的时间刻度,然后再将傅里叶变换后的数据取对数求出能量密度谱,将能量与颜色做一个映射,然后画出图像

分帧

语音信号是一个准稳态的信号,若把它分成较短的帧,每帧中可将其看做稳态信号,可用处理稳态信号的方法来处理。为了使一帧与另一帧之间的参数能够平稳过渡,应在相邻两帧之间互相有部分重叠。一般情况下,帧长取10 ~ 30ms,所以每秒的帧数约为33 ~ 100帧。帧移与帧长的比值一般取0~1/2。其中设每帧长度为win,后一帧对前一帧的位移量为inc。

因此设计分帧函数就是在函数名中给三个参数,enframe(x, win, inc),其中x为加载的音频数据,win为帧长,inc为帧移,返回值为分帧后的数据。

代码如下:

#分帧函数
def enframe(x, win, inc=None):''':param x: 音频数据:param win: 帧长:param inc: 帧移:return: 分帧后的列表'''nx = len(x)# 获取音频的长度if isinstance(win, list) or isinstance(win, np.ndarray):# 判断win是否为窗函数nwin = len(win)nlen = nwin  # 帧长=窗长elif isinstance(win, int):# 说明没有窗函数,将帧长设置为1nwin = 1nlen = win  # 设置为帧长if inc is None:# 帧移不为空则传给nleninc = nlennf = (nx - nlen + inc) // inc# 算出有多少帧frameout = np.zeros((nf, nlen))# 填充一个零矩阵出来,行为帧,列为帧数据indf = np.multiply(inc, np.array([i for i in range(nf)])) # 设置每帧在x中的位移量位置for i in range(nf):# 将数据分帧存在frameout中frameout[i, :] = x[indf[i]:indf[i] + nlen]return frameout

加窗

在语音处理中,经常可以听到对语音进行分帧和加窗的操作,那加窗到底是什么,为什么要加窗呢?语音信号是一种非平稳的时变信号,要进行FFT或其他针对平稳信号而进行的信号处理时就十分困难。加窗和分帧就类似与高等数学中求积分一样,将曲线分成无限个小格,每个格就可以等似为矩形。在语音处理中也是这样,通过分帧和加窗可以把语音信号在一帧内看作是短时平稳的,加窗其实就是对分帧后的每一帧数据s(n)s(n)s(n)分别乘上窗数据w(n)w(n)w(n),从而形成加窗语音信号sw(n)=s(n)∗w(n)s_w(n)=s(n) \ast w(n)sw​(n)=s(n)∗w(n)。常见的窗函数有矩形窗、海宁窗、汉明窗。

矩形窗的函数表达式为:
w(n)={1,0<=n<L−10,其他 w(n)=\left\{\begin{array}{ll} 1, & 0<=n<L-1 \\ 0, & \text { 其他 } \end{array}\right. w(n)={1,0,​0<=n<L−1 其他 ​

海宁窗的表达式为:
w(n)={0.5(1−cos⁡(2πn/(L−1)),0<=n<L−10,其他 w(n)=\left\{\begin{array}{ll} 0.5(1 - \cos (2 \pi n /(L-1)) , & 0<=n<L-1 \\ 0, & \text { 其他 } \end{array}\right. w(n)={0.5(1−cos(2πn/(L−1)),0,​0<=n<L−1 其他 ​

汉明窗的表达式为:
w(n)={0.54−0.46cos⁡(2πn/(L−1)),0<=n<L−10,其他 w(n)=\left\{\begin{array}{ll} 0.54-0.46 \cos (2 \pi n /(L-1)), & 0<=n<L-1 \\ 0, & \text { 其他 } \end{array}\right. w(n)={0.54−0.46cos(2πn/(L−1)),0,​0<=n<L−1 其他 ​

代码如下所示:

#加窗
def hanning(N):''':param N: 窗长度:return: 窗数据'''len = [i for i in range(N)]w = 0.5 * (1 - np.cos(np.multiply(len, 2 * np.pi) / (N - 1)))return w
def rectangular(N):''':param N: 窗长度:return: 窗数据'''len = [i for i in range(N)]w = np.ones(N)return w
def hamming(N):''':param N: 窗长度:return: 窗数据'''len = [i for i in range(N)]w = 0.54 - 0.46 * np.cos(np.multiply(len, 2 * np.pi) / (N - 1))return w

短时傅里叶变换

分帧和加窗之后再进行傅里叶变换就称作短时傅里叶变换,先将加窗后的数据进行转置,再调用fft()函数进行快速傅里叶变换,从而达到所需要的效果。

代码如下所示:

#短时傅里叶变换
def STFFT(x, nfft):''':param x: 需要fft变换的数据:param win: 窗长:param nfft: fft点数:param inc: 帧移:return: fft后的数据'''x = x.T#进行转置y = np.fft.fft(x, nfft, axis=0)#进行点数为nfft的fft变换return y[:nfft // 2, :]

生成语谱图

在进行完以上步骤后,我们还需要算出频率刻度,算出每一帧所对应的时间,再将傅里叶变换后的数据进行求取对数,调用pcolormesh()函数将三个维度的数据进行映射,从而可以用颜色来表示能量的强弱。

代码如下所示:

#绘制语谱图
#计算每帧对应的时间
def frametime(frameNum, frameLen, inc, fs):''':param frameNum: 帧数值:param frameLen: 帧长度:param inc: 帧移:param fs: 采样率:return:'''ll = np.array([i for i in range(frameNum)])return ((ll - 1) * inc + frameLen / 2) / fsdef spectrogram(filepath, wlen, inc, nfft, windows):''':param filepath: 音频文件路径:param wlen: 窗长度:param inc: 帧移:param nfft: fft点数:param win: 窗口类型:return:'''data, fs = librosa.load(filepath, sr=None, mono=False)  # sr=None声音保持原采样频率, mono=False声音保持原通道数# 分帧xn = enframe(data, wlen, inc)# 加窗if windows == "hanning":win = hanning(wlen)elif windows == "hamming":win = hamming(wlen)elif windows == "rectangular":win = rectangular(wlen)xn = xn * win# 短时傅里叶变换y = STFFT(xn, nfft)fre_scale = [i * fs / wlen for i in range(wlen // 2)]  # 频率刻度frameTime = frametime(y.shape[1], wlen, inc, fs)  # 每帧对应的时间abs_y = np.abs(y)spe_data = 10 * np.log10((abs_y * abs_y))  # 取对数后的数据plt.pcolormesh(frameTime, fre_scale, spe_data)plt.ylabel('Frequency')plt.xlabel('Time(s)')

这样语谱图就绘制好了,将自己生成的语谱图和调用librosa绘制的语谱图进行对比,fft点数均为256,如图\ref{4}所示,在Audition中绘制出语谱图与之对比,所画出的语谱图基本一致。

批量生成语谱图

用Python自动生成语谱图显然比自己一个个改文件路径要快得多,因此设计一个批处理文件,首先在文件中输入音频所在的文件夹路径,输入生成语谱图所需保存的路径,程序就会从文件夹中识别出.wav文件,将其路径传递给spectrogram()的filename形参,这样就可以绘制出语谱图,再用savefig()函数将其以原音频名的格式保存为**.pdf的矢量格式图,也可以改为其他png或者jpeg格式。
代码如下所示:

import os
import matplotlib.pyplot as plt
import function as fun
wlen = 1024
inc = 128
nfft = wlen
filepath = "F:/audio/"#输入文件所在的录音
filepathout = "F:/audio/语谱图/"#语谱图输出路径
wavelist = []
filenames = os.listdir(filepath)
for filename in filenames:name, category = os.path.splitext(filepath + filename)  # 分解文件扩展名if category == '.wav':  # 若文件为wav音频文件wavelist.append(filename)names, cat = os.path.splitext(filename)# print(names)#以下部分是绘制语谱图fun.spectrogram(filename, wlen, inc, nfft, windows="hanning")plt.savefig(fname = filepathout + names + ".pdf")plt.close()print("图片" + names + "生成成功")

不调包绘制音频语谱图并批量生成语谱图相关推荐

  1. python从语音生成语谱图

    python从语音生成语谱图 文章目录 python从语音生成语谱图 生成语谱图的过程 引入必要的库 语音生成语谱图 结果图 语音信号的原始数据 语音信号转为语谱图 生成语谱图的过程 参考文档 预增强 ...

  2. 使用神经网络中的卷积核生成语谱图

    主题思想: 正交基函数, sin,cos 是通过网络训练得到的参数. 使用一维卷积核直接对于原始音频,进行卷积生成语谱图: 使用一维卷积核生成语谱图特征, 不同于以往的方式,正是因为这些正交基函数是通 ...

  3. python实现绘制信号序列语谱图

    python实现绘制信号序列语谱图 功能:绘制信号序列语谱图 代码: import numpy as np # 导入音频及绘图显示包 import librosa.display # 导入绘图工作的函 ...

  4. 使用ComplexHeatmap包绘制个性化热图

    文章目录 使用ComplexHeatmap包绘制个性化热图 检测安装加载包 创建测试数据集 一行命令绘图 调参美化 猜你喜欢 写在后面 使用ComplexHeatmap包绘制个性化热图 作者:刘梦瑶 ...

  5. 数据可视化——R语言ggplot2包绘制相关矩阵为热图

    数据可视化--R语言ggplot2包绘制相关矩阵为热图 概述:R语言软件和数据可视化--ggplot2快速绘制相关矩阵为热图.本文翻译了一篇英文博客,博客原文链接:http://www.sthda.c ...

  6. php热图,科学网—使用ComplexHeatmap包绘制个性化热图 - 刘永鑫的博文

    使用ComplexHeatmap包绘制个性化热图 作者:刘梦瑶 诺禾致源 微生物信息 审稿:刘永鑫 中国科学院遗传与发育生物学研究所 ComplexHeatmap包由顾祖光博士创建,是一个非常全面的绘 ...

  7. 数据可视化——R语言ggplot2包绘制精美的小提琴图(并箱线图或误差条图组合)

    数据可视化--R语言ggplot2包绘制精美的小提琴图(并箱线图或误差条图组合) 概述:R语言使用ggplot2工具包绘制小提琴图.为了使数据表达更加丰富,同时将小提琴图与箱线图和误差条图相结合.另外 ...

  8. ComplexHeatmap包绘制热图(二)

    前面我介绍了如何利用ComplexHeatmap包绘制简单的热图,现在我们绘制一个稍微复杂一些的热图 首先还是配置数据 data=matrix(rnorm(100),nrow=10) colnames ...

  9. R语言使用table1包绘制(生成)三线表、使用单变量分列构建三线表、编写自定义三线表结构(将因子变量细粒度化重新构建三线图)、为不同的变量显示不同的统计信息

    R语言使用table1包绘制(生成)三线表.使用单变量分列构建三线表.编写自定义三线表结构(将因子变量细粒度化重新构建三线图).为不同的变量显示不同的统计信息 目录

最新文章

  1. linux日志idProduct,linux – 机器ID是uuid吗?
  2. Qt Dll总结——链接库预备知识(转载)
  3. 关于Android 隐藏 API 和内部 API的查看与使用
  4. 【信息抽取】如何使用卷积神经网络进行关系抽取
  5. 设计模式原则(单一、开放封闭、里氏代换、依赖倒转、迪米特法则五大原则)...
  6. fernflower idea内置的反编译工具
  7. 捕获异常_Recover捕获异常
  8. Android编程之指定ListView的item位置
  9. mysql优化20条原则
  10. 全站黑白悼念代码,几行代码全网站黑白色
  11. Springboot个人博客搭建(附源码)
  12. t分布 u分布 卡方分布_t分布曲线和正太分布,和z分布,和卡方分布,和方差分析的f分布曲线有什么区别?...
  13. 国产麒麟操作系统kylin V10 sp2操作系统安装openldap和kerberos
  14. USER_TAB_COLS,USER_TAB_COLUMNS,ALL_TAB_COLS,ALL_TAB_COLUMNS获取数据库元素的区别
  15. reporting php,php error_reporting函数怎么用
  16. faker.js生成手机号
  17. c语言多个附加说明符,C语言教程第三章.ppt
  18. 解决Linux服务器中TCP的FIN_WAIT2,CLOSE_WAIT状态连接过多的问题
  19. 九问 Gopher China 2020 讲师之毛康力:从 Go 1.0 使用至今的鲜肉老司机
  20. iOS----支付/银联/微信

热门文章

  1. 0基础快速入门CSS技术栈(3)—图解详细阐述CSS文字文本样式及综合案例、样式调试工具、快速开发html的emment语法(附详细案例源码解析过程)
  2. python学习:List和Turple
  3. C#创建文件写入及追加内容
  4. python中的编码方式
  5. php为什么没有npm,在phpstorm的terminal中输入npm显示不是内部或外部命令
  6. Arduino UNO原理图学习记录
  7. 华为、小米图片上传裁剪失败问题
  8. 设计模式--类图、实例代码
  9. 汽车融资租赁系统开发 | 互融云汽车融资租赁系统 实现全自动化流程管理
  10. 小米10pro第二个摄像头下面_小米10 Pro内部大公开!看看3999到底花得值不值