语音识别--光谱门控降噪

⚠申明: 未经许可,禁止以任何形式转载,若要引用,请标注链接地址。 全文共计7267字,阅读大概需要3分钟
🌈更多学习内容, 欢迎👏关注👀【文末】我的个人微信公众号:不懂开发的程序猿
个人网站:https://jerry-jy.co/

❗❗❗知识付费,🈲止白嫖,有需要请后台私信或【文末】个人微信公众号联系我

语音识别--光谱门控降噪

  • 光谱门控降噪
    • 一、任务需求
    • 二、任务目标
          • 1、在噪声音频剪辑上计算 FFT
          • 2、通过噪声的 FFT 计算频率数据
          • 3、根据噪声的统计数据(以及算法的所需灵敏度)计算阈值
          • 4、对信号计算 FFT
          • 5、通过将信号 FFT 与阈值进行比较来确定掩膜
          • 6、使用滤波器在频率和时间上平滑掩膜
          • 7、掩码应用于信号的 FFT,并反转
    • 三、任务环境
          • 1、jupyter开发环境
          • 2、python3.6
          • 3、tensorflow2.4
    • 四、任务实施过程
      • 加载工具
      • 1、加载数据
      • 2、添加噪音
      • 3、去噪
    • 五、任务小结
  • 说明

光谱门控降噪


一、任务需求

本降噪方法使用了audacity的降噪方法

该降噪方法使用 Python 实现,可以降低语音、生物声学和生理信号等时域信号中的噪声。它依赖于一种称为“频谱门控”的方法,这是一种噪声门控方法。它的工作原理是计算信号(以及可选的噪声信号)的频谱图并估计该信号/噪声的每个频带的噪声阈值(或门)。该阈值用于计算掩码,该掩码将噪声选入频率变化阈值以下。

本方法要求两个输入:

原型噪声音频
要去除的信号

要求:使用audacity的降噪方法对音频进行降噪

二、任务目标

1、在噪声音频剪辑上计算 FFT
2、通过噪声的 FFT 计算频率数据
3、根据噪声的统计数据(以及算法的所需灵敏度)计算阈值
4、对信号计算 FFT
5、通过将信号 FFT 与阈值进行比较来确定掩膜
6、使用滤波器在频率和时间上平滑掩膜
7、掩码应用于信号的 FFT,并反转

三、任务环境

1、jupyter开发环境
2、python3.6
3、tensorflow2.4

四、任务实施过程

实验步骤

  1. 在噪声音频剪辑上计算 FFT
  2. 通过噪声的 FFT 计算频率数据
  3. 根据噪声的统计数据(以及算法的所需灵敏度)计算阈值
  4. 对信号计算 FFT
  5. 通过将信号 FFT 与阈值进行比较来确定掩码
  6. 使用过滤器在频率和时间上平滑蒙版
  7. 掩码应用于信号的 FFT,并反转

加载工具

import IPython
from scipy.io import wavfile
import scipy.signal
import numpy as np
import matplotlib.pyplot as plt
import librosa
%matplotlib inline

1、加载数据

原始语音内容如下:

"I know the human being and fish can coexist peacefully."– Saginaw, Michigan, September 29, 2000
wav_loc = "/home/jovyan/datas/fish.wav"
rate, data = wavfile.read(wav_loc)
data = data / 32768
IPython.display.Audio(data=data, rate=rate)
fig, ax = plt.subplots(figsize=(20,4))
ax.plot(data)

[<matplotlib.lines.Line2D at 0x7f564b8feb00>]

在这里插入图片描述
上图显示的是该语音对应的波形,横坐标是采样点

2、添加噪音

定义噪声生成器

  • 使用快速傅里叶变换生成噪声
  • 生成带限噪声
def fftnoise(f):f = np.array(f, dtype="complex")Np = (len(f) - 1) // 2phases = np.random.rand(Np) * 2 * np.piphases = np.cos(phases) + 1j * np.sin(phases)f[1 : Np + 1] *= phasesf[-1 : -1 - Np : -1] = np.conj(f[1 : Np + 1])return np.fft.ifft(f).realdef band_limited_noise(min_freq, max_freq, samples=1024, samplerate=1):freqs = np.abs(np.fft.fftfreq(samples, 1 / samplerate))f = np.zeros(samples)f[np.logical_and(freqs >= min_freq, freqs <= max_freq)] = 1return fftnoise(f)

生成噪声,并在原始音频上添加噪声

noise_len = 2 # 单位:秒
# 使用自定义函数生成噪声
noise = band_limited_noise(min_freq=4000, max_freq = 12000, samples=len(data), samplerate=rate)*30
# 将噪声裁剪成和原始音频同样长
noise_clip = noise[:rate*noise_len]
# 将噪声与原始音频叠加
audio_clip_band_limited = data+noise

演示添加噪声后的音频数据

fig, ax = plt.subplots(figsize=(20,4))
ax.plot(audio_clip_band_limited)
IPython.display.Audio(data=audio_clip_band_limited, rate=rate)

在这里插入图片描述
可以看到,添加噪声以后,声音的波形明显受到干扰,听起来也不够清楚。

3、去噪

自定义相关函数,用于降噪及演示降噪的过程

import time
from datetime import timedelta as td# 短时傅立叶变换
def _stft(y, n_fft, hop_length, win_length):return librosa.stft(y=y, n_fft=n_fft, hop_length=hop_length, win_length=win_length)# 逆短时傅立叶变换
def _istft(y, hop_length, win_length):return librosa.istft(y, hop_length, win_length)# 将幅度谱图转换为 dB 标度的谱图。
def _amp_to_db(x):return librosa.core.amplitude_to_db(x, ref=1.0, amin=1e-20, top_db=80.0)# 将 dB 标度的谱图转换为幅度谱图。
def _db_to_amp(x,):return librosa.core.db_to_amplitude(x, ref=1.0)# 绘制频谱图
def plot_spectrogram(signal, title):fig, ax = plt.subplots(figsize=(20, 4))cax = ax.matshow(signal,origin="lower",aspect="auto",cmap=plt.cm.seismic,vmin=-1 * np.max(np.abs(signal)),vmax=np.max(np.abs(signal)),)fig.colorbar(cax)ax.set_title(title)plt.tight_layout()plt.show()# 绘制统计量及滤波器
def plot_statistics_and_filter(mean_freq_noise, std_freq_noise, noise_thresh, smoothing_filter
):fig, ax = plt.subplots(ncols=2, figsize=(20, 4))plt_mean, = ax[0].plot(mean_freq_noise, label="Mean power of noise")plt_std, = ax[0].plot(std_freq_noise, label="Std. power of noise")plt_std, = ax[0].plot(noise_thresh, label="Noise threshold (by frequency)")ax[0].set_title("Threshold for mask")ax[0].legend()cax = ax[1].matshow(smoothing_filter, origin="lower")fig.colorbar(cax)ax[1].set_title("Filter for smoothing Mask")plt.show()# 定义降噪函数
def removeNoise(audio_clip,noise_clip,n_grad_freq=2,n_grad_time=4,n_fft=2048,win_length=2048,hop_length=512,n_std_thresh=1.5,prop_decrease=1.0,verbose=False,visual=False,
):"""根据仅包含噪声的剪辑从音频中去除噪声参数:audio_clip(数组):第一个参数。noise_clip(数组):第二个参数。n_grad_freq (int):使用掩码平滑处理多少个频率通道。n_grad_time (int):用掩码平滑的时间通道数。n_fft (int):STFT 列之间的帧数。win_length (int): 每帧音频都被 window() 窗口化。窗口的长度为“win_length”,然后用零填充以匹配“n_fft”。hop_length (int):STFT 列之间的帧数。n_std_thresh (int):比噪声的平均 dB(在每个频率级别)大多少个标准偏差被视为信号prop_decrease (float): 你应该在多大程度上减少噪音(1 = 全部,0 = 无)visual (bool): 是否绘制算法的步骤返回:数组:减去噪声的恢复信号"""if verbose:start = time.time()# 对噪声应用短时傅里叶变换noise_stft = _stft(noise_clip, n_fft, hop_length, win_length)noise_stft_db = _amp_to_db(np.abs(noise_stft))  # 转换为dB频谱# 对噪声计算均值、标准差统计量mean_freq_noise = np.mean(noise_stft_db, axis=1)std_freq_noise = np.std(noise_stft_db, axis=1)noise_thresh = mean_freq_noise + std_freq_noise * n_std_threshif verbose:print("STFT on noise:", td(seconds=time.time() - start))start = time.time()# 对信号应用短时傅里叶变换if verbose:start = time.time()sig_stft = _stft(audio_clip, n_fft, hop_length, win_length)sig_stft_db = _amp_to_db(np.abs(sig_stft))if verbose:print("STFT on signal:", td(seconds=time.time() - start))start = time.time()# 计算dB频谱掩码mask_gain_dB = np.min(_amp_to_db(np.abs(sig_stft)))print(noise_thresh, mask_gain_dB)# 在时间和频率上为掩码创建平滑过滤器smoothing_filter = np.outer(np.concatenate([np.linspace(0, 1, n_grad_freq + 1, endpoint=False),np.linspace(1, 0, n_grad_freq + 2),])[1:-1],np.concatenate([np.linspace(0, 1, n_grad_time + 1, endpoint=False),np.linspace(1, 0, n_grad_time + 2),])[1:-1],)smoothing_filter = smoothing_filter / np.sum(smoothing_filter)# 计算每个频率/时间窗的阈值db_thresh = np.repeat(np.reshape(noise_thresh, [1, len(mean_freq_noise)]),np.shape(sig_stft_db)[1],axis=0,).T# 如果信号高于阈值则屏蔽sig_mask = sig_stft_db < db_threshif verbose:print("Masking:", td(seconds=time.time() - start))start = time.time()# 使用平滑滤波器对掩码进行卷积sig_mask = scipy.signal.fftconvolve(sig_mask, smoothing_filter, mode="same")sig_mask = sig_mask * prop_decreaseif verbose:print("Mask convolution:", td(seconds=time.time() - start))start = time.time()# 对信号应用掩码sig_stft_db_masked = (sig_stft_db * (1 - sig_mask)+ np.ones(np.shape(mask_gain_dB)) * mask_gain_dB * sig_mask)  # 对真实值进行掩码sig_imag_masked = np.imag(sig_stft) * (1 - sig_mask)sig_stft_amp = (_db_to_amp(sig_stft_db_masked) * np.sign(sig_stft)) + (1j * sig_imag_masked)if verbose:print("Mask application:", td(seconds=time.time() - start))start = time.time()# 修复信号recovered_signal = _istft(sig_stft_amp, hop_length, win_length)recovered_spec = _amp_to_db(np.abs(_stft(recovered_signal, n_fft, hop_length, win_length)))if verbose:print("Signal recovery:", td(seconds=time.time() - start))if visual:plot_spectrogram(noise_stft_db, title="Noise")if visual:plot_statistics_and_filter(mean_freq_noise, std_freq_noise, noise_thresh, smoothing_filter)if visual:plot_spectrogram(sig_stft_db, title="Signal")if visual:plot_spectrogram(sig_mask, title="Mask applied")if visual:plot_spectrogram(sig_stft_db_masked, title="Masked signal")if visual:plot_spectrogram(recovered_spec, title="Recovered spectrogram")return recovered_signal

output = removeNoise(audio_clip=audio_clip_band_limited, noise_clip=noise_clip,verbose=True,visual=True)

上图依次为我们演示了:

  • 噪声的频谱图
  • 计算的掩膜的阈值
  • 用于平滑掩膜的滤波器
  • 原始信号对应的频谱图
  • 计算得到的掩膜频谱图
  • 经过掩膜处理的信号频谱图
  • 经过恢复后的声音信号频谱图

最后我们观察一下降噪以后得到的声音结果

fig, ax = plt.subplots(nrows=1,ncols=1, figsize=(20,4))
plt.plot(output, color='black')
ax.set_xlim((0, len(output)))
plt.show()
# 播放声音样本
IPython.display.Audio(data=output, rate=44100)

在这里插入图片描述

五、任务小结

本实验完成光谱门控降噪方法对声音进行降噪处理。通过本实验我们学习到了光谱门控降噪的相关知识,需要掌握以下知识点:

  • 通过噪声的傅里叶变换计算得到噪声相关特征
  • 通过对信号计算傅里叶变换,确定阈值,从而确定掩膜/掩码
  • 对声音掩膜应用滤波器,实现降噪

–end–

说明

本实验(项目)/论文若有需要,请后台私信或【文末】个人微信公众号联系我

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3015877.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

FSC森林认证是什么?

FSC森林认证&#xff0c;又称木材认证&#xff0c;是一种运用市场机制来促进森林可持续经营&#xff0c;实现生态、社会和经济目标的工具。FSC森林认证包括森林经营认证&#xff08;Forest Management, FM&#xff09;和产销监管链认证&#xff08;Chain of Custody, COC&#…

使用IIS部署Vue项目

前提 使用IIS部署Vue项目&#xff0c;后端必须跨域&#xff0c;不要在Vue中用proxy跨域&#xff0c;那个只在dev环境中有用&#xff01; IIS安装&#xff0c;不用全部打勾&#xff0c;有些他默认就是方块 ■ 选择性安装的&#xff0c;就维持原样就可以。 添加网站配置 右键…

Ecovadis认证是什么?

Ecovadis认证是一种企业社会责任&#xff08;CSR&#xff09;评估和评级的认证&#xff0c;旨在衡量企业在环境、劳工和人权、道德以及可持续采购四个方面的可持续发展表现。该认证已成为全球范围内许多公司和组织的评估标准之一&#xff0c;有助于提高企业的会声誉和可持续发展…

Redis系列之key过期策略介绍

为什么要有过期策略&#xff1f; Redis是一个内存型的数据库&#xff0c;数据是放在内存里的&#xff0c;但是内存也是有大小的&#xff0c;所以&#xff0c;需要配置redis占用的最大内存&#xff0c;主要通过maxmemory配置 maxmomory <bytes> # redis占用的最大内存官…

Pycharm无法链接服务器环境(host is unresponsived)

困扰了很久的一个问题&#xff0c;一开始是在服务器ubuntu20.04上安装pycharm community&#xff0c;直接运行服务器上的pycharm community就识别不了anaconda中的环境 后来改用pycharm professional也无法远程连接上服务器的环境&#xff0c;识别不了服务器上的环境&#xff…

Nessus 部署实验

一、下载安装https://www.tenable.com/downloads/nessus 安装好之后&#xff0c;Nessus会自动打开浏览器&#xff0c;进入到初始化选择安装界面&#xff0c;这里我们要选择 Managed Scanner 点击继续&#xff0c;下一步选择Tenable.sc 点击继续&#xff0c;设置用户名和密码 等…

2024DCIC海上风电出力预测Top方案 + 光伏发电出力高分方案学习记录

海上风电出力预测 赛题数据 海上风电出力预测的用电数据分为训练组和测试组两大类&#xff0c;主要包括风电场基本信息、气象变量数据和实际功率数据三个部分。风电场基本信息主要是各风电场的装机容量等信息&#xff1b;气象变量数据是从2022年1月到2024年1月份&#xff0c;…

翻译《The Old New Thing》- Rendering menu glyphs is slightly trickier

Rendering menu glyphs is slightly trickier - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20050802-13/?p34743 Raymond Chen 2005年08月02日 上次&#xff0c;我们看到了如何绘制有主题和无主题的单选按钮&#xff0c;我提到菜单位图更…

cmake进阶:目录属性说明一

一. 简介 接下来简单学习一下 cmake 中的属性相关的概念。 属性大概可以分为多种&#xff1a;全局属性、目录属性&#xff08;源码属性&#xff09;、目标属性以及其它一些分类。 二. cmake进阶&#xff1a;目录属性 cmake中的属性可以 在如下网址查询到&#xff1a; http…

【深度学习实战(33)】训练之model.train()和model.eval()

一、model.train()&#xff0c;model.eval()作用&#xff1f; model.train() 和 model.eval() 是 PyTorch 中的两个方法&#xff0c;用于设置模型的训练模式和评估模式。 model.train() 方法将模型设置为训练模式。在训练模式下&#xff0c;模型会启用 dropout 和 batch norm…

python爬虫学习------scrapy第三部分(第三十一天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

ttkbootstrap界面美化系列之PanedWindow(七)

在界面设计中经常用PanedWindow控件来对整个界面进行切割布局&#xff0c;让整个界面看上去有层次感&#xff0c;不至于说杂乱无章。在我之前的文章中有对tkinter的该控件做了详细的介绍&#xff0c;链接如下基于Tkinter的PanedWindow组件进行窗口布局-CSDN博客 本文主要是介绍…

MapReduce的Shuffle过程

Shuffle是指从 Map 产生输出开始,包括系统执行排序以及传送Map输出到Reduce作为输入的过程. Shuffle 阶段可以分为 Map 端的 Shuffle 阶段和 Reduce 端的 Shuffle 阶段. Shuffle 阶段的工作过程,如图所示: Map 端的 Shuffle 阶段 1&#xff09;每个输入分片会让一个 Map 任务…

Linux学习之路 -- 文件 -- 文件描述符

前面介绍了与文件相关的各种操作&#xff0c;其中的各个接口都离不开一个整数&#xff0c;那就是文件描述符&#xff0c;本文将介绍文件描述符的一些相关知识。 目录 <1>现象 <2>原理 文件fd的分配规则和利用规则实现重定向 <1>现象 我们可以先通过prin…

04_SpringCloud

文章目录 单体架构与微服务架构的介绍单体架构微服务架构 微服务的实现服务之间的调用服务注册中心Eureka 注册中心Eureka的自我保护机制Nacos注册中心 单体架构与微服务架构的介绍 单体架构 单体架构 所有的代码最终打包成一个文件(jar包)&#xff0c;整个系统的所有功能单元…

爆赞好文之java反序列化之CB超详细易懂分析

java反序列化之CB超详细易懂分析 CB1环境搭建前言分析PropertyUtilsBeanComparatorPriorityQueue CB2环境搭建前言exp CB1 环境搭建 pom.xml <dependencies><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils&l…

生成gitee公钥

1、打开设置 2、设置SSH公钥 3、生成公钥 4、复制终端输出的公钥&#xff0c;放到这里&#xff0c;标题随便取。 5、测试 ssh -T gitgitee.com 最后用这个测试

IT 项目管理介绍和资料汇总

IT项目管理到底是什么&#xff1f;是对组织承担的任何信息技术项目的成功监督。IT项目经理负责规划、预算、执行、领导、故障排除和维护这些项目。IT项目经理可能会做的事情包括&#xff1a; 1、硬件安装 2、软件、网站和应用程序开发 3、网络和云计算解决方案的升级和/或推出…

软考中级-软件设计师(八)算法设计与分析 考点最精简

一、算法设计与分析的基本概念 1.1算法 算法&#xff08;Algorithm&#xff09;是对特定问题求解步骤的一种描述&#xff0c;有5个重要特性&#xff1a; 有穷性&#xff1a;一个算法必须总是在执行又穷步骤后结束&#xff0c;且每一步都可在又穷时间内完成 确定性算法中每一…