使用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.rhkb.cn/news/467930.html

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

相关文章

【WRF模拟】全过程总结:WPS预处理及WRF运行

【WRF模拟】全过程总结:WPS预处理及WRF运行 1 数据准备1.1 嵌套域设置(Customize domain)-基于QGis中gis4wrf插件1.2 静态地理数据1.2.1 叶面积指数LAI和植被覆盖度Fpar(月尺度)1.2.2 地面反照率(月尺度)1.2.3 土地利用类型+不透水面积1.2.4 数据处理:geotiff→tiff(W…

【react】Redux基础用法

1. Redux基础用法 Redux 是一个用于 JavaScript 应用的状态管理库,它不依赖于任何 UI库,但常用于与 React 框架配合使用。它提供了一种集中式的状态管理方式,将应用的所有状态保存在一个单一的全局 Store(存储)中&…

DevCheck Pro手机硬件检测工具v5.33

前言 DevCheck Pro是一款手机硬件和操作系统信息检测查看工具,该软件的功能非常强大,为用户提供了系统、硬件、应用程序、相机、网络、电池等一系列信息查看功能 安装环境 [名称]:DevCheckPro [版本]:5.33 [大小]&a…

Docker的轻量级可视化工具Portainer

docker目录 1 Portainer官方链接2 是什么?3 下载安装4 跑通一次5 后记 1 Portainer官方链接 这里给出portainer的官方链接:https://www.portainer.io/ portainer安装的官方链接:https://docs.portainer.io/start/install-ce/server/docker/l…

IoTDB 与 HBase 对比详解:架构、功能与性能

五大方向,洞悉 IoTDB 与 HBase 的详尽对比! 在物联网(IoT)领域,数据的采集、存储和分析是确保系统高效运行和决策准确的重要环节。随着物联网设备数量的增加和数据量的爆炸式增长,开发者和决策者们需要选择…

【c++丨STL】vector模拟实现

🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:C、STL 目录 前言 一、vector底层刨析 二、模拟实现 1. 属性、迭代器以及函数声明 2. 功能实现 交换两个容器的内容 构造函数 拷贝构造 赋值重载 析构…

C++中类的默认成员函数

默认成员函数 1.构造函数2.析构函数3.拷贝构造函数4.赋值运算符重载4.1运算符重载4.2赋值运算符重载 #mermaid-svg-oipiwg9stvONvYK0 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-oipiwg9stvONvYK0 .error-icon{f…

数据编排与ETL有什么关系?

数据编排作为近期比较有热度的一个话题,讨论度比较高,同时数据编排的出现也暗示着数字化进程的自动化发展。在谈及数据编排时,通常也会谈到ETL,这两个东西有相似点也有不同点。 数据编排和ETL(提取、转换、加载&#x…

【SpringCloud】SpringBoot集成Swagger 常用Swagger注解

概述:SpringBoot集成Swagger 常用Swagger注解 导语 相信无论是前端还是后端开发,都或多或少地被接口文档折磨过。前端经常抱怨后端给的接口文档与实际情况不一致。后端又觉得编写及维护接口文档会耗费不少精力,经常来不及更新。其实无论是前…

革命性AI搜索引擎!ChatGPT最新功能发布,无广告更智能!

文章目录 零、前言一、ChatGPT最新AI搜索引擎功能操作指导实战1:搜索新闻实战2:搜索天气实战3:搜索体育消息 二、感受 零、前言 大人,时代变了。 最强 AI 助力下的无广告搜索引擎终于问世。我们期待已久的这一刻终于到来了,从今天起,ChatGPT…

基于 CMSIS-PACK 移植Bootloader

基于 CMSIS-PACK 移植 1.准备工作 准备一份基础的裸机源码 (可通过 STM32CubeMx 可视化软件创建也可按照工程项目所需文档手动创建) 工程,如一份 stm32 包含一个支持 printf 的串口初始化代码。 2.安装Pack包 在 MDK 中部署 **MicroBoot **的第一步是获取对应的…

苍穹外卖day09超出配送范围前端不提示问题

同学们在写苍穹外卖项目day09时调用了百度地图api来判断用户地址是否超出配送范围, 但是在黑马官方的课程或资料中,出现这样的问题时只会向用户端的控制台报错并不会提醒用户 如下图: 解决方法: 其实解决方法很简单只需要找到向…

嵌入式linux中PWM控制与实现

大家好,今天主要给大家分享一下,如何使用linux系统里面的PWM的功能,可以控制对应电机的转速。 第一:PWM驱动基本简介 PWM就是脉冲宽度调制。 PWM信号有两个关键术语:频率和占空比,频率指的是开关的速度。占空比就是一个周期内高电平和低电平时间的比例,一个周期内高电…

CUDA系统学习之一软件堆栈架构

一、CPU与GPU体系架构 计算单元分布 CPU: 少量强大的ALU(算术逻辑单元),通常4-8个核心GPU: 大量小型ALU,成百上千个计算核心特点:GPU更适合并行计算,可以同时处理大量数据控制单元(Control) CPU: 较大的控制单元,复杂的…

「QT」几何数据类 之 QPoint 整型点类

✨博客主页何曾参静谧的博客📌文章专栏「QT」QT5程序设计📚全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasolid…

0x00基础算法 -- 0x01 位运算

资料来源:算法竞赛进阶指南活动 - AcWing 1、进制表示 二进制表示:m位二进制中,通常称最低位为第0位,从右到左以此类推,最高位为第m-1位。 常用十六进制表示的数字: 32位补码int(十进制&#xf…

H5移动端预览PDF方法

新建页面 新建一个页面以便去预览对应的pdf 新建完后在 pages.json 文件内去新增对应路由 页面内容 <template><view class"page"><view class"pdf"><view id"demo"></view></view><view class"b…

嵌入式开发之线程

进程 vs 线程 进程在切换时系统开销大很多操作系统引入了轻量级进程LWP同一进程中的线程共享相同地址空间Linux不区分进程、线程(都会创建:task_strcut)线程特点: 通常线程指的是共享相同的地址空间的多个任务,使用多线程的好处 大大提高了任务切换的效率避免了额外的TLB…

【SQL实验】更新操作

完整代码在文章末尾【代码是自己的解答&#xff0c;并非标准答案&#xff0c;也有可能写错&#xff0c;文中可能会有不准确或待完善之处&#xff0c;恳请各位读者不吝批评指正&#xff0c;共同促进学习交流】 将素材“图书管理”文件下载到本地&#xff0c;并将其还原到SQL SER…

Hadoop(HDFS)

Hadoop是一个开源的分布式系统架构&#xff0c;旨在解决海量数据的存储和计算问题&#xff0c;Hadoop的核心组件包括Hadoop分布式文件系统&#xff08;HDFS&#xff09;、MapReduce编程模型和YARN资源管理器,最近需求需要用到HDFS和YARN。 文章目录 HDFS优缺点HDFS的读写原理 常…