Saltar al contenido

agregando ruido a una señal en python

Después de consultar expertos en el tema, programadores de deferentes ramas y profesores hemos dado con la solución al dilema y la plasmamos en este post.

Solución:

Puedes generar un ruido arrayy añádelo a tu señal

import numpy as np

noise = np.random.normal(0,1,100)

# 0 is the mean of the normal distribution you are choosing from
# 1 is the standard deviation of the normal distribution
# 100 is the number of elements you get in array noise

… Y para aquellos que, como yo, están muy temprano en su curva de aprendizaje,

import numpy as np
pure = np.linspace(-1, 1, 100)
noise = np.random.normal(0, 1, 100)
signal = pure + noise

Para aquellos que intentan establecer la conexión entre SNR y una variable aleatoria normal generada por numpy:

[1] relación SNR

donde es importante tener en cuenta que P es promedio energía.

O en dB:
[2] SNR dB2

En este caso, ya tenemos una señal y queremos generar ruido para darnos una SNR deseada.

Si bien el ruido puede tener diferentes sabores según lo que esté modelando, un buen comienzo (especialmente para este ejemplo de radiotelescopio) es el ruido gaussiano blanco aditivo (AWGN). Como se indicó en las respuestas anteriores, para modelar AWGN necesita agregar una variable aleatoria gaussiana de media cero a su señal original. La varianza de esa variable aleatoria afectará la promedio potencia de ruido

Para una variable aleatoria gaussiana X, la potencia promedio episodiotambién conocido como el segundo momento, es
[3] Ex

Así que para el ruido blanco, Ex y la potencia media es entonces igual a la varianza Ex.

Al modelar esto en python, puede
1. Calcule la varianza en función de una SNR deseada y un conjunto de mediciones existentes, lo que funcionaría si espera que sus mediciones tengan valores de amplitud bastante consistentes.
2. Alternativamente, puede configurar la potencia del ruido a un nivel conocido para que coincida con algo como el ruido del receptor. El ruido del receptor podría medirse apuntando el telescopio al espacio libre y calculando la potencia promedio.

De cualquier manera, es importante asegurarse de agregar ruido a su señal y tomar promedios en el espacio lineal y no en unidades de dB.

Aquí hay un código para generar una señal y trazar el voltaje, la potencia en vatios y la potencia en dB:

# Signal Generation
# matplotlib inline

import numpy as np
import matplotlib.pyplot as plt

t = np.linspace(1, 100, 1000)
x_volts = 10*np.sin(t/(2*np.pi))
plt.subplot(3,1,1)
plt.plot(t, x_volts)
plt.title('Signal')
plt.ylabel('Voltage (V)')
plt.xlabel('Time (s)')
plt.show()

x_watts = x_volts ** 2
plt.subplot(3,1,2)
plt.plot(t, x_watts)
plt.title('Signal Power')
plt.ylabel('Power (W)')
plt.xlabel('Time (s)')
plt.show()

x_db = 10 * np.log10(x_watts)
plt.subplot(3,1,3)
plt.plot(t, x_db)
plt.title('Signal Power in dB')
plt.ylabel('Power (dB)')
plt.xlabel('Time (s)')
plt.show()

Señal generada

Aquí hay un ejemplo para agregar AWGN basado en una SNR deseada:

# Adding noise using target SNR

# Set a target SNR
target_snr_db = 20
# Calculate signal power and convert to dB 
sig_avg_watts = np.mean(x_watts)
sig_avg_db = 10 * np.log10(sig_avg_watts)
# Calculate noise according to [2] then convert to watts
noise_avg_db = sig_avg_db - target_snr_db
noise_avg_watts = 10 ** (noise_avg_db / 10)
# Generate an sample of white noise
mean_noise = 0
noise_volts = np.random.normal(mean_noise, np.sqrt(noise_avg_watts), len(x_watts))
# Noise up the original signal
y_volts = x_volts + noise_volts

# Plot signal with noise
plt.subplot(2,1,1)
plt.plot(t, y_volts)
plt.title('Signal with noise')
plt.ylabel('Voltage (V)')
plt.xlabel('Time (s)')
plt.show()
# Plot in dB
y_watts = y_volts ** 2
y_db = 10 * np.log10(y_watts)
plt.subplot(2,1,2)
plt.plot(t, 10* np.log10(y_volts**2))
plt.title('Signal with noise (dB)')
plt.ylabel('Power (dB)')
plt.xlabel('Time (s)')
plt.show()

Señal con objetivo SNR

Y aquí hay un ejemplo para agregar AWGN basado en una potencia de ruido conocida:

# Adding noise using a target noise power

# Set a target channel noise power to something very noisy
target_noise_db = 10

# Convert to linear Watt units
target_noise_watts = 10 ** (target_noise_db / 10)

# Generate noise samples
mean_noise = 0
noise_volts = np.random.normal(mean_noise, np.sqrt(target_noise_watts), len(x_watts))

# Noise up the original signal (again) and plot
y_volts = x_volts + noise_volts

# Plot signal with noise
plt.subplot(2,1,1)
plt.plot(t, y_volts)
plt.title('Signal with noise')
plt.ylabel('Voltage (V)')
plt.xlabel('Time (s)')
plt.show()
# Plot in dB
y_watts = y_volts ** 2
y_db = 10 * np.log10(y_watts)
plt.subplot(2,1,2)
plt.plot(t, 10* np.log10(y_volts**2))
plt.title('Signal with noise')
plt.ylabel('Power (dB)')
plt.xlabel('Time (s)')
plt.show()

Señal con nivel de ruido objetivo

Aquí puedes ver las reseñas y valoraciones de los usuarios

Recuerda que puedes optar por la opción de agregar una reseña .

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *