matlab - 如何使用Matlab函数snr()获得准确的估计?

标签 matlab signal-processing noise

我绑定(bind)了 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 

最佳答案

您输入的噪音不正确。通过使用 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产生高斯噪声。

关于matlab - 如何使用Matlab函数snr()获得准确的估计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48625566/

相关文章:

python - 在python中快速生成3D噪声

audio - FFMPEG(输入 8K AAC ->(AAC FLV)youtube 流媒体噪音

c - 外部变量 mex 文件

matlab - 为matlab中的多个单元格赋值

matlab - MATLAB 编译器的安全性

math - 绘制周期性时间序列的 FFT 的实部与虚部时,对称性意味着什么

matlab - wav文件和FFT的matlab中的Audioread

c# - 如何检测图像中能量最低的区域

matlab - 奈奎斯特准则 - 算法中的 undefined variable

python - 这是什么声音?