La génération d'un signal bruité, ou l'ajout de bruit dans une image, peut être utile pour tester les filtres passe-bas destinés à réduire le bruit. Cette page montre comment générer un signal affecté d'un bruit gaussien ou d'un bruit impulsif.
Soit xn un signal discret. Le bruit est une perturbation, que l'on notera bn. Le signal résultant est :
bn est une variable aléatoire continue. On parle de bruit gaussien lorsque la densité de probabilité de cette variable est la loi gaussienne (ou loi normale). On suppose que la loi gaussienne est centrée. La densité de probabilité est alors :
La probabilité pour que le bruit b soit compris entre x et x+dx est p(x)dx.
Les signaux délivrés par les instruments de mesure comportent un bruit qui peut être généralement considéré comme gaussien. Cette hypothèse permet de définir l'écart type σ comme l'incertitude type due aux erreurs aléatoires.
On dispose d'un générateur de nombre pseudo-aléatoires délivrant des nombres dans l'intervalle [0,1] avec une densité de probabilité uniforme. La génération de nombres aléatoires vérifiant la distribution gaussienne se fait en utilisant le théorème suivant ([1]) : si U1 et U2 sont deux variables aléatoires uniformes sur l'intervalle [0,1] alors
est une variable aléatoire vérifiant la loi gaussienne centrée.
La fonction suivante délivre un nombre aléatoire gaussien :
import random import math def aleaGauss(sigma): U1 = random.random() U2 = random.random() return sigma*math.sqrt(-2*math.log(U1))*math.cos(2*math.pi*U2)
On peut aussi utiliser la fonction random.gauss(mu,sigma).
Pour vérifier son fonctionnement, nous allons calculer un histogramme à partir de N tirages. L'histogramme comporte 2p+1 intervalles répartis sur l'intervalle [-1,1]. L'intervalle central doit être centré en zéro.
import numpy from matplotlib.pyplot import * p=10 histogram = numpy.zeros(2*p+1) N=1000 xmax=5.0 dx = xmax*2/(2*p+1) sigma=1.0 x = numpy.zeros(N) for k in range(N): x[k] = aleaGauss(sigma) if abs(x[k])<xmax: i = int((x[k]+xmax)/dx) histogram[i] += 1 xlist = numpy.arange(2*p+1)*dx-xmax+dx/2 figure(figsize=(6,6)) stem(xlist,histogram)figA.pdf
On peut obtenir l'histogramme directement avec la fonction hist :
figure(figsize=(6,6)) hist(x,bins=2*p+1,range=[-xmax,xmax])figB.pdf
Un signal périodique est défini par ses harmoniques :
def signal(t): return 1.0*math.cos(2*math.pi*t)+0.5*math.cos(6*math.pi*t+math.pi/3)
Au moment d'échantillonner ce signal, on ajoute un bruit gaussien :
N=1000 T = 2.0 dt = T/N y = numpy.zeros(N) t = numpy.zeros(N) sigma = 0.1 for k in range(N): t[k] = k*dt y[k] = signal(t[k])+aleaGauss(sigma) figure(figsize=(12,4)) plot(t,y)figC.pdf
La même méthode peut être appliquée à une image numérique pour lui ajouter un bruit gaussien.
Lecture du fichier et séparation des couches :
from PIL import Image img = Image.open("../../../../simul/image/objets.png") (red,green,blue,alpha)=img.split() array=numpy.array(red) figure(figsize=(4,4)) imshow(array,cmap=cm.gray)figD.pdf
On ajoute un bruit gaussien à la couche rouge. Comme la couche a une profondeur de 8 bits, la valeur finale après ajout du bruit ne doit pas sortir de l'intervalle [0,255].
array=numpy.array(red) s=array.shape sigma=10 for j in range(s[0]): for i in range(s[1]): v = int(math.floor(array[j][i]+random.gauss(0,sigma))) if v > 255: v = 255 if v<0: v = 0 array[j][i] = v figure(figsize=(4,4)) imshow(array,cmap=cm.gray) Image.fromarray(array).save("../../../../simul/image/objets-bruit.png")figE.pdf
Le bruit impulsif n'affecte que quelques échantillons du signal en modifiant fortement leur valeur. Un exemple de bruit impulsif est celui généré par des perturbations électromagnétiques transitoires. Des poussières ou des piqûres sur des images photographiques constituent aussi un bruit impulsif.
Comme exemple de bruit impulsif sur une image, on choisit aléatoirement des pixels dans l'image dont on divise la valeur par deux :
array=numpy.array(red) s=array.shape N = 5000 for k in range(N): i = random.randint(0,s[1]-1) j = random.randint(0,s[0]-1) array[j][i] = int(array[j][i]/2) figure(figsize=(4,4)) imshow(array,cmap=cm.gray) Image.fromarray(array).save("../../../../simul/image/objets-bruit-impulsif.png")figF.pdf