如何计算含脉冲噪声曲线的SNR及滤波后的信噪比提升
MATLAB中信噪比(SNR)计算与滤波效果评估方案
一、SNR核心计算逻辑
信噪比(dB)的计算公式为:SNR(dB) = 10×log₁₀(信号功率 / 噪声功率)
其中:
- 信号功率:干净信号的平方均值
Pₛ = mean(s.²) - 噪声功率:噪声分量的平方均值
Pₙ = mean((x - s).²)(x为加噪/滤波后信号,s为对应干净信号)
二、修正加噪代码(避免索引越界)
原加噪循环存在索引越界问题,调整为随机选取干净信号生成1000组加噪数据,同时存储对应干净信号用于后续SNR计算:
cd 'C:blah\blah\' z_numfiles = 100; for k = 1:z_numfiles myfilename = sprintf('scope_%d.csv', k); nometal{k} = xlsread(myfilename, 'C4:C500'); end % 修正后的加噪流程 pd1 = makedist('Stable','alpha',0.5,'beta',0,'gam',0.001,'delta',0); distr_puls_nometal = cell(1000, 1); clean_corresponding = cell(1000, 1); % 存储加噪信号对应的干净信号 samplesize = 497; for m = 1:1000 k = randi(100); % 随机选一组干净信号 s = cell2mat(nometal{k}); temp = s; for i = 1:samplesize a = random(pd1); temp(i) = temp(i) + a; temp(i) = max(0, min(3, temp(i))); % 限幅简化写法 end distr_puls_nometal{m} = temp; clean_corresponding{m} = s; end
三、计算加噪后SNR下降幅度
批量计算所有加噪信号的SNR,并与干净信号的SNR对比得到下降幅度:
SNR_noisy = zeros(1000, 1); SNR_clean = zeros(1000, 1); for m = 1:1000 s = clean_corresponding{m}; x = distr_puls_nometal{m}; noise = x - s; P_s = mean(s.^2); P_n = mean(noise.^2); P_n = max(P_n, 1e-10); % 避免除以0 SNR_noisy(m) = 10*log10(P_s / P_n); % 计算干净信号的固有SNR(以自身波动为噪声) P_n_clean = var(s - mean(s)); P_n_clean = max(P_n_clean, 1e-10); SNR_clean(m) = 10*log10(P_s / P_n_clean); end avg_SNR_drop = mean(SNR_clean - SNR_noisy); fprintf('加噪后平均SNR下降幅度:%.2f dB\n', avg_SNR_drop);
四、评估滤波后的SNR提升效果
假设已用滚动均值和分块算术均值滤波,计算滤波后的SNR并对比加噪信号的SNR:
% 滤波处理(窗口/块大小设为5,可按需调整) window_size = 5; block_size = 5; filtered_rolling = cell(1000, 1); filtered_mean = cell(1000, 1); clean_filtered_rolling = cell(1000, 1); clean_filtered_mean = cell(1000, 1); for m = 1:1000 x = distr_puls_nometal{m}; s = clean_corresponding{m}; % 滚动均值滤波(丢弃端点) filtered_rolling{m} = movmean(x, window_size, 'Endpoints', 'discard'); clean_filtered_rolling{m} = movmean(s, window_size, 'Endpoints', 'discard'); % 分块算术均值滤波 num_blocks = floor(samplesize / block_size); mean_block = zeros(num_blocks, 1); s_mean_block = zeros(num_blocks, 1); for b = 1:num_blocks idx = (b-1)*block_size+1 : b*block_size; mean_block(b) = mean(x(idx)); s_mean_block(b) = mean(s(idx)); end filtered_mean{m} = mean_block; clean_filtered_mean{m} = s_mean_block; end % 计算滤波后SNR及提升幅度 SNR_rolling = zeros(1000, 1); SNR_mean = zeros(1000, 1); for m = 1:1000 % 滚动均值滤波SNR s_roll = clean_filtered_rolling{m}; x_roll = filtered_rolling{m}; noise_roll = x_roll - s_roll; P_s_roll = mean(s_roll.^2); P_n_roll = mean(noise_roll.^2); P_n_roll = max(P_n_roll, 1e-10); SNR_rolling(m) = 10*log10(P_s_roll / P_n_roll); % 算术均值滤波SNR s_mean = clean_filtered_mean{m}; x_mean = filtered_mean{m}; noise_mean = x_mean - s_mean; P_s_mean = mean(s_mean.^2); P_n_mean = mean(noise_mean.^2); P_n_mean = max(P_n_mean, 1e-10); SNR_mean(m) = 10*log10(P_s_mean / P_n_mean); end avg_SNR_boost_rolling = mean(SNR_rolling - SNR_noisy(1:length(SNR_rolling))); avg_SNR_boost_mean = mean(SNR_mean - SNR_noisy(1:length(SNR_mean))); fprintf('滚动均值滤波平均SNR提升:%.2f dB\n', avg_SNR_boost_rolling); fprintf('算术均值滤波平均SNR提升:%.2f dB\n', avg_SNR_boost_mean);
五、对其他噪声分布的适用性分析
- 高斯/均匀白噪声:均值类滤波效果显著,因为这类噪声均值为0,多次平均后噪声功率会按比例降低(算术均值噪声功率为原噪声的1/N,N为平均次数),滚动均值窗口越大降噪越强,但会损失信号细节。
- 脉冲噪声(如椒盐噪声):均值类滤波效果有限,脉冲的极端值会拉高窗口/块的均值,无法有效抑制脉冲;此时中值滤波是更优选择。
- 有色噪声(如粉红噪声):均值类滤波本质是低通滤波,对低频占优的有色噪声抑制效果差,需改用自适应滤波或频域滤波方法。
- 其他重尾分布噪声:和alpha稳定分布类似,均值类滤波受极端值影响大,降噪效果弱于针对重尾噪声的专用滤波器(如分数低阶统计量滤波器)。
内容的提问来源于stack exchange,提问作者ChrisD91
相关产品推荐
相关产品推荐

