[简单实践]Noisy Print - 自制基于加性噪声模型的简易降噪器

NoisyPrint

最近在学习的过程中,突然想起一个在Adobe Audition中用过的功能。

为什么会想到这个功能呢,因为在我使用DeepFilter的过程中,我发现对于一些低信噪比的信号来说,DeepFilter很容易出现过拟合现象,导致音源的过度失真。那么有没有什么好办法解决这个问题呢?答案当然是有的,就是这个采样部分噪音,然后在频域上进行相减的方法。

项目地址,持续更新欢迎Star Github : LeventureQys/NoisyPrint

原理

1. 加性噪声模型

在信号处理领域,含噪声的信号通常可以被建模为:

x ( t ) = s ( t ) + n ( t ) x(t) = s(t) + n(t) x(t)=s(t)+n(t)

  • x(t):观测到的含噪声信号
  • s(t):原始干净信号
  • n(t):噪声信号

这个模型假设噪声是加性的,并且与原始信号不相关。

2. 频域中的表示

通过短时傅里叶变换(STFT),将时域信号转换到频域:

X ( ω ) = S ( ω ) + N ( ω ) X(\omega) = S(\omega) + N(\omega) X(ω)=S(ω)+N(ω)

  • X ( ω ) X(\omega) X(ω):含噪声信号的频谱
  • S ( ω ) S(\omega) S(ω): 原始信号的频谱
  • N ( ω ) N(\omega) N(ω): 噪声信号的频谱

这意味着在频域中,信号的频谱是线性叠加的。

综上

我们可以直接反过来计算,得到我们的 S ( ω ) S(\omega) S(ω) 然后在进行反傅里叶变换,获得时域信息。

总结流程:

  • 1.采集噪声样本并建立噪声频谱模型
  • 2.将含噪声的音频信号分帧处理
  • 3.对每一帧进行窗函数处理
  • 4.对窗化后的帧进行快速傅里叶变换(FFT)
  • 5.从信号的频谱中减去噪声频谱
  • 6.处理频谱减法后的负值和伪影
  • 7.进行逆快速傅里叶变换(IFFT)重建时域信号
  • 8.通过重叠相加(Overlap-Add)方法重建完整的信号
  • 9.后处理,如频谱平滑

实操:

1.采集噪声样本并建立噪声频谱模型

这一段我直接使用Audition进行的,具体不表,总之是两段音频,分别是全音频和纯噪音

原始音频:

纯噪音:

可以看得到,这音频中明显是有比较强烈的噪音的。

2. 3. 4.

这部分暂且不表,详情见下方代码:

import numpy as np
import scipy.io.wavfile as wav
import matplotlib.pyplot as plt
from scipy.signal import get_window
from scipy.fftpack import fft, ifft# 1. 读取纯噪声信号,建立噪声频谱模型
noise_rate, noise_data = wav.read('./AudioSource/Noisy.wav')
# 如果噪声是立体声,转换为单声道
if len(noise_data.shape) > 1:noise_data = noise_data.mean(axis=1)# 计算噪声频谱模型
frame_size = 1024
overlap = 512
noise_frames = []
for i in range(0, len(noise_data) - frame_size, overlap):frame = noise_data[i:i+frame_size]windowed_frame = frame * get_window('hamming', frame_size)spectrum = fft(windowed_frame)noise_frames.append(np.abs(spectrum))
# 计算平均噪声频谱
noise_spectrum = np.mean(noise_frames, axis=0)# 2. 读取需要降噪的音频信号
rate, data = wav.read('./AudioSource/Source.wav')
if len(data.shape) > 1:data = data.mean(axis=1)# 保存降噪前的频谱,用于后续对比
original_spectrum = []# 进行降噪处理
output_data = np.zeros(len(data))
window = get_window('hamming', frame_size)
for i in range(0, len(data) - frame_size, overlap):# 2. 分帧frame = data[i:i+frame_size]# 3. 窗函数处理windowed_frame = frame * window# 4. FFTspectrum = fft(windowed_frame)# 保存原始频谱original_spectrum.append(np.abs(spectrum))# 5. 频谱减法magnitude = np.abs(spectrum)phase = np.angle(spectrum)subtracted_magnitude = magnitude - noise_spectrum# 6. 处理负值和伪影subtracted_magnitude = np.maximum(subtracted_magnitude, 0.0)# 7. IFFTreconstructed_spectrum = subtracted_magnitude * np.exp(1j * phase)reconstructed_frame = np.real(ifft(reconstructed_spectrum))# 8. Overlap-Add 重建信号output_data[i:i+frame_size] += reconstructed_frame * window# 保存降噪后的频谱,用于对比
denoised_spectrum = []
for i in range(0, len(output_data) - frame_size, overlap):frame = output_data[i:i+frame_size]windowed_frame = frame * windowspectrum = fft(windowed_frame)denoised_spectrum.append(np.abs(spectrum))# 9. 后处理(可选,这里暂不实现)# 保存降噪后的音频
wav.write('./AudioSource/Denosed.wav', rate, output_data.astype(np.int16))# 绘制频谱对比
# 计算平均频谱
original_spectrum_mean = np.mean(original_spectrum, axis=0)
denoised_spectrum_mean = np.mean(denoised_spectrum, axis=0)
freqs = np.linspace(0, rate, frame_size)plt.figure(figsize=(12,6))
plt.plot(freqs[:frame_size//2], 20*np.log10(original_spectrum_mean[:frame_size//2]), label='Original')
plt.plot(freqs[:frame_size//2], 20*np.log10(denoised_spectrum_mean[:frame_size//2]), label='Processed')
plt.xlabel('频率 (Hz)')
plt.ylabel('幅度 (dB)')
plt.title('降噪前后频谱对比')
plt.legend()
plt.show()

测试效果

这个库还有很多可以优化的空间,可以参考Audition下的控制面板,可以简单窥见可以优化的空间:

  • 1.优化曲线频域相减对于频域下不同值的曲线增益因子 r \mathcal{r} r在这里是没有考虑的,在实际的使用中是可以进行考虑的。

  • 2.这里是直接简单粗暴的直接减掉了所有的频域内容,实际上可以不那么生硬地进行剪辑。

  • 3.可以使用小范围的 FFT来进行实时性音频降噪的尝试。

  • 4.进行C++的移植,实际上这些库都有。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

低质量数据的多模态融合方法

目录 多模态融合 低质量多模态融合的核心挑战 噪声多模态数据学习 缺失模态插补 平衡多模态融合 动态多模态融合 启发式动态融合 基于注意力的动态融合 不确定性感知动态融合 论文 多模态融合 多模态融合侧重于整合多种模态的信息,以实现更准确的预测,在自动驾驶、…

08_OpenCV文字图片绘制

import cv2 import numpy as npimg cv2.imread(image0.jpg,1) font cv2.FONT_HERSHEY_SIMPLEXcv2.rectangle(img,(500,400),(200,100),(0,255,0),20) # 1 dst 2 文字内容 3 坐标 4 5 字体大小 6 color 7 粗细 8 line type cv2.putText(img,flower,(200,50),font,1,(0,0,250)…

c#-出现类型初始值设定项引发异常的解决方案

当出现该问题时,通常摸不着头脑,无法定位到该问题所在行。 我们可以找到应发异常的类,例如我上面类为YY_Model.DefaultConfig。 打开这个类文件,加一个断点,一行行运行,到哪里突然跳出该文件,则…

(计算机毕设)基于Vue和Spring Boot的宠物救助网站设计与实现

博主可接毕设!!! 毕业设计(论文) 基于Vue和Spring Boot的宠物救助网站设计与实现 摘 要 随着中国互联网的迅猛发展,传统宠物救助领域面临着信息管理繁琐、辐射范围有限、信息传播受限、丢失宠物找回几率较…

机器学习框架(含实例说明)

机器学习框架是用于开发和部署机器学习模型的软件库和工具集。它们提供了一系列的算法、工具和基础设施,帮助开发者更高效地构建、训练和部署机器学习模型。以下是一些主要的机器学习框架及其详细介绍: 1. TensorFlow TensorFlow 是由Google开发的开源…

卫瓴科技,驶向「协同CRM」深水区

在卫瓴协同CRM的产品之上,能看到的不单纯是产品本身,即“提高转化率”这个单纯的指标,而更多的是在产品之中蕴含的“现代企业营销建设”的科学理念和认知。以此为基础,企业可以构建真正有价值且能长期驱动的品牌营销模型。 作者…

攻防世界---->sherlock

做题笔记。 下载。 单词中出现大写很可疑。因为大写最多出现在开头等。 猜测是隐写术。 进行筛选。 借助python实现 with open(C:\\Users\\Acer\\Downloads\\f590c0f99c014b01a5ab8b611b46c57c.txt, r) as file:text file.read() uppercase_letters [char for char in text…

Study-Oracle-11-ORALCE19C-ADG集群测试

一、用户及数据测试 1、主库创建tes3用户,创建表test_table。备库登录test3用户并查询test_table表中数据。 -- 创建用户 CREATE USER test7 IDENTIFIED BY test7;-- 给予创建会话的权限 GRANT CREATE SESSION TO test7;-- 给予创建表的权限 GRANT CREATE TABLE TO…

贴吧软件怎么切换ip

在网络使用中,有时我们需要切换IP地址来满足特定的需求,比如需要切换贴吧软件IP以进行不同的操作。本文将介绍几种贴吧切换IP地址的方法,帮助用户更好地管理自己的网络身份和访问权限。 1、更换网络环境‌ 通过连接到不同的Wi-Fi网络或使用移…

解决雪花ID在前端精度丢失问题

解决雪花ID在前端精度丢失问题 在现代分布式系统中,雪花算法(Snowflake)被广泛用于生成唯一的ID。这些ID通常是Long类型的整数。然而,当这些ID从后端传递到前端时,JavaScript的精度限制可能会导致精度丢失&#xff0c…

Android 电源管理各个版本的变动和限制

由于Android设备的电池容量有限,而用户在使用过程中会进行各种高耗电操作,如网络连接、屏幕亮度调节、后台程序运行等,因此需要通过各种省电措施来优化电池使用‌,延长电池续航时间,提高用户体验,并减少因电…

开源的云平台有哪些?

开源云平台为用户提供了构建、管理和运行云基础设施及应用的能力,同时允许社区参与开发和改进。以下是一些知名的开源云平台: 1. OpenStack 简介:OpenStack:一个广泛使用的开源云平台,它由多个组件组成,提…

【ubuntu】修改用户名、主机名、主文件夹名、登录名、密码

目录 1.他们是什么 2.修改方法 2.1 修改用户密码 2.2 修改主机名 2.2.1 切换到root用户 2.2.2 修改名称 2.3 修改用户名 主文件夹名 登录名 2.2.1 sudoers 2.2.2 passwd 2.2.3 shadow 2.2.4 group 2.2.5 修改主文件夹名 3.重启 1.他们是什么 (1&#xf…

一键生成PPT的AI工具-Kimi!

一键生成PPT的AI工具-Kimi! 前言介绍Kimi为什么选择Kimi如何使用Kimi在线编辑PPT下载生成的PPT自己编辑 结语 😀大家好!我是向阳🌞,一个想成为优秀全栈开发工程师的有志青年! 📔今天不来讨论前后…

前端反接保护:实用方案解析与探讨

前端反接保护通常采用肖特基二极管方案或PMOS/NMOS方案,本文另外介绍一种理想二极管方案。 1、肖特基二极管方案 由于肖特基二极管具有正向导通电压,只能用于小电流场合,甚至于直接使用普通的整流二极管。比如1A电流,设D1的正向…

OJ在线评测系统 微服务 用分布式消息队列 RabbitMQ 解耦判题服务和题目服务 手搓交换机和队列 实现项目异步化

消息队列解耦 项目异步化 分布式消息队列 分布式消息队列是一种用于异步通信的系统,它允许不同的应用程序或服务之间传递消息。消息队列的核心理念是将消息存储在一个队列中,发送方可以将消息发送到队列,而接收方则可以在适当的时候从队列中…

系统架构设计师论文《论企业集成平台的理解与应用》精选试读

论文真题 企业集成平台(Enterprise Imtcgation Plaform,EIP)是支特企业信息集成的像环境,其主要功能是为企业中的数据、系统和应用等多种对象的协同行提供各种公共服务及运行时的支撑环境。企业集成平台能够根据业务模型的变化快速地进行信息系统的配置…

面试(十)

目录 一. 单元测试 二. FreeRTOS和裸机哪个实时性好? 三. 怎么判断某个程序的运行时间 四. 函数指针 五. 全局变量被线程使用冲突 5.1 使用互斥锁 5.2 使用读写锁 5.3 使用原子操作 六. 局部变量没有初始化是什么值 七. uint_8 n 255 , n等于多少 八. …

单体到微服务架构服务演化过程

单体到微服务架构服务演化过程 架构服务化 聊聊从单体到微服务架构服务演化过程 单体分层架构 在 Web 应用程序发展的早期,大部分工程是将所有的服务端功能模块打包到单个巨石型(Monolith)应用中,譬如很多企业的 Java 应用程序…

3、Docker搭建MQTT及Spring Boot 3.x集成MQTT

一、前言 本篇主要是围绕着两个点,1、Docker 搭建单机版本 MQTT(EMQX),2、Spring Boot 3.x 集成 MQTT(EMQX); 而且这里的 MQTT(EMQX)的搭建也只是一个简单的过程&#x…