comparison transformations/BruitGauss.py @ 62:bab98bb47616

Correction majeure. Auparavant, le lissage gaussien etait global avec une seule gaussienne. Maintenant, le lissage gaussien est local. Un bruit correle est rajoute sur l'image
author SylvainPL <sylvain.pannetier.lebeuf@umontreal.ca>
date Tue, 09 Feb 2010 11:41:17 -0500
parents 349d8dc9504c
children cc641ee75d3b
comparison
equal deleted inserted replaced
61:cc4be6b25b8e 62:bab98bb47616
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # coding: utf-8 2 # coding: utf-8
3 3
4 ''' 4 '''
5 Ajout de bruit gaussien dans les donnees. Un bruit poivre et sel est ajoute 5 Ajout de bruit gaussien dans les donnees. A chaque iteration, un bruit poivre
6 aux donnees, puis un filtre gaussien est applique sur l'image. 6 et sel est ajoute, puis un lissage gaussien autour de ce point est ajoute.
7 On fait un nombre d'iteration = 1024*complexity/25 ce qui equivaud
8 a complexity/25 des points qui recoivent le centre du noyau gaussien.
9 Il y en a beaucoup moins que le bruit poivre et sel, car la transformation
10 est plutôt aggressive et touche beaucoup de pixels autour du centre
7 11
8 La proportion de bites aleatoires est definit par complexity. 12 La grandeur de la gaussienne ainsi que son ecart type sont definit par complexity
9 Lorsque cette valeur est a 1 ==> Plus reconnaissable et 0 ==> Rien ne se passe 13 et par une composante aleatoire normale.
10
11 Le niveau de lisssage est definit par complexity
12 Au plus c'est eleve, au plus c'est lisse
13 14
14 Ce fichier prend pour acquis que les images sont donnees une a la fois 15 Ce fichier prend pour acquis que les images sont donnees une a la fois
15 sous forme de numpy.array de 1024 (32 x 32) valeurs entre 0 et 1. 16 sous forme de numpy.array de 1024 (32 x 32) valeurs entre 0 et 1.
16 17
17 Sylvain Pannetier Lebeuf dans le cadre de IFT6266, hiver 2010 18 Sylvain Pannetier Lebeuf dans le cadre de IFT6266, hiver 2010
26 class BruitGauss(): 27 class BruitGauss():
27 28
28 def __init__(self): 29 def __init__(self):
29 self.proportion_bruit=0.1 #Le pourcentage des pixels qui seront bruites 30 self.proportion_bruit=0.1 #Le pourcentage des pixels qui seront bruites
30 self.nb_chng=10 #Le nombre de pixels changes. Seulement pour fin de calcul 31 self.nb_chng=10 #Le nombre de pixels changes. Seulement pour fin de calcul
31 self.sigma_gauss=0.5 #L'ecart type du noyau gaussien 32 self.sigma_gauss=3.0 #L'ecart type du noyau gaussien
33 self.grandeur=7 #Largeur de la fenetre gaussienne
32 34
33 def get_settings_names(self): 35 def get_settings_names(self):
34 return ['proportion_bruit','sigma_gauss'] 36 return ['proportion_bruit','sigma_gauss','grandeur']
35 37
36 def regenerate_parameters(self, complexity): 38 def regenerate_parameters(self, complexity):
37 self.proportion_bruit = complexity #Generation uniforme 39 self.proportion_bruit = float(complexity)/25
38 self.nb_chng=int(1024*self.proportion_bruit) 40 self.nb_chng=int(1024*self.proportion_bruit)
39 self.sigma_gauss=complexity+0.2 41 if float(complexity) > 0:
42 self.sigma_gauss=max(0,numpy.random.normal(complexity*5,complexity))
43 self.grandeur=int(min(31,max(1,8*complexity*numpy.random.normal(1,float(complexity)/2))))
44 else:
45 self.sigma_gauss = 0
46 self.grandeur=1
47 #Un peu de paranoia ici, mais on ne sait jamais
48
49 if self.grandeur%2 == 0:
50 self.grandeur+=1 #Toujours un nombre impair, plus simple plus tard
40 return self._get_current_parameters() 51 return self._get_current_parameters()
41 52
42 def _get_current_parameters(self): 53 def _get_current_parameters(self):
43 return [] 54 return [self.proportion_bruit,self.sigma_gauss,self.grandeur]
44 55
45 def get_parameters_determined_by_complexity(self, complexity):
46 return [self.proportion_bruit,self.sigma_gauss]
47 56
48 def transform_image(self, image): 57 def transform_image(self, image):
49 image=image.reshape(1024,1) 58 image=image.reshape((32,32))
50 changements=random.sample(xrange(numpy.size(image)),self.nb_chng) #Les pixels qui seront changes 59
51 for j in xrange(0,self.nb_chng): 60 #creation du noyau gaussien
52 image[changements[j]]=numpy.random.random() #On determine les nouvelles valeurs des pixels changes 61 gauss=numpy.zeros((self.grandeur,self.grandeur))
53 image=image.reshape(32,32) 62 x0 = y0 = self.grandeur/2
54 image=(scipy.ndimage.filters.gaussian_filter\ 63 for i in xrange(0,self.grandeur):
55 (image, self.sigma_gauss, order=0, \ 64 for j in xrange(0,self.grandeur):
56 output=None, mode='reflect', cval=0.0)) 65 gauss[i,j]=numpy.exp(-4*numpy.log(2) * ((i-x0)**2 + (j-y0)**2) / self.sigma_gauss**2)
57 66 #pylab.contour(gauss)
67 #pylab.show() #Pour voir si la gaussienne est bien comme desiree
68
69 #Chaque tour dans la boucle ajoute un pointpoivre et sel, puis
70 #y ajoute un bruit gaussien autour afin d'avoir de la correlation dans
71 #les points
72
73 for i in xrange(0,self.nb_chng):
74 x_bruit=int(numpy.random.randint(0,32))
75 y_bruit=int(numpy.random.randint(0,32))
76
77 image[x_bruit,y_bruit]=max(0,min(1,numpy.random.normal(0.4,self.proportion_bruit*20)))
78
79 bord = int((self.grandeur-1)/2)
80 #Faire le "smooting"
81 for x in xrange(0,self.grandeur):
82 for y in xrange(0,self.grandeur):
83 #pour etre certain de ne pas changer le vide
84 if x_bruit-bord+x < 0:
85 continue
86 if y_bruit-bord+y < 0:
87 continue
88 if x_bruit-bord+x > 31:
89 continue
90 if y_bruit-bord+y > 31:
91 continue
92 image[x_bruit-bord+x,y_bruit-bord+y]=max(image[x_bruit-bord+x,y_bruit-bord+y],gauss[x,y]*image[x_bruit,y_bruit])
93 #image[x_bruit-bord+x,y_bruit-bord+y]=min(1,image[x_bruit-bord+x,y_bruit-bord+y]*(1+gauss[x,y]))
94 #Cette derniere ligne n'est pas très interessante. Elle ajoute le bruit
95 #plutot que de prendre le max entre la valeur presente et le bruit. Ca rend l'image un peu
96 #chaostique, pas une bonne idee
97
58 return image 98 return image
59 99
60 #---TESTS--- 100 #---TESTS---
61 101
62 def _load_image(): 102 def _load_image():