使用Python實現(xiàn)音頻降噪功能
依賴庫安裝
在開始之前,我們需要安裝以下依賴庫:
- pydub:用于音頻文件的讀取和寫入。
- numpy:用于數(shù)組和數(shù)值計算。
- noisereduce:用于音頻降噪。
- matplotlib:用于繪制波形圖。
使用以下命令安裝依賴庫:
pip install pydub numpy noisereduce matplotlib
安裝 FFmpeg
FFmpeg 是一個強大的多媒體處理工具,pydub 庫需要依賴它來處理音頻文件。請按照以下步驟在 Windows 上安裝 FFmpeg:
- 下載 FFmpeg:訪問 FFmpeg 的官方網(wǎng)站。下載預編譯的 FFmpeg 二進制文件。
- 解壓文件:解壓到一個目錄,例如 C:\ffmpeg。
- 配置環(huán)境變量:將 FFmpeg 的 bin 目錄添加到系統(tǒng)環(huán)境變量中,然后重啟
- 驗證安裝:打開終端,輸入命令
ffmpeg -version,如果安裝成功,將看到 FFmpeg 的版本信息輸出。
對于m4a文件,可以使用FFmpeg將其轉(zhuǎn)換為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
設置參數(shù)和讀取音頻文件
# 設置音頻文件路徑
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")
將音頻數(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ù)據(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ù)據(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}")
對音頻進行降噪處理
# 初始化降噪后的數(shù)據(jù)數(shù)組
reduced_noise = np.zeros_like(raw_data)
# 設置降噪?yún)?shù)(可調(diào)整 prop_decrease 的值來改變降噪力度)
prop_decrease_value = 0.95
if 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
)
將降噪后的數(shù)據(jù)轉(zhuǎn)換回音頻并保存
# 將降噪后的數(shù)據(jù)轉(zhuǎn)換為 AudioSegment 對象
if audio.channels == 2:
# 將二維數(shù)組展平成一維交錯數(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。值越大,降噪力度越強。您可以通過調(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}")
# 對每個通道分別進行降噪
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
# 將降噪后的數(shù)據(jù)轉(zhuǎn)換回 AudioSegment 對象
# 注意,AudioSegment 需要一維數(shù)組,立體聲需要交錯的字節(jié)數(shù)據(jù)
# 將數(shù)組轉(zhuǎn)換為 bytes
if audio.channels == 2:
# 將二維數(shù)組轉(zhuǎn)換為交錯的一維數(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實現(xiàn)音頻降噪功能的詳細內(nèi)容,更多關(guān)于Python音頻降噪的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用wxPython實現(xiàn)逐行加載HTML內(nèi)容并實時顯示效果
這篇博客中,我們將詳細分析如何使用 wxPython 構(gòu)建一個簡單的桌面應用程序,用于逐行加載并顯示 HTML 文件的內(nèi)容,并在加載完成后通過瀏覽器組件呈現(xiàn)最終頁面,通過該應用,我們可以體驗到逐行加載 HTML 內(nèi)容的視覺效果,類似于模擬代碼輸入,需要的朋友可以參考下2024-11-11
python2和python3應該學哪個(python3.6與python3.7的選擇)
許多剛?cè)腴T Python 的朋友都在糾結(jié)的的問題是:我應該選擇學習 python2 還是 python3,Python 3.7 已經(jīng)發(fā)布了,目前Python的用戶,主要使用的版本 應該是 Python3.6 和 Python2.7 ,那么是不是該轉(zhuǎn)到 Python 3.7 呢2019-10-10
PyTorch模型轉(zhuǎn)TensorRT是怎么實現(xiàn)的?
今天給大家?guī)淼氖顷P(guān)于Python的相關(guān)知識,文章圍繞著PyTorch模型轉(zhuǎn)TensorRT是怎么實現(xiàn)的展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下2021-06-06
django ObjectDoesNotExist 和 DoesNotExist的用法
這篇文章主要介紹了django ObjectDoesNotExist 和 DoesNotExist的用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07
python中class(object)的含義是什么以及用法
這篇文章主要介紹了python中class(object)的含義是什么以及用法說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02

