目录 信噪比(SNR) 峰值信噪比(PSNR) 分段信噪比(SegSNR) 对数拟然对比度(log Likelihood Ratio Measure) PESQ 对数谱距离(Log Spectral Distance) 参考文献: 信噪比(SNR) 有用信号功率与噪声功率的比(此处功率为平均功率),也等于幅度比的平方 SNR(dB)=10log10∑N−1n=0s2(n)∑N−1n=0d2(n)=10∗log10(PsignalPnoise)=20∗log10(AsignalAnoise) SNR(dB)=10log10∑N−1n=0s2(n)∑N−1n=0[x(n)−s(n)2] 其中: Psignal为信号功率;Pnoise为噪声功率;Asignal为信号幅度;Anoise为噪声幅度值,功率等于幅度值的平方 MATLAB版本代码 View Code python代码 复制代码 def numpy_SNR(origianl_waveform, target_waveform): # 单位 dB signal = np.sum(origianl_waveform ** 2) noise = np.sum((origianl_waveform - target_waveform) ** 2) snr = 10 * np.log10(signal / noise) return snr 复制代码 np.linalg.norm(x)=x21+x22+...+x2n−−−−−−−−−−−−−√ 这个公式和上面是一样的 复制代码 def wav_snr(ref_wav, in_wav):# 如果ref wav稍长,则用0填充in_wav if (abs(in_wav.shape[0] - ref_wav.shape[0]) < 10): pad_width = ref_wav.shape[0] - in_wav.shape[0] in_wav = np.pad(in_wav, (0, pad_width), 'constant') else: print("错误:参考wav与输入wav的长度明显不同") return -1 # 计算 SNR norm_diff = np.square(np.linalg.norm(in_wav - ref_wav)) if (norm_diff == 0): print("错误:参考wav与输入wav相同") return -1 ref_norm = np.square(np.linalg.norm(ref_wav)) snr = 10 * np.log10(ref_norm / norm_diff) return snr 复制代码 峰值信噪比(PSNR) 表示信号的最大瞬时功率和噪声功率的比值,最大瞬时功率为语音数据中最大值得平方。 SNR(dB)=10∗log10(MAX(Psignal)Pnoise)=10log10MAX[s(n)]2d2(n) SNR(dB)=10log10MAX[s(n)]21N∑N−1n=0[x(n)−s(n)]2=20log10MAX[s(n)]MSE−−−−−√ 复制代码 import numpy as np def psnr(ref_wav, in_wav): MSE = numpy.mean((ref_wav - in_wav) ** 2) MAX = np.max(ref_wav) # 信号的最大平时功率 return 20 * np.log10(MAX / np.sqrt(MSE)) 复制代码 分段信噪比(SegSNR)   由于语音信号是一种缓慢变化的短时平稳信号,因而在不同时间段上的信噪比也应不一样。为了改善上面的问题,可以采用分段信噪比。分段信噪比即是先对语音进行分帧,然后对每一帧语音求信噪比,最好求均值。 MATLAB版本的代码 MATLAB版本代码 View Code python代码 复制代码 def SegSNR(ref_wav, in_wav, windowsize, shift): if len(ref_wav) == len(in_wav): pass else: print('音频的长度不相等!') minlenth = min(len(ref_wav), len(in_wav)) ref_wav = ref_wav[: minlenth] in_wav = in_wav[: minlenth] # 每帧语音中有重叠部分,除了重叠部分都是帧移,overlap=windowsize-shift # num_frame = (len(ref_wav)-overlap) // shift # num_frame = (len(ref_wav)-windowsize+shift) // shift num_frame = (len(ref_wav) - windowsize) // shift + 1 # 计算帧的数量 SegSNR = np.zeros(num_frame) # 计算每一帧的信噪比 for i in range(0, num_frame): noise_frame_energy = np.sum(ref_wav[i * shift, i * shift+windowsize] ** 2) # 每一帧噪声的功率 speech_frame_energy = np.sum(in_wav[i * shift, i * shift+windowsize] ** 2) # 每一帧信号的功率 SegSNR[i] = np.log10(speech_frame_energy / noise_frame_energy) return 10 * np.mean(SegSNR) 复制代码 对数拟然对比度(log Likelihood Ratio Measure)   坂仓距离测度是通过语音信号的线性预测分析来实现的。ISD基于两组线性预测参数(分别从原纯净语音和处理过的语音的同步帧得到)之间的差异。LLR可以看成一种坂仓距离(Itakura Distance,IS)但是IS距离需要考虑模型增益。而LLR不需要考虑模型争议引起的幅度位移,更重视整体谱包络的相似度。 PESQ   PESQ是用于语音质量评估的一种方法,ITU提供了C语言代码,下载请点击这里,但是在使用之前我们需要先编译C脚本,生成可执行文件exe 编译方式为:在命令行进入下载好的文件 cd \Software\source gcc -o PESQ *.c   经过编译,会在当前文件夹生成一个pesq.exe的可执行文件 使用方式为: 命令行进入pesq.exe所在的文件夹 执行命令:pesq 采样率 "原始文件路径名" "劣化文件路径名” 回车 等待结果即可,值越大,质量越好。 例如:pesq +16000 raw.wav processed.wav 对数谱距离(Log Spectral Distance) 两个频谱之间的距离度量(用分贝表示)。两个频谱P(W)和P^(w)之间的对数谱距离被定义为: DLS=12π∫π−π[10∗log10P(w)P^(w)]2dw−−−−−−−−−−−−−−−−−−−−−−√ 其中,p(w)和P^(w)是功率谱。对数谱距离是时多对称的。 复制代码 def numpy_LSD(origianl_waveform, target_waveform): """ 比较原始和目标音频之间的对数谱距离(LSD),也称为对数谱失真, 是两个频谱之间的距离测量值(以dB表示) """ print("数据形状为", origianl_waveform.shape) print("数据类型为", type(origianl_waveform)) original_spectrogram = librosa.core.stft(origianl_waveform, n_fft=2048) target_spectrogram = librosa.core.stft(target_waveform, n_fft=2048) original_log = np.log10(np.abs(original_spectrogram) ** 2) target_log = np.log10(np.abs(target_spectrogram) ** 2) original_target_squared = (original_log - target_log) ** 2 target_lsd = np.mean(np.sqrt(np.mean(original_target_squared, axis=0))) return target_lsd 复制代码 参考文献: 非典型废言的CSDN博客 视频质量度量指标 作者:凌逆战 欢迎任何形式的转载,但请务必注明出处。 限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。 本文章不做任何商业用途,仅作为自学所用,文章后面会有参考链接,我可能会复制原作者的话,如果介意,我会修改或者删除。https://www.cnblogs.com/LXP-Never/p/11071911.html