2014-05-16 84 views
10

在許多領域,我發現在添加噪音的同時,我們提到了一些規格,如零均值和方差。我需要添加AWGN,有色噪聲,Db中不同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 
+0

您可以在命令窗口中查看'awgn'和'wgn'的所有代碼:type'edit awgn'或'edit wgn'。 – horchler

+0

Steven,信號功率計算是否正確?如果你檢查定義: http://www.gaussianwaves.com/2013/12/power-and-energy-of-a-signal/ 你不會在那裏找到一個sqrt ... 此外沒有sqrt信號由您的公式和使用差異計算的權力是相同的(他們應該是)。 – Lukasz

+0

由於許多不同的版本向信號添加噪聲,我有點困惑。我不想使用'awgn()'函數,並且僅基於想要知道如何添加特定方差和特定信噪比值的複雜噪聲的理論。 – SKM

回答

7

我加入另一個答案,因爲這讓我感到史蒂芬的說法並不正確,並Horchler的建議,看看裏面功能awgn是一個很好的一個。

MATLAB或Octave(在通信工具箱中)具有功能awgn,其增加(高斯白噪聲)以獲得期望的信噪功率電平;以下是代碼的相關部分(從八度音功能):

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(輸入數據的能力)的計算看,從史蒂芬答案似乎不是非常正確的。

您可以要求函數計算您的數據陣列的總功率,並將其與您提供的期望s/n值結合以計算所添加噪聲的適當功率電平。你這樣做是通過傳遞「測量」的字符串可選輸入中,像這樣的(見here爲Octave文檔或here的MATLAB文檔):

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

這導致最終meas=1meas==1是真正的上面的代碼。函數awgn然後使用傳遞給它的信號來計算信號功率,並且從這個和期望的s/n它然後計算對於所增加的噪聲適當的功率電平。

作爲文檔進一步解釋

默認情況下,SNR和PWR被假定爲在dB和DBW 分別。該默認行爲可以通過設置爲 「dB」的類型進行選擇。在類型被設置爲「線性」的情況下,pwr被假定爲以瓦特爲單位的 ,並且snr是比率。

這意味着您可以傳遞負值或0 dB snr值。結果也將取決於您傳遞的其他選項,例如字符串「測量」。

對於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

+0

謝謝你再次看到這個問題。我不太遵循如何應用變量meas(它在哪裏使用)。此外,這是如何處理負和零信噪比?說,如果SNR = -10作爲一個數字或SNR = 0? – SKM

+0

@SKM請參閱補充說明 –

+0

@SKM還增加了關於功率與真實/複雜數據關係的修正。 –

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一部分。

+0

忘了問一個問題,如果你願意回覆它 - 對於複雜的信號,你提到了sqrt(2)。我該如何去解決我在問題中發佈的方式?或者是其他東西?你能否也展示覆雜的信號?其次,我如何知道信號何時複雜? – SKM

+0

是的,你做得對。 – Steven

+1

它是否很複雜取決於仿真中信號的物理意義,例如如果它是正交調製信號將會很複雜。如果你的意思是在matlab中,你可以使用isreal()函數。 – Steven

0

如果你添加一個條件來檢查targetSNR是否爲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 
3

這裏的大多數答案都忘記了SNR是以分貝爲單位指定的。因此,你不應該遇到'除以0'的錯誤,因爲你應該真的除以10^(targetSNR/10),這對於真正的targetSNR來說不會是負數也不爲零。