我绑定了Matlab函数snr
,它是自R2013b以来信号处理工具箱的一部分。如Matlab文档中所述,此函数接受功率谱密度(PSD)估计作为输入。我虽然说:'这很酷!这意味着即使我不知道噪声是什么,我也可以计算出SNR。'
然而,snr
函数给出的结果不是SNR计算的标准公式,即SNR = 10 * log10(mean(signal.^2) / mean(noise.^2))
。差异大约为6 dB。
似乎用pwelch和fft两者的PSD估计过多地使噪声平滑,因此噪声功率变得比应有的小。如何使用snr
获得更准确的估算?
这是我的代码:
rng default
fs = 50e3;
sourceSig = sin(linspace(0,1,fs) .* 2 * pi * 100);
noise = 0.5 * rand(size(sourceSig));
noisySig = sourceSig + noise;
% calc SNR using equation
sigPow_check = 10 * log10(mean(sourceSig.^2)); % signal power
noisePow_check = 10 * log10(mean(noise.^2)); % noise power
SNR_check = sigPow_check - noisePow_check;
fprintf('\n calculation with equation: \n')
fprintf('SNR: %.2f dB \n', SNR_check)
fprintf('noise power: %.2f dB \n', noisePow_check)
fprintf('signal power: %.2f dB \n', sigPow_check)
% calc SNR using snr function and PSD, PSD estimated with pwelch
[pxx_1, f1] = pwelch(noisySig,[],[],[],fs);
[SNR_1, noisePow1] = snr(pxx_1,f1,'psd'); % in dB
fprintf('\n estimation with pwelch and snr: \n')
fprintf('SNR: %.2f dB \n', SNR_1)
fprintf('noise power: %.2f dB \n', noisePow1)
fprintf('signal power: %.2f dB \n', SNR_1+noisePow1)
% calc SNR using snr function and PSD, PSD estimated with fft
N = length(noisySig);
xdft = fft(noisySig);
xdft = xdft(1:N/2+1); % one sided spectrum
pxx_2 = ((1/(fs*N)) * abs(xdft).^2)'; % PSD
pxx_2(2:end-1) = 2*pxx_2(2:end-1); % scale
f2 = (0:fs/N:fs/2)'; % freq vector
[SNR_2, noisePow2] = snr(pxx_2,f2,'psd'); % in dB
fprintf('\n estimation with fft and snr: \n')
fprintf('SNR: %.2f dB \n', SNR_2)
fprintf('noise power: %.2f dB \n', noisePow2)
fprintf('signal power: %.2f dB \n', SNR_2+noisePow2)
控制台输出是:
calculation with equation:
SNR: 7.79 dB
noise power: -10.80 dB
signal power: -3.01 dB
estimation with pwelch and snr:
SNR: 13.77 dB
noise power: -16.77 dB
signal power: -3.00 dB
estimation with fft and snr:
SNR: 13.81 dB
noise power: -16.81 dB
signal power: -3.01 dB
答案 0 :(得分:0)
您的输入噪音不正确。通过使用noise = 0.5 * rand(size(sourceSig));
,函数rand
将产生正随机数,而这很少作为噪声出现。算法可能会产生意外的结果。您真的打算使用非居中噪音吗?
我建议您集中噪音:
a = 0.5;
noise = (a*rand(size(sourceSig)))-a/2;
结果是:
calculation with equation:
SNR: 13.80 dB
noise power: -16.81 dB
signal power: -3.01 dB
estimation with pwelch and snr:
SNR: 13.78 dB
noise power: -16.78 dB
signal power: -3.00 dB
estimation with fft and snr:
SNR: 13.81 dB
noise power: -16.81 dB
signal power: -3.01 dB
您也可以尝试randn
产生高斯噪声。