使用Python實(shí)現(xiàn)音頻降噪功能
依賴庫安裝
在開始之前,我們需要安裝以下依賴庫:
- pydub:用于音頻文件的讀取和寫入。
- numpy:用于數(shù)組和數(shù)值計(jì)算。
- noisereduce:用于音頻降噪。
- matplotlib:用于繪制波形圖。
使用以下命令安裝依賴庫:
pip install pydub numpy noisereduce matplotlib
安裝 FFmpeg
FFmpeg 是一個(gè)強(qiáng)大的多媒體處理工具,pydub 庫需要依賴它來處理音頻文件。請(qǐng)按照以下步驟在 Windows 上安裝 FFmpeg:
- 下載 FFmpeg:訪問 FFmpeg 的官方網(wǎng)站。下載預(yù)編譯的 FFmpeg 二進(jìn)制文件。
- 解壓文件:解壓到一個(gè)目錄,例如 C:\ffmpeg。
- 配置環(huán)境變量:將 FFmpeg 的 bin 目錄添加到系統(tǒng)環(huán)境變量中,然后重啟
- 驗(yàn)證安裝:打開終端,輸入命令
ffmpeg -version,如果安裝成功,將看到 FFmpeg 的版本信息輸出。
對(duì)于m4a文件,可以使用FFmpeg將其轉(zhuǎn)換為wav,再進(jìn)行處理:
ffmpeg -i file.m4a file.wav
導(dǎo)入庫
from pydub import AudioSegment import numpy as np from pathlib import Path import noisereduce as nr import matplotlib.pyplot as plt
設(shè)置參數(shù)和讀取音頻文件
# 設(shè)置音頻文件路徑
seq = "01"
data_folder = Path("data/")
file_to_open = data_folder / f"{seq}.wav"
# 設(shè)置截取時(shí)間(秒)
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")
將音頻數(shù)據(jù)轉(zhuǎn)換為 NumPy 數(shù)組
# 獲取音頻樣本數(shù)據(jù)
raw_data = np.array(audio.get_array_of_samples())
# 處理立體聲和單聲道
if audio.channels == 2:
# 將立體聲數(shù)據(jù)重塑為二維數(shù)組
raw_data = raw_data.reshape((-1, 2))
# 截取指定時(shí)間段的數(shù)據(jù)
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:
# 截取指定時(shí)間段的數(shù)據(jù)
raw_data = raw_data[time_beg * audio.frame_rate : time_end * audio.frame_rate]
print(f"Mono audio detected. Data shape: {raw_data.shape}")
對(duì)音頻進(jìn)行降噪處理
# 初始化降噪后的數(shù)據(jù)數(shù)組
reduced_noise = np.zeros_like(raw_data)
# 設(shè)置降噪?yún)?shù)(可調(diào)整 prop_decrease 的值來改變降噪力度)
prop_decrease_value = 0.95
if audio.channels == 2:
# 分別對(duì)每個(gè)通道進(jìn)行降噪
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:
# 對(duì)單聲道音頻進(jìn)行降噪
reduced_noise = nr.reduce_noise(
y=raw_data, sr=audio.frame_rate, prop_decrease=prop_decrease_value
)
將降噪后的數(shù)據(jù)轉(zhuǎn)換回音頻并保存
# 將降噪后的數(shù)據(jù)轉(zhuǎn)換為 AudioSegment 對(duì)象
if audio.channels == 2:
# 將二維數(shù)組展平成一維交錯(cuò)數(shù)組
interleaved = reduced_noise.astype(np.int16).flatten().tobytes()
else:
interleaved = reduced_noise.astype(np.int16).tobytes()
# 創(chuàng)建新的音頻段
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()
調(diào)整降噪力度
在降噪處理中,prop_decrease參數(shù)控制了降噪的力度,其取值范圍為 0 到 1。值越大,降噪力度越強(qiáng)。您可以通過調(diào)整 prop_decrease_value 的值來改變降噪效果:
prop_decrease_value = 0.5 # 降低降噪力度
測試結(jié)果

附錄
完整程序:
from pydub import AudioSegment
import numpy as np
from pathlib import Path
import noisereduce as nr
import matplotlib.pyplot as plt
seq = "03"
data_folder = Path("data/")
file_to_open = data_folder / f"{seq}.wav"
time_beg = 120
time_end = 170
prop_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")
# 將音頻數(shù)據(jù)轉(zhuǎn)換為 NumPy 數(shù)組
raw_data = np.array(audio.get_array_of_samples())
# 如果是立體聲,轉(zhuǎn)換為二維數(shù)組
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}")
# 對(duì)每個(gè)通道分別進(jìn)行降噪
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]
# 對(duì)單通道音頻進(jìn)行降噪
reduced_noise = nr.reduce_noise(y=raw_data, sr=audio.frame_rate)
# # 放大音量
# reduced_noise = reduced_noise * 10
# # 將大于1000的值截?cái)酁?
# reduced_noise[np.abs(reduced_noise) > 2000] = 0
# 將降噪后的數(shù)據(jù)轉(zhuǎn)換回 AudioSegment 對(duì)象
# 注意,AudioSegment 需要一維數(shù)組,立體聲需要交錯(cuò)的字節(jié)數(shù)據(jù)
# 將數(shù)組轉(zhuǎn)換為 bytes
if audio.channels == 2:
# 將二維數(shù)組轉(zhuǎn)換為交錯(cuò)的一維數(shù)組
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()
以上就是使用Python實(shí)現(xiàn)音頻降噪功能的詳細(xì)內(nèi)容,更多關(guān)于Python音頻降噪的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
PyQt5實(shí)現(xiàn)用戶登錄GUI界面及登錄后跳轉(zhuǎn)
PyQt5是強(qiáng)大的GUI工具之一,通過其可以實(shí)現(xiàn)優(yōu)秀的桌面應(yīng)用程序。本文主要介紹了PyQt5實(shí)現(xiàn)用戶登錄GUI界面及登錄后跳轉(zhuǎn),具有一定的參考價(jià)值,感興趣的可以了解一下2021-11-11
PyQt5實(shí)現(xiàn)簡單數(shù)據(jù)標(biāo)注工具
這篇文章主要為大家詳細(xì)介紹了PyQt5實(shí)現(xiàn)簡單數(shù)據(jù)標(biāo)注工具,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03
Pytorch從0實(shí)現(xiàn)Transformer的實(shí)踐
本文主要介紹了Pytorch從0實(shí)現(xiàn)Transformer的實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
Python中的jquery PyQuery庫使用小結(jié)
這篇文章主要介紹了Python中的jquery PyQuery庫使用小結(jié),需要的朋友可以參考下2014-05-05
Python Django實(shí)現(xiàn)個(gè)人博客系統(tǒng)的搭建
個(gè)人博客是一個(gè)非常好的平臺(tái),可以讓人們分享自己的知識(shí)和經(jīng)驗(yàn),也可以讓人們交流和互動(dòng)。在這篇文章中,我們將介紹如何使用Python Django框架來開發(fā)一個(gè)個(gè)人博客系統(tǒng),希望對(duì)大家有所幫助2023-04-04
在 Python 中如何使用 Re 模塊的正則表達(dá)式通配符
這篇文章主要介紹了在 Python 中如何使用 Re 模塊的正則表達(dá)式通配符,本文詳細(xì)解釋了如何在 Python 中使用帶有通配符的 re.sub() 來匹配字符串與正則表達(dá)式,需要的朋友可以參考下2023-06-06
利用Python和PyQt5構(gòu)建一個(gè)多功能PDF轉(zhuǎn)換器
在日常工作中,處理PDF文件幾乎是每個(gè)人都不可避免的任務(wù),本文將通過Python和PyQt5搭建一個(gè)強(qiáng)大的PDF文件處理平臺(tái),希望對(duì)大家有所幫助2024-12-12

