使用Python实现音频降噪

在音频处理领域,背景噪声是一个常见的问题。为了提高音频的质量,我们需要对音频进行降噪处理。本文将介绍如何使用 Python 实现音频降噪。

依赖库安装

在开始之前,我们需要安装以下依赖库:

  • pydub:用于音频文件的读取和写入。
  • numpy:用于数组和数值计算。
  • noisereduce:用于音频降噪。
  • matplotlib:用于绘制波形图。

使用以下命令安装依赖库:

pip install pydub numpy noisereduce matplotlib

安装 FFmpeg

FFmpeg 是一个强大的多媒体处理工具,pydub 库需要依赖它来处理音频文件。请按照以下步骤在 Windows 上安装 FFmpeg:

  1. 下载 FFmpeg:访问 FFmpeg 的官方网站。下载预编译的 FFmpeg 二进制文件。
  2. 解压文件:解压到一个目录,例如 C:\ffmpeg。
  3. 配置环境变量:将 FFmpeg 的 bin 目录添加到系统环境变量中,然后重启
  4. 验证安装:打开终端,输入命令 ffmpeg -version,如果安装成功,将看到 FFmpeg 的版本信息输出。

对于m4a文件,可以使用FFmpeg将其转换为wav,再进行处理:

ffmpeg -i file.m4a file.wav

导入库

from pydub import AudioSegment
import numpy as np
from pathlib import Path
import noisereduce as nr
import matplotlib.pyplot as plt

设置参数和读取音频文件

# 设置音频文件路径
seq = "01"
data_folder = Path("data/")
file_to_open = data_folder / f"{seq}.wav"# 设置截取时间(秒)
time_beg = 10
time_end = 55# 读取音频文件
audio = AudioSegment.from_file(file_to_open, format="wav")# 打印音频信息
print(f"Channels: {audio.channels}")
print(f"Frame rate: {audio.frame_rate} Hz")
print(f"Duration: {len(audio) / 1000.0} seconds")

将音频数据转换为 NumPy 数组

# 获取音频样本数据
raw_data = np.array(audio.get_array_of_samples())# 处理立体声和单声道
if audio.channels == 2:# 将立体声数据重塑为二维数组raw_data = raw_data.reshape((-1, 2))# 截取指定时间段的数据raw_data = raw_data[time_beg * audio.frame_rate : time_end * audio.frame_rate, :]print(f"Stereo audio detected. Data shape: {raw_data.shape}")
else:# 截取指定时间段的数据raw_data = raw_data[time_beg * audio.frame_rate : time_end * audio.frame_rate]print(f"Mono audio detected. Data shape: {raw_data.shape}")

对音频进行降噪处理

# 初始化降噪后的数据数组
reduced_noise = np.zeros_like(raw_data)# 设置降噪参数(可调整 prop_decrease 的值来改变降噪力度)
prop_decrease_value = 0.95if audio.channels == 2:# 分别对每个通道进行降噪for i in range(audio.channels):reduced_noise[:, i] = nr.reduce_noise(y=raw_data[:, i], sr=audio.frame_rate, prop_decrease=prop_decrease_value)
else:# 对单声道音频进行降噪reduced_noise = nr.reduce_noise(y=raw_data, sr=audio.frame_rate, prop_decrease=prop_decrease_value)

将降噪后的数据转换回音频并保存

# 将降噪后的数据转换为 AudioSegment 对象
if audio.channels == 2:# 将二维数组展平成一维交错数组interleaved = reduced_noise.astype(np.int16).flatten().tobytes()
else:interleaved = reduced_noise.astype(np.int16).tobytes()# 创建新的音频段
denoised_audio = audio._spawn(interleaved)# 保存降噪后的音频文件
output_path = data_folder / f"{seq}_denoised.wav"
denoised_audio.export(output_path, format="wav")

绘制降噪前后的波形图

plt.figure(figsize=(12, 6))# 原始音频波形
plt.subplot(2, 1, 1)
plt.title('原始音频波形')
plt.plot(raw_data)
plt.tight_layout()# 降噪后音频波形
plt.subplot(2, 1, 2)
plt.title('降噪后音频波形')
plt.plot(reduced_noise)
plt.tight_layout()plt.show()

调整降噪力度

在降噪处理中,

prop_decrease

参数控制了降噪的力度,其取值范围为 0 到 1。值越大,降噪力度越强。您可以通过调整 prop_decrease_value 的值来改变降噪效果:

prop_decrease_value = 0.5  # 降低降噪力度

测试结果

附录

完整程序:

from pydub import AudioSegment
import numpy as np
from pathlib import Path
import noisereduce as nr
import matplotlib.pyplot as pltseq = "03"
data_folder = Path("data/")
file_to_open = data_folder / f"{seq}.wav"time_beg = 120
time_end = 170prop_decrease = 0.95# 读取原始音频文件
audio = AudioSegment.from_file(file_to_open, format="wav")# 打印音频信息
print(f"Channels: {audio.channels}")
print(f"Frame rate: {audio.frame_rate}")
print(f"Duration: {len(audio) / 1000.0} seconds")# 将音频数据转换为 NumPy 数组
raw_data = np.array(audio.get_array_of_samples())# 如果是立体声,转换为二维数组
if audio.channels == 2:# 截取raw_data = raw_data.reshape((-1, 2))raw_data = raw_data[time_beg * audio.frame_rate:time_end * audio.frame_rate, :]print(f"Stereo audio detected. Data shape: {raw_data.shape}")# 对每个通道分别进行降噪reduced_noise = np.zeros_like(raw_data)for i in range(audio.channels):reduced_noise[:, i] = nr.reduce_noise(y=raw_data[:, i], sr=audio.frame_rate, prop_decrease=prop_decrease)
else:print(f"Mono audio detected. Data shape: {raw_data.shape}")raw_data = raw_data[time_beg * audio.frame_rate:time_end * audio.frame_rate]# 对单通道音频进行降噪reduced_noise = nr.reduce_noise(y=raw_data, sr=audio.frame_rate)# # 放大音量
# reduced_noise = reduced_noise * 10# # 将大于1000的值截断为0
# reduced_noise[np.abs(reduced_noise) > 2000] = 0# 将降噪后的数据转换回 AudioSegment 对象
# 注意,AudioSegment 需要一维数组,立体声需要交错的字节数据# 将数组转换为 bytes
if audio.channels == 2:# 将二维数组转换为交错的一维数组interleaved = reduced_noise.astype(np.int16).flatten().tobytes()
else:interleaved = reduced_noise.astype(np.int16).tobytes()denoised_audio = audio._spawn(interleaved)# 保存降噪后的音频
output_path = data_folder / f"{seq}_denoised.wav"
denoised_audio.export(output_path, format="wav")# 绘制降噪前后的波形
plt.figure(figsize=(12, 6))plt.subplot(2, 1, 1)
plt.title('raw_data')
plt.plot(raw_data)
plt.tight_layout()plt.subplot(2, 1, 2)
plt.title('reduced_noise')
plt.plot(reduced_noise)
plt.tight_layout()plt.show()

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

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

相关文章

科大讯飞面经,蛮简单的

先来看面经: 下面我来简单聊聊这些问题。 自我介绍 关于如何自我介绍,这个如果还不会或者还没有准备,请先准备好你要如何向面试官介绍自己。 面试本来就是一个自我推销的方式之一,如果自我介绍都不会说,你如何卖个好价…

ARM64汇编寻址、汇编指令、指令编码方式

版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/ ARM64汇编寻址 1. 立即数寻址(Immediate Addressing) 这种方式直接将立即数作为操作数,适合小数据或常量。ARM64的立即数…

创建者模式之【建造者模式】

建造者模式 概述 将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。 分离了部件的构造(由Builder来负责)和装配(由Director负责)。 从而可以构造出复杂的对象。这个模式适用于:某个对象的构建过程复杂的情况。由于实现了构建和…

什么是CANN和Ascend C

1 CANN是什么 异构计算架构CANN(Compute Architecture for Neural Networks)是华为针对AI场景推出的异构计算架构,向上支持多种AI框架,包括MindSpore、PyTorch、TensorFlow等,向下服务AI处理器与编程,发挥…

GenAI 用于客户支持 — 第 5 部分:可观察性

作者:来自 Elastic Andy James 本系列将带你深入了解我们如何在客户支持中使用生成式人工智能。加入我们,实时分享我们的历程,本篇文章重点介绍支持助理的可观察性。 本博客系列揭示了我们的现场工程团队如何使用 Elastic stack 和生成式 AI …

python安装selenium,geckodriver,chromedriver,Selenium IDE

安装浏览器 找到浏览器的版本号 chrome 版本 130.0.6723.92(正式版本) (64 位) firfox 116.0.3 (64 位),但是后面运行的时候又自动更新到了 127.0.0.8923 安装selenium > pip install selenium > pip show …

Docker部署SpringBoot项目(镜像部署)

目录 一、在pom.xml 文件中加入依赖 1.依赖内容 2.依赖说明和解释 3.使用流程 4.示例 5.注意 二、执行打包 1.使用命令打包 2.使用IDEA提供快捷方式 三、将jar包上传到服务器 四、创建相关配置 1.创建一个Dockerfile文件 2.添加配置 3.举例 五、生成Docker镜像 1.…

WPF+MVVM案例实战与特效(二十五)- 3D粒子波浪效果实现

文章目录 1、案例效果2、案例实现1、文件创建2. 功能代码实现3、粒子功能应用1、前端布局与样式2、代码解释2、 后端功能代码1、案例效果 2、案例实现 1、文件创建 打开 Wpf_Examples 项目、Models 文件夹下创建 3D粒子模型类 ParticleWaveEffectModel.cs 文件。在Tools 文件…

设计模式之建造者模式(各项装修物料组合套餐选配场景)

前言: 乱码七糟,我时常怀疑这个成语是来形容程序猿的! 无论承接什么样的需求,是不是身边总有那么几个人代码写的烂,但是却时常有测试小姐姐过来聊天(求改bug)、有产品小伙伴送吃的(求写需求)、有业务小妹妹陪着改代码(…

ffmpeg视频滤镜:组合两个视频为立体视频- framepack

视频描述 framepack 官方网址 > FFmpeg Filters Documentation 这个滤镜会将两个视频进行组合,有个前提是这两个视频的帧率、分别率必须一样。比如输入的是两个852x480 视频,输出可能是1704*480(左右拼接)、852*960&#xf…

【K8S问题系列 | 8】K8S集群资源突然爆满导致 Pod 状态变为 Pending 详细解决方案

在 Kubernetes 集群中,当 CPU 突然爆满时,Pod 可能无法获得所需的资源,从而导致其状态变为 Pending。以下是更详细的解决方案描述,有效应对这一问题。 解决方案 1: 扩展集群资源 描述 当集群资源不足以支撑当前的工作负载时&…

第18篇 :深入剖析systemverilog中 randomize 失败案例启示录(一)

经过前面章节的理论学习,我们对systemverilog中的随机约束,有一定的了解,那么,今天开始,着重讲述一些工作中遇到的困惑。主要通过一些例子,层层递进,举一反三,源于实践,剖…

mac端mumu模拟器adb识别不了问题

1.在终端中输入:system_profiler SPUSBDataType,把0x05e3 (Genesys Logic, Inc.)复制 2. 1.cd ~/.android/ 2.open . 3.找到.android/adb_usb.ini文件 将以上格式的Wendor ID放入该文件 3.依次执行 * adb devices* adb kill-server* adb start-server* adb disco…

Ubuntu版本、ROS版本与Python 版本之间的关系

引言 在机器人开发中,ROS(机器人操作系统)广泛应用于科研和工业领域,支持多个Ubuntu和Python版本。然而,随着不同Ubuntu LTS版本的发布以及Python逐渐从2.x向3.x过渡,ROS的版本选择和兼容性要求也在不断变化…

Linux - 信号

文章目录 一、信号的定义二、查看信号三、产生信号1、指令2、系统调用3、由软件条件产生信号4、异常5、键盘输入 四、保存信号1、补充:信号其他相关概念2、信号保存在哪,怎么保存?3、信号集操作函数 五、捕获信号1、概念2、捕获信号的时机3、…

PMP–知识卡片--项目干系人

项目干系人主要分为两类:参与项目的人和受项目影响的人。按照由近及远,从项目经理、项目团队等逐渐扩充至供应商、客户、监管机构等。 项目往往死在被忽略的干系人手上,作为项目经理,要尽可能地识别出来所有可能影响项目以及受项目…

MATLAB - ROS 2 分析器

系列文章目录 前言 本主题介绍如何连接 ROS 2 网络,分析网络图中所有元素的基本信息(如节点名称和节点之间的信息),以及可视化与 ROS 2 节点相关的参数(如主题、服务和操作)之间的交互。 一、连接并查看 RO…

分组校验在Spring中的应用详解

目录 前言1. 什么是分组校验2. 分组校验的基本原理3. 分组校验的实现步骤3.1 定义分组接口3.2 在校验项中指定分组3.3 校验时指定要校验的分组3.4 默认分组和分组的继承 4. 分组校验的优势和适用场景4.1 优势4.2 适用场景 5. 常见问题与解决方案5.1 校验未生效5.2 无法识别默认…

SDL打开YUV视频

文章目录 问题1:如何控制帧率?问题2:如何触发退出事件?问题3:如何实时调整视频窗口的大小问题4:YUV如何一次读取一帧的数据? 问题1:如何控制帧率? 单独用一个子线程给主线…

[MySQL]索引

索引介绍 索引是帮助数据库高效获取数据的数据结构。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用数据, 这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。 假设我们有…