0%

向信号中添加噪声

向一段信号中添加噪声,是不可以直接相加的,而是,需要根据信噪比来进行添加。


参考资料



理论


SNR

信噪比

$$ SNR = {P_{signal} \over P_{noise}} $$

为有用信号功率(Power of Signal)与噪声功率(Power of Noise)的比。

它的单位一般使用分贝(dB),其值为十倍对数信号与噪声功率比:

$$ SNR(dB) = 10 * log_{10} ({P_{signal} \over P_{noise}}) $$

或者

$$ SNR(dB) = 10 * log_{10} ({\sum_{n=0}^{N-1} {x^2 (n)} \over \sum_{n=0}^{N-1} {n^2 (n)} }) $$

其中,x(n)表示干净信号,n(n)表示噪声信号。


添加高斯噪声


高斯白噪声是均值为 0 方差为 1 的。

我们的目标是给原始信号x(n)加入多少分贝的高斯白噪声。已知信噪比SNR,则噪声功率的计算公式为:

$$ P_n = {P_s \over 10^{ SNR \over 10}} $$

噪声信号的计算公式为 $ n = \sqrt{Pn}\cdot len(x) $

生成高斯噪声

1
2
3
4
5
def get_white_noise(x, snr):
P_signal = np.sum(abs(x)**2)/len(x)
P_noise = P_signal/10**(snr/10.0)
white_noise = np.random.randn(len(x)) * np.sqrt(P_noise)
return white_noise

添加高斯噪声

1
2
3
4
5
6
def wgn(x, snr):
P_signal = np.sum(abs(x)**2)/len(x)
P_noise = P_signal/(10**((snr/10)))
white_noise = np.random.randn(len(x)) * np.sqrt(P_noise)
signal_add_noise = x + white_noise
return signal_add_noise

或者

1
2
3
def wgn(x, snr):
white_noise = get_white_noise(x,snr)
return signal_add_noise

添加其他噪声


1
2
3
4
5
6
7
def Add_noise(x, d, SNR):
P_signal=np.sum(abs(x)**2)
P_d=np.sum(abs(d)**2)
P_noise=P_signal/10**(SNR/10)
noise=np.sqrt(P_noise/P_d)*d
noise_signal=x+noise
return noise_signal

其他函数


1
2
3
4
5
6
7
8
9
10
def check_snr(signal, noise):
"""
:param signal: 原始信号
:param noise: 生成噪声
:return: 返回两者的信噪比
"""
signal_power = (1 / signal.shape[0]) * np.sum(np.power(signal, 2))
noise_power = (1 / noise.shape[0]) * np.sum(np.power(noise, 2))
SNR = 10 * np.log10(signal_power / noise_power)
return SNR
1
2
3
4
5
6
7
8
9
10
11
def numpy_SNR(origianl_waveform, target_waveform):
# 单位 dB
"""
:origianl_waveform: 去噪后的信号
:target_waveform: 原始干净信号
:return: 返回两者的信噪比
"""
signal = np.sum(origianl_waveform ** 2)
noise = np.sum((origianl_waveform - target_waveform) ** 2)
snr = 10 * np.log10(signal / noise)
return snr

ps: 往往数据处理完之后,还需要进行数据的归一化或者标准化,可以参考

请我喝杯咖啡吧~