Modo corretto per aggiungere rumore al segnale

In molte aree ho scoperto che aggiungendo rumore, citiamo alcune specifiche come la media e la varianza zero. Devo aggiungere AWGN, rumore colorato, rumore uniforms di SNR variabile in Db. Il codice seguente mostra il modo in cui ho generato e aggiunto rumore. Sono consapevole della funzione awgn() ma è una specie di scatola nera senza sapere come si aggiunge il rumore. Quindi, qualcuno può spiegare il modo corretto di generare e aggiungere rumore. Grazie

 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 

Sto aggiungendo un’altra risposta poiché mi sembra che Steven’s non sia del tutto corretto e il suggerimento di Horchler di guardare all’interno della funzione awgn è buono.

Sia MATLAB che Octave (nella toolbox di comunicazione) hanno una funzione awgn che aggiunge il rumore (bianco gaussiano) per raggiungere il livello desiderato di potenza da segnale a rumore; la seguente è la porzione pertinente del codice (dalla funzione 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); 

Come puoi vedere dal modo in cui p (la potenza dei dati di input) è calcasting, la risposta di Steven non sembra essere abbastanza corretta.

È ansible chiedere alla funzione di calcolare la potenza totale dell'array di dati e combinarla con il valore s / n desiderato fornito per calcolare il livello di potenza appropriato del rumore aggiunto. Lo fai passando la stringa "misurata" tra gli ingressi opzionali, come questa (vedi qui per la documentazione di Octave o qui per la documentazione di MATLAB):

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

Questo porta alla fine a meas=1 e quindi meas==1 è vero nel codice sopra. La funzione awgn utilizza quindi il segnale passato ad esso per calcolare la potenza del segnale, e da questo e il s / n desiderato calcola quindi il livello di potenza appropriato per il rumore aggiunto.

Come spiega ulteriormente la documentazione

Di default si presuppone che snr e pwr siano rispettivamente in dB e dBW. Questo comportamento predefinito può essere scelto con il tipo impostato su "dB". Nel caso in cui type sia impostato su "linear", si presume che pwr sia in Watt e snr è un rapporto.

Ciò significa che è ansible passare un valore di snr negativo o di 0 dB. Il risultato dipenderà anche dalle altre opzioni che passerai, come la stringa "misurata".

Per il caso MATLAB suggerisco di leggere la documentazione , spiega come usare la funzione awgn in diversi scenari. Nota che le implementazioni in Octave e MATLAB non sono identiche, il calcolo della potenza del rumore dovrebbe essere lo stesso, ma potrebbero esserci diverse opzioni.

Ed ecco la parte rilevante di wgn (chiamata in precedenza da 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 

Se si desidera verificare la potenza del proprio disturbo ( np ), le funzioni awgn e awg presuppongono che le seguenti relazioni siano awgn :

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

dove var(...,1) è la varianza della popolazione per il rumore y .

La maggior parte delle risposte qui dimentica che l’SNR è specificato in decibel. Pertanto, non dovresti incontrare l’errore “divisione per 0”, perché dovresti realmente dividere per 10^(targetSNR/10) che non è mai negativo né zero per il targetSNR reale targetSNR .

Puoi usare randn () per generare un vettore di rumore ‘awgnNoise’ della lunghezza che vuoi. Quindi, dato un valore SNR specificato, calcola la potenza del segnale originale e la potenza del vettore di rumore “awgnNoise”. Ottieni il giusto fattore di ridimensionamento dell’ampiezza per il vettore del rumore e ridimensionalo.

Il seguente codice è un esempio per corrompere il segnale con rumore bianco, assumendo che il segnale di ingresso sia 1D e valutato reale.

 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 

Fai attenzione al fattore sqrt (2) quando gestisci un segnale complesso, se vuoi generare separatamente la parte reale e quella immaginaria.

Questo problema ‘should not divide by 0’ potrebbe essere risolto facilmente aggiungendo una condizione per verificare se targetSNR è 0 e farlo solo se non è 0. Quando il tuo SNR target è 0, significa che è puro rumore.

 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