正确的方法来增加信号噪音

时间:2014-05-16 00:21:34

标签: matlab signal-processing noise

在许多领域我发现在添加噪声的同时,我们提到了一些规范,如零均值和方差。我需要在Db中添加AWGN,有色噪声,不同SNR的均匀噪声。以下代码显示了我生成和添加噪声的方式。我知道函数awgn()但它是一种黑盒子的东西,不知道如何添加噪声。那么,有人可以解释生成和添加噪声的正确方法。谢谢

SNR = [-10:5:30]; %in Db
snr = 10 .^ (0.1 .* SNR);

for I = 1:length(snr)
    noise = 1 / sqrt(2) * (randn(1, N) + 1i * randn(1, N));
    u = y + noise .* snr(I);
end

4 个答案:

答案 0 :(得分:8)

我添加了另一个答案,因为我觉得Steven不太正确,而Horchler建议查看函数awgn是一个很好的答案。

MATLAB或Octave(在通信工具箱中)具有函数awgn,其增加(白高斯)噪声以获得所需的信噪功率水平;以下是代码的相关部分(来自Octave函数):

  if (meas == 1)  % <-- if using signal power to determine appropriate noise power
    p = sum( abs( x(:)) .^ 2) / length(x(:));
    if (strcmp(type,"dB"))
      p = 10 * log10(p);
    endif
  endif

  if (strcmp(type,"linear"))
    np = p / snr;
  else   % <-- in dB
    np = p - snr;
  endif

  y = x + wgn (m, n, np, 1, seed, type, out);

正如您所看到的那样p(输入数据的力量)的计算方式,Steven的答案看起来并不完全正确。

您可以要求该函数计算数据阵列的总功率,并将其与您提供的所需s / n值相结合,以计算增加噪声的适当功率级别。你通过传递字符串&#34;测量&#34;在可选输入中,如下所示(有关Octave文档,请参阅here,有关MATLAB文档,请参阅here):

     y = awgn (x, snr, 'measured')

这最终导致meas=1,因此meas==1在上面的代码中为真。函数awgn然后使用传递给它的信号来计算信号功率,然后根据它和期望的s / n计算增加的​​噪声的适当功率电平。

正如文件进一步解释

  

默认情况下,假设snr和pwr为dB和dBW   分别。可以在类型设置为的情况下选择此默认行为   &#34;分贝&#34 ;.在type设置为&#34; linear&#34;的情况下,假设pwr为   在瓦特和snr是一个比例。

这意味着您可以传递负值或0 dB snr值。结果还取决于您传递的其他选项,例如字符串&#34;测量&#34;。

对于MATLAB案例,我建议阅读documentation,它解释了如何在不同的场景中使用函数awgn。请注意,Octave和MATLAB中的实现并不相同,噪声功率的计算应该相同,但可能有不同的选项。

以下是wgn的相关部分(上文awgn调用):

  if (strcmp(type,"dBW"))
    np = 10 ^ (p/10);
  elseif (strcmp(type,"dBm"))
    np = 10 ^((p - 30)/10);
  elseif (strcmp(type,"linear"))
    np = p;
  endif

  if(!isempty(seed))
    randn("state",seed);
  endif

  if (strcmp(out,"complex"))
    y = (sqrt(imp*np/2))*(randn(m,n)+1i*randn(m,n)); % imp=1 assuming impedance is 1 Ohm
  else
    y = (sqrt(imp*np))*randn(m,n);
  endif

如果您想检查噪音(np)的功效,awgnawg功能会假设以下关系:

  np = var(y,1);        % linear scale
  np = 10*log10(np);    % in dB 

其中var(...,1)是噪音y种群方差。

答案 1 :(得分:3)

这里的大多数答案都忘记了SNR以分贝为单位。因此,你不应该遇到'除以0'错误,因为你应该真正除以10^(targetSNR/10),它对于真正的targetSNR来说永远不会为负,也不会为零。

答案 2 :(得分:1)

您可以使用randn()生成所需长度的噪声向量'awgnNoise'。然后,给定指定的SNR值,计算原始信号的功率和噪声矢量'awgnNoise'的功率。 为噪声向量获得正确的幅度缩放因子,然后对其进行缩放。

下面的代码是一个用白噪声破坏信号的例子,假设输入信号是1D和实值。

function out_signal = addAWGN(signal, targetSNR)
sigLength = length(signal); % length
awgnNoise = randn(size(signal)); % orignal noise
pwrSig = sqrt(sum(signal.^2))/sigLength; % signal power
pwrNoise = sqrt(sum(awgnNoise.^2))/sigLength; % noise power

scaleFactor = (pwrSig/pwrNoise)/targetSNR; %find scale factor
awgnNoise = scaleFactor*awgnNoise; 
out_signal = signal + awgnNoise; % add noise

处理复杂信号时要小心sqrt(2)因子,如果你想分别生成real和imag部分。

答案 3 :(得分:1)

如果添加一个条件来检查targetSNR是否为0,那么'不应该除以0'问题可以很容易地解决。只有当它不是0时才这样做。当你的目标SNR为0时,这意味着它是纯噪声。

function out_signal = addAWGN(signal, targetSNR)
sigLength = length(signal); % length
awgnNoise = randn(size(signal)); % orignal noise
pwrSig = sqrt(sum(signal.^2))/sigLength; % signal power
pwrNoise = sqrt(sum(awgnNoise.^2))/sigLength; % noise power
if targetSNR ~= 0
   scaleFactor = (pwrSig/pwrNoise)/targetSNR; %find scale factor
   awgnNoise = scaleFactor*awgnNoise; 
   out_signal = signal + awgnNoise; % add noise
else
   out_signal = awgnNoise; % noise only
end