信噪比是科学和工程中使用的一种测量方法,用于比较所需信号水平与背景噪声水平。信噪比定义为信号功率与噪声功率之比,通常以分贝表示。高于 1:1(大于 0 dB)的比率表示信号大于噪声。
信噪比是影响处理或传输信号的系统(例如通信系统、音频系统、雷达系统、成像系统和数据采集系统)的性能和质量的重要参数。高信噪比意味着信号清晰且易于检测或解释,而低信噪比意味着信号被噪声破坏或遮蔽,可能难以区分或恢复。可以通过各种方法来提高信噪比,例如增加信号强度、降低噪声水平、滤除不需要的噪声或使用纠错技术。
信噪比的一种定义是信号(有意义的输入)的功率与背景噪声(无意义或不需要的输入)的功率之比:
S N R = P 信号 P 噪声 SNR =\frac{P_{\text {信号 }}}{P_{\text {噪声 }}} SNR=P噪声 P信号
其中 P P P 是平均功率。信号功率和噪声功率必须在系统中相同或等效的点以及相同的系统带宽内进行测量。
随机变量 ( S ) (S) (S) 与随机噪声 N N N 的信噪比为:
S N R = E [ S 2 ] E [ N 2 ] SNR =\frac{ E \left[S^2\right]}{ E \left[N^2\right]} SNR=E[N2]E[S2]
其中 E 指的是期望值,在本例中是 N N N 的均方。
如果信号只是 s s s 的常数值,则该方程简化为
S N R = s 2 E [ N 2 ] SNR =\frac{s^2}{ E \left[N^2\right]} SNR=E[N2]s2
如果噪声的预期值为零(通常如此),则分母是其方差,即其标准差的平方 σ N \sigma_{ N } σN。
信号和噪声必须以相同的方式测量,例如相同阻抗上的电压。它们的均方根也可以根据以下公式使用:
S N R = P 信号 P 噪声 = ( A 信号 A 噪声 ) 2 SNR =\frac{P_{\text {信号 }}}{P_{\text {噪声 }}}=\left(\frac{A_{\text {信号 }}}{A_{\text {噪声 }}}\right)^2 SNR=P噪声 P信号 =(A噪声 A信号 )2
其中 A A A 是均方根 (RMS) 幅度(例如,RMS 电压)。
一种情景,估算信号本身的功率,从而估算出信号与噪声功率之间的比率(假设噪声功率保持不变)。
S N R d b = 10 ⋅ log 10 P s − P n P n S N R_{d b}=10 \cdot \log _{10} \frac{P_s-P_n}{P_n} SNRdb=10⋅log10PnPs−Pn
另一种情景,使系统尽可能干净(例如,在单位增益下绕过或类似装置!),测量输入信号功率和输出信号功率,并假设它们之间的差异就是所添加的噪声水平:
P n = P o − P i P_n=P_o-P_i Pn=Po−Pi
其余换算与第一种情景相同。
import seaborn as sn
from scipy.stats import norm
import scipy.signal as sig
sr = 48000
T = 0.1 #seconds
N = int(T*sr)
n = arange(N)
t = n/sr
silence = zeros(N)
np.random.seed(1)
A = 1.0
a = 0.5
s = 0.1
powFund = A**2/2
powHarm = a**2/2
varnoise = s**2
f0 = 9000#*(sr/2)
h1 = f0*2.
noiseOnly = s*matlabRandn(len(t))
signalOnly = A * cos(pi*2*f0*t)
harmonicsOnly = a*sin(pi*2*t*h1)
y = signalOnly + harmonicsOnly + noiseOnly
faxis,psX = sig.periodogram(signalOnly,fs=sr, window=('kaiser',38))
faxis,psH = sig.periodogram(harmonicsOnly,fs=sr, window=('kaiser',38))
defSNR = 10*log10(powFund/varnoise)
print('SNR by definition, not computation: {} dB'.format(defSNR))
faxis,ps = sig.periodogram(y,fs=sr, window=('kaiser',38))
fundBin = argmax(ps)
_=plot(faxis,10*log10(ps), label='$y(n)$, the test signal')
_=plot(faxis,10*log10(psX),'--', label='$x(n)$, signal only', alpha=0.7)
_=plot(faxis,10*log10(psH),'--', label='$h(n)$, harmonics only', alpha=0.7)
title('Test Signal, SNR by definition: {} dB'.format(defSNR))
ylim([-100,0])
xlabel('Freq[Hz]')
ylabel('power [dB]')
legend()
grid(True)
输出
SNR by definition, not computation: 16.989700043360187 dB
def signalPower(x):
return average(x**2)
def SNR(signal, noise):
powS = signalPower(signal)
powN = signalPower(noise)
return 10*log10((powS-powN)/powN)
def SNRsystem(inputSig, outputSig):
noise = outputSig-inputSig
powS = signalPower(outputSig)
powN = signalPower(noise)
return 10*log10((powS-powN)/powN)
method1 = SNR(exampleOutput,noiseOnly)
print("Result Method 1: {} dB".format(method1))
输出
Result Method 1: 17.971278119623197 dB
method2 = SNRsystem(exampleInput,exampleOutput)
print("Result Method 2: {} dB".format(method2))
输出
Result Method 2: 5.7231662754316766 dB