这个问题可以分解为两个主要部分:1. 噪音抑制 (Noise Reduction) 和 2. 人声增强 (Voice Enhancement)。
我们将从简单到复杂,介绍几种不同的方法和对应的库。
核心库
在开始之前,请确保安装了必要的 Python 库:
# noisereduce 是一个专门用于降噪的库 pip install noisereduce # librosa 和 soundfile 用于音频的读取和处理 pip install librosa soundfile # pydub 用于简单的音频操作,如音量调整 pip install pydub # scipy 提供了强大的信号处理工具,如滤波器 pip install scipy numpy
方法一:使用 noisereduce 库(最简单、最直接)
noisereduce 是一个基于谱减法 (Spectral Subtraction) 的降噪库,它非常易于使用,效果也很不错,特别适合处理有稳定背景噪音(如风扇声、空调声)的音频。
工作原理:
你提供一段纯噪音的音频片段(例如,说话前几秒的静音部分)。
库会分析这段噪音的频谱特征(“噪音轮廓”)。
然后,它会从整个音频的频谱中减去这个噪音轮廓,从而达到降噪的目的。
代码示例:
import soundfile as sf import noisereduce as nr import numpy as np # 1. 读取音频文件 # soundfile.read 会返回音频数据(numpy array)和采样率 audio_data, sample_rate = sf.read("your_audio_with_noise.wav") # 假设音频的前2秒是纯噪音 # 注意:如果你的音频数据是多声道的,需要先处理成单声道 if audio_data.ndim > 1: audio_data = np.mean(audio_data, axis=1) # 转为单声道 noise_len_seconds = 2 noise_clip = audio_data[:int(noise_len_seconds * sample_rate)] # 2. 执行降噪 # prop_decrease 控制降噪的强度,值在 0 到 1 之间 reduced_noise_audio = nr.reduce_noise(y=audio_data, sr=sample_rate, y_noise=noise_clip, prop_decrease=1.0) # 3. 保存处理后的音频 sf.write("audio_reduced_noise.wav", reduced_noise_audio, sample_rate) print("降噪完成!文件已保存为 audio_reduced_noise.wav")
优点:
简单易用:几行代码就能搞定。
效果显著:对于稳态噪音效果很好。
缺点:
需要纯噪音片段:如果找不到纯噪音片段,效果会打折扣。
可能产生伪影:降噪强度过高时,可能会引入一些“音乐伪影”(musical artifacts),听起来有点像水流声。
方法二:结合传统信号处理技术(更灵活、更可控)
如果你想有更多的控制权,或者处理的噪音类型更复杂,可以结合使用滤波器和音量标准化等技术。
步骤 1: 使用高通滤波器去除低频噪音人声主要集中在 85Hz - 1100Hz 范围内。而很多背景噪音(如电流声、空调的嗡嗡声)是低频的。我们可以使用一个高通滤波器(High-pass Filter)来滤除这些低于人声基频的噪音。
from scipy.signal import butter, lfilter def high_pass_filter(data, cutoff, fs, order=5): """ 设计并应用一个高通滤波器。 :param data: 音频数据 (numpy array) :param cutoff: 截止频率 (Hz) :param fs: 采样率 (Hz) :param order: 滤波器阶数 :return: 滤波后的数据 """ nyq = 0.5 * fs normal_cutoff = cutoff / nyq b, a = butter(order, normal_cutoff, btype='high', analog=False) y = lfilter(b, a, data) return y # 假设 audio_data 和 sample_rate 已经加载 # 为人声设置一个合理的截止频率,比如 80Hz filtered_audio = high_pass_filter(audio_data, cutoff=80, fs=sample_rate)步骤 2: 人声增强
降噪后,我们可能需要对人声本身进行增强,使其更清晰、更突出。
a) 音量标准化 (Normalization)将音频的峰值调整到一个标准水平(如 -1 dBFS),可以防止削波并确保音量一致。
import numpy as np def normalize(data, target_dbfs=-1.0): """将音频标准化到目标分贝水平""" peak = np.max(np.abs(data)) if peak == 0: return data # 计算需要的增益 ratio = 10**(target_dbfs / 20.0) # 应用增益 normalized_data = data / peak * ratio return normalized_data # 标准化上面滤波后的音频 normalized_audio = normalize(filtered_audio)
b) 动态范围压缩 (Dynamic Range Compression)压缩器可以减小音频中最大声和最小声的差距。这能让人声中较轻柔的部分变得更清晰,而不会让大声的部分变得刺耳。pydub 库可以很方便地实现这个功能。
from pydub import AudioSegment from pydub.effects import compress_dynamic_range import io # 需要先将 numpy array 转换为 pydub 的 AudioSegment 对象 # 注意:需要知道原始音频的位深度 (sample_width) # 假设是16-bit PCM audio_segment = AudioSegment( normalized_audio.tobytes(), frame_rate=sample_rate, sample_width=normalized_audio.dtype.itemsize, # 假设是 float32,则为 4 channels=1 ) # 应用动态范围压缩 compressed_audio_segment = compress_dynamic_range(audio_segment) # 如果需要,可以再转换回 numpy array 进行后续处理 # compressed_audio_data = np.array(compressed_audio_segment.get_array_of_samples()) # ... # 或者直接导出 compressed_audio_segment.export("audio_enhanced.wav", format="wav")
方法三:使用深度学习模型(效果最好、最前沿)
对于非稳态、复杂的背景噪音(如街道声、其他人说话的声音),传统方法效果有限。这时,深度学习模型就派上用场了。这些模型通过在大量数据上训练,学会了区分人声和各种噪音。
推荐模型:Facebook's DemucsDemucs 最初是为音乐源分离(将鼓、贝斯、人声等分离)而设计的,但它在分离人声和背景噪音方面表现极其出色。
如何使用:
安装 demucs:
pip install -U demucs
注意:可能需要 PyTorch,如果安装时遇到问题,请先根据你的 CUDA 版本(或CPU)安装 PyTorch。 pip install torch torchvision torchaudio
使用命令行工具(最简单):demucs 提供了一个非常方便的命令行工具。
# --two-stems=vocals 会将音频分离成 "人声" 和 "其他" python -m demucs --two-stems=vocals "your_audio_with_noise.wav"
执行后,会在一个名为 separated/htdemucs 的目录下找到两个文件:
vocals.wav (纯净的人声)
no_vocals.wav (背景噪音)
优点:
效果顶尖:能够处理极其复杂的噪音场景,分离出的人声非常干净。
无需噪音样本:模型是预训练好的,不需要你提供纯噪音片段。
缺点:
计算密集:处理速度比传统方法慢,可能需要 GPU 来加速。
环境配置:依赖 PyTorch,环境配置可能比普通库复杂一些。
总结与建议
快速入门/处理稳态噪音:
首选 noisereduce。它简单、快速,效果立竿见影。
需要精细控制/学习原理:
使用 scipy.signal 进行滤波(如高通滤波),再结合 pydub 或自定义的标准化、压缩函数进行人声增强。这是一个很好的学习信号处理的实践。
追求最佳效果/处理复杂噪音:
毫无疑问,选择 demucs 这样的深度学习模型。它代表了目前最先进的水平,能给你带来惊喜。
完整流程建议:一个通用的高质量处理流程可以是:
使用 demucs 分离出纯净人声。
对分离出的人声 vocals.wav 文件,使用 pydub 或其他工具进行音量标准化和动态范围压缩,使其听感更好。
网友回复