1.信噪比的定义
英文名称叫做SNR或S/N(SIGNAL-NOISE RATIO),又称为讯噪比。是指一个电子设备或者电子系统中信号与噪声的比例。这里面的信号指的是来自设备外部需要通过这台设备进行处理的电子信号,噪声是指经过该设备后产生的原信号中并不存在的无规则的额外信号(或信息),并且该种信号并不随原信号的变化而变化。
2.计算方法
信噪比是一个比值,也可以认为是一种倍数,在通信和电子工程中,我们希望的是信噪比越高越好。比如说信号噪声的强度是噪声的10倍、100倍、1000倍,由于这个数字可能是一个很大很大的数字,所以我们采用分贝(dB)来表示。其定义为:“两个同类功率量或可与功率类比的量之比值的常用对数乘以10等于1时的级差” 。公式如下:
N d B = 10 l g P s P n N_{dB}=10\mathrm{lg}\frac{P_s}{P_n} NdB=10lgPnPs
因此信噪比的定义即:
S N R = 10 l g P s P n SNR=10\mathrm{lg}\frac{P_s}{P_n} SNR=10lgPnPs
其中 P s P_s Ps是信号的功率, P n P_n Pn是噪声的功率, l g \mathrm{lg} lg表示以10为底的对数。
假如说知道信噪比和信号功率,可以知道噪声功率为:
P n = P s 1 0 ( S N R / 10 ) P_n=\frac{P_s}{10^{(SNR/10)}} Pn=10(SNR/10)Ps
那对于一个数字信号而言,它的功率如何求呢?
假设数字信号 x ( n ) x(n) x(n)的序列长度为 N N N,那么它的功率就是:
P = ∑ n = 0 N − 1 x ( n ) 2 N P = \frac{\sum_{n=0}^{N-1}x(n)^{2}}{N} P=N∑n=0N−1x(n)2
在这里陈清一个概念,信号的功率由信号能量除以时间得到。信号能量在连续的情形就是对 x x x平方后求积分,而在离散的情形自然是求和代替积分了。
3.推导公式
信号的功率: P s P_s Ps,噪声的功率: P n P_n Pn,以及信噪比: S N R SNR SNR,三个值,只要知道其中的任意的两个值,便能够得到第三个值。
例如:由信号的功率: P s P_s Ps和信噪比: S N R SNR SNR,则噪声功率:
P n = P s 1 0 S N R / 10 P_n=\frac{P_s}{10^{SNR/10}} Pn=10SNR/10Ps
4.Matlab动手实现
先来生成一个信号:
T = 1; %仿真时间dt = 0.001; %采样率t = 0: dt: 1-dt; %时间向量N = length(t); %序列长度f = 5; %信号频率,Hz为单位a = cos(2*pi*f*t); %周期信号plot(t, a);p = sum(a.^2)/N;
该信号的功率:0.5 w。
白噪声的功率用其方差来定义。
如何产生白噪声呢?
Matlab中randn可以产生均值为0,方差为1(即功率为1)的随机序列。
n = randn(N,1); %产生噪声,功率为1plot(t,n)sum(n.^2)/N
如何产生指定功率的白噪声,例如我们要产生功率为 P n P_n Pn的白噪声:
n = sqrt(P_n)*randn(N,1); %产生噪声,功率为P_n
我们可以验证一下它的正确性:
p = 10; %功率为pnoise = sqrt(p)*randn(10000,1); %生成功率为p的噪声sum(noise.^2)/length(noise) %输出计算得到的噪声
输出:
ans = 9.9994
因此这样编程时正确的。我们还可以使用matlab自带的函数产生高斯白噪声。wgn(m,n,p)产生功率为p (dBW)的mn的高斯白噪声矩阵,其中p是以dbW为单位的输出强度。瓦和dB W之间的运算关系:
d B W = 10 l g ( P 1 W ) \mathrm{dBW} =10\mathrm{lg}(\frac{P}{1\mathrm{W}}) dBW=10lg(1WP)
因此,10w = 10log10(10)dbW。编程验证:
p = 10;noise = wgn(10000,1,10*log10(p));sum(noise.^2)/length(noise)
输出:
ans = 9.8748
有一点误差。
搞清楚如何生成固定信噪比的噪声后,在一个信号上添加指定信噪比的程序如下:
clc;clear all;close all;SNR = 10; %信噪比为10T = 1; %仿真时间dt = 0.001; %采样率t = 0: dt: 1-dt; %时间向量N = length(t); %序列长度f = 5; %信号频率,Hz为单位a = cos(2*pi*f*t); %周期信号plot(t, a, 'k');P_s = sum(a.^2)/N; %信号功率P_n = P_s/(10^(SNR/10)); %计算噪声功率n = sqrt(P_n)*randn(N,1); %产生噪声,功率为P_nhold on %保持绘图界面plot(t,n,'r');sum(n.^2)/Nnosie_a = a' + n; %添加噪声后的信号hold on %保持绘图界面plot(t,nosie_a,'g');legend('Pure signal','Noise','Noise signal');
4.自己编函数
以上的程序仅仅是给一个信号添加特定信噪比,为方便使用,可以编写一个函数。
%%-------------------------------------------------%% 给输入信号添加一定信噪比%% 输入参数 pureSignal : 输入信号%% SNR : 信噪比,dB为单位%% 输出参数 noiseSignal%% 输出参数 Location: 估计的时延参数 %%huasir @shenZhen%%2022.4.5%%-------------------------------------------------%%-------------------------------------------------function [noiseSignal] = mySNR(pureSignal, SNR)[m,n] = size(pureSignal);Power_pureSignal = sum(abs(pureSignal).^2)/length(pureSignal);Power_noise = Power_pureSignal/(10^(SNR/10)); %计算噪声功率noise = sqrt(Power_noise)*randn(m,n); %生成噪声noiseSignal = noise + pureSignal; %给信号添加噪声end
5.Matlab自带的函数
matlab中可以采用如下函数给信号添加一定噪声:
y = awgn(x,snr,'measured')
其中x是原始输入信号,snr即信噪比,'measured‘是指在添加噪声之前先测量一下输入信号的功率,加入没有这个参数的话,它会默认输入信号的功率为0。事实上,很多情况下我们的输入信号的功率不可能为0。
下面验证一下这段代码的正确性:
clc;clear all;close all;SNR = 10; %信噪比为10T = 1; %仿真时间dt = 0.001; %采样率t = 0: dt: 1-dt; %时间向量N = length(t); %序列长度f = 5; %信号频率,Hz为单位a = cos(2*pi*f*t); %周期信号plot(t, a, 'k');P_s = sum(a.^2)/N; %信号功率noise_a = awgn(a,SNR,'measured') ; %添加噪声后的信号,调用matlab函数hold on %保持绘图界面plot(t,noise_a,'g');legend('Pure signal','Noise signal');noise = noise_a - a; %做差求噪声P_n = sum(noise.^2)/N;my_SNR = 10*log10(P_s/P_n) %计算得到的信噪比
我设置的信噪比是10,最终计算得到的信噪比是
my_SNR = 9.8643
有一定误差,目前暂不明确为什么会出现这种情况。