You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

音频文件噪声量化与带噪/干净音频分类(非深度学习方案需求)

无参考噪声量化与通话音频分类方案(非深度学习)

核心思路

无需预先分离信号与噪声,通过提取音频统计特征或利用语音活动检测(VAD)量化噪声程度,进而实现带噪/干净通话音频的分类。

实用方案与Python实现

1. 频谱平坦度(Spectral Flatness Measure, SFM)

干净语音的频谱存在明显共振峰(陡峭的频谱形态),而交通等噪声的频谱更接近平坦分布。SFM取值范围为[0,1],越接近1说明音频越偏向噪声,越接近0则越接近干净语音。

import librosa
import numpy as np

def compute_sfm(audio_path):
    # 加载音频并保留原始采样率
    y, sr = librosa.load(audio_path, sr=None)
    # 计算全局频谱平坦度(也可按帧计算后取平均值)
    sfm = librosa.feature.spectral_flatness(y=y)
    return np.mean(sfm)

2. 基于VAD的噪声时长占比

通话数据天然包含语音段与静音/噪声段,用非深度学习VAD工具(如webrtcvad)检测语音活动,未被标记为语音的时段即为噪声段,计算噪声段时长占总时长的比例作为指标。比例越高,说明音频中噪声占比越大。

import webrtcvad
import librosa
import numpy as np

def compute_noise_duration_ratio(audio_path, vad_aggressiveness=3):
    # webrtcvad仅支持16kHz/32kHz/48kHz采样率,统一转换为16kHz
    y, sr = librosa.load(audio_path, sr=16000)
    # 转换为16位PCM格式(webrtcvad要求的输入格式)
    y_pcm = (y * 32767).astype(np.int16)
    
    vad = webrtcvad.Vad(vad_aggressiveness)
    # 帧长必须为10/20/30ms,选择20ms平衡精度与速度
    frame_ms = 20
    frame_len = int(sr * frame_ms / 1000)
    total_frames = len(y_pcm) // frame_len
    noise_frames = 0
    
    for i in range(total_frames):
        frame = y_pcm[i*frame_len : (i+1)*frame_len]
        # 判断当前帧是否为语音
        if not vad.is_speech(frame.tobytes(), sr):
            noise_frames += 1
    
    return noise_frames / total_frames

3. 短时能量与过零率组合特征

干净语音的短时能量波动大(语音有强弱变化),过零率低;噪声的能量相对平稳,过零率高。通过计算这两个特征的统计值,组合成噪声指标。

import librosa
import numpy as np

def compute_energy_zcr_metric(audio_path):
    y, sr = librosa.load(audio_path, sr=None)
    # 帧长20ms,步长10ms
    frame_len = int(sr * 0.02)
    hop_len = int(sr * 0.01)
    
    # 计算短时能量(用RMS近似)
    rms = librosa.feature.rms(y=y, frame_length=frame_len, hop_length=hop_len)
    energy_std = np.std(rms)  # 能量波动越小,噪声可能性越高
    
    # 计算过零率
    zcr = librosa.feature.zero_crossing_rate(y=y, frame_length=frame_len, hop_length=hop_len)
    zcr_mean = np.mean(zcr)  # 过零率越高,噪声可能性越高
    
    # 组合成指标(值越大,噪声越严重)
    return zcr_mean / (energy_std + 1e-6)  # 加1e-6避免除零错误

分类优化建议

单一指标可能存在误判,建议:

  • 组合上述多个特征(如SFM、噪声占比、能量标准差、过零率均值)作为输入特征
  • 用传统机器学习模型(如逻辑回归、SVM、随机森林)训练分类器,仅需少量标注的带噪/干净音频即可获得稳定的分类效果

关于SNR的说明

你提到的“均值除以标准差”并非标准SNR计算方式,标准SNR需要明确分离的信号与噪声数据。在无参考干净音频的场景下,无法计算真实SNR,上述方案均为无参考噪声量化指标,更适配你的需求。

内容的提问来源于stack exchange,提问作者Tushar Agarwal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 06:35:00