Mercurial > ift6266
comparison data_generation/transformations/Rature.py @ 167:1f5937e9e530
More moves - transformations into data_generation, added "deep" folder
author | Dumitru Erhan <dumitru.erhan@gmail.com> |
---|---|
date | Fri, 26 Feb 2010 14:15:38 -0500 |
parents | transformations/Rature.py@7640cb31cf1f |
children |
comparison
equal
deleted
inserted
replaced
166:17ae5a1a4dd1 | 167:1f5937e9e530 |
---|---|
1 #!/usr/bin/python | |
2 # coding: utf-8 | |
3 | |
4 ''' | |
5 Ajout d'une rature sur le caractère. La rature est en fait un 1 qui recoit une | |
6 rotation et qui est ensuite appliqué sur le caractère. Un grossissement, puis deux | |
7 erosions sont effectuees sur le 1 afin qu'il ne soit plus reconnaissable. | |
8 Il y a des chances d'avoir plus d'une seule rature ! | |
9 | |
10 Il y a 15% d'effectuer une rature. | |
11 | |
12 Ce fichier prend pour acquis que les images sont donnees une a la fois | |
13 sous forme de numpy.array de 1024 (32 x 32) valeurs entre 0 et 1. | |
14 | |
15 Sylvain Pannetier Lebeuf dans le cadre de IFT6266, hiver 2010 | |
16 | |
17 ''' | |
18 | |
19 import numpy, Image, random | |
20 import scipy.ndimage.morphology | |
21 from pylearn.io import filetensor as ft | |
22 | |
23 | |
24 class Rature(): | |
25 | |
26 def __init__(self,seed=1256): | |
27 self.angle=0 #Angle en degre de la rotation (entre 0 et 180) | |
28 self.numero=0 #Le numero du 1 choisi dans la banque de 1 | |
29 self.gauche=-1 #Le numero de la colonne la plus a gauche contenant le 1 | |
30 self.droite=-1 | |
31 self.haut=-1 | |
32 self.bas=-1 | |
33 self.faire=1 #1=on effectue et 0=fait rien | |
34 | |
35 self.crop_haut=0 | |
36 self.crop_gauche=0 #Ces deux valeurs sont entre 0 et 31 afin de definir | |
37 #l'endroit ou sera pris le crop dans l'image du 1 | |
38 | |
39 self.largeur_bande=-1 #La largeur de la bande | |
40 self.smooth=-1 #La largeur de la matrice carree servant a l'erosion | |
41 self.nb_ratures=-1 #Le nombre de ratures appliques | |
42 self.fini=0 #1=fini de mettre toutes les couches 0=pas fini | |
43 self.complexity=0 #Pour garder en memoire la complexite si plusieurs couches sont necessaires | |
44 self.seed=seed | |
45 | |
46 #numpy.random.seed(self.seed) | |
47 | |
48 f3 = open('/data/lisa/data/ift6266h10/un_rature.ft') #Doit etre sur le reseau DIRO. | |
49 #f3 = open('/home/sylvain/Dropbox/Msc/IFT6266/donnees/un_rature.ft') | |
50 #Il faut arranger le path sinon | |
51 w=ft.read(f3) | |
52 f3.close() | |
53 self.d=(w.astype('float'))/255 | |
54 | |
55 self.patch=self.d[0].reshape((32,32)) #La patch de rature qui sera appliquee sur l'image | |
56 | |
57 def get_settings_names(self): | |
58 return ['angle','numero','faire','crop_haut','crop_gauche','largeur_bande','smooth','nb_ratures'] | |
59 | |
60 def get_seed(self): | |
61 return self.seed | |
62 | |
63 def regenerate_parameters(self, complexity,next_rature = False): | |
64 | |
65 | |
66 self.numero=random.randint(0,4999) #Ces bornes sont inclusives ! | |
67 self.fini=0 | |
68 self.complexity=complexity | |
69 | |
70 if float(complexity) > 0: | |
71 | |
72 self.gauche=self.droite=self.haut=self.bas=-1 #Remet tout a -1 | |
73 | |
74 self.angle=int(numpy.random.normal(90,100*complexity)) | |
75 | |
76 self.faire=numpy.random.binomial(1,0.15) ##### 15% d'effectuer une rature ##### | |
77 if next_rature: | |
78 self.faire = 1 | |
79 #self.faire=1 #Pour tester seulement | |
80 | |
81 self.crop_haut=random.randint(0,17) | |
82 self.crop_gauche=random.randint(0,17) | |
83 if complexity <= 0.25 : | |
84 self.smooth=6 | |
85 elif complexity <= 0.5: | |
86 self.smooth=5 | |
87 elif complexity <= 0.75: | |
88 self.smooth=4 | |
89 else: | |
90 self.smooth=3 | |
91 | |
92 p = numpy.random.rand() | |
93 if p < 0.5: | |
94 self.nb_ratures= 1 | |
95 else: | |
96 if p < 0.8: | |
97 self.nb_ratures = 2 | |
98 else: | |
99 self.nb_ratures = 3 | |
100 | |
101 #Creation de la "patch" de rature qui sera appliquee sur l'image | |
102 if self.faire == 1: | |
103 self.get_size() | |
104 self.get_image_rot() #On fait la "patch" | |
105 | |
106 else: | |
107 self.faire=0 #On ne fait rien si complexity=0 !! | |
108 | |
109 return self._get_current_parameters() | |
110 | |
111 | |
112 def get_image_rot(self): | |
113 image2=(self.d[self.numero].reshape((32,32))[self.haut:self.bas,self.gauche:self.droite]) | |
114 | |
115 im = Image.fromarray(numpy.asarray(image2*255,dtype='uint8')) | |
116 | |
117 #La rotation et le resize sont de belle qualite afin d'avoir une image nette | |
118 im2 = im.rotate(self.angle,Image.BICUBIC,expand=False) | |
119 im3=im2.resize((50,50),Image.ANTIALIAS) | |
120 | |
121 grosse=numpy.asarray(numpy.asarray(im3)/255.0,dtype='float32') | |
122 crop=grosse[self.haut:self.haut+32,self.gauche:self.gauche+32] | |
123 | |
124 self.get_patch(crop) | |
125 | |
126 def get_patch(self,crop): | |
127 smooting = numpy.ones((self.smooth,self.smooth)) | |
128 #Il y a deux erosions afin d'avoir un beau resultat. Pas trop large et | |
129 #pas trop mince | |
130 trans=scipy.ndimage.morphology.grey_erosion\ | |
131 (crop,size=smooting.shape,structure=smooting,mode='wrap') | |
132 trans1=scipy.ndimage.morphology.grey_erosion\ | |
133 (trans,size=smooting.shape,structure=smooting,mode='wrap') | |
134 | |
135 | |
136 patch_img=Image.fromarray(numpy.asarray(trans1*255,dtype='uint8')) | |
137 | |
138 patch_img2=patch_img.crop((4,4,28,28)).resize((32,32)) #Pour contrer les effets de bords ! | |
139 | |
140 trans2=numpy.asarray(numpy.asarray(patch_img2)/255.0,dtype='float32') | |
141 | |
142 | |
143 #Tout ramener entre 0 et 1 | |
144 trans2=trans2-trans2.min() #On remet tout positif | |
145 trans2=trans2/trans2.max() | |
146 | |
147 #La rayure a plus de chance d'etre en bas ou oblique le haut a 10h | |
148 if random.random() <= 0.5: #On renverse la matrice dans ce cas | |
149 for i in xrange(0,32): | |
150 self.patch[i,:]=trans2[31-i,:] | |
151 else: | |
152 self.patch=trans2 | |
153 | |
154 | |
155 | |
156 | |
157 def get_size(self): | |
158 image=self.d[self.numero].reshape((32,32)) | |
159 | |
160 #haut | |
161 for i in xrange(0,32): | |
162 for j in xrange(0,32): | |
163 if(image[i,j]) != 0: | |
164 if self.haut == -1: | |
165 self.haut=i | |
166 break | |
167 if self.haut > -1: | |
168 break | |
169 | |
170 #bas | |
171 for i in xrange(31,-1,-1): | |
172 for j in xrange(0,32): | |
173 if(image[i,j]) != 0: | |
174 if self.bas == -1: | |
175 self.bas=i | |
176 break | |
177 if self.bas > -1: | |
178 break | |
179 | |
180 #gauche | |
181 for i in xrange(0,32): | |
182 for j in xrange(0,32): | |
183 if(image[j,i]) != 0: | |
184 if self.gauche == -1: | |
185 self.gauche=i | |
186 break | |
187 if self.gauche > -1: | |
188 break | |
189 | |
190 #droite | |
191 for i in xrange(31,-1,-1): | |
192 for j in xrange(0,32): | |
193 if(image[j,i]) != 0: | |
194 if self.droite == -1: | |
195 self.droite=i | |
196 break | |
197 if self.droite > -1: | |
198 break | |
199 | |
200 | |
201 def _get_current_parameters(self): | |
202 return [self.angle,self.numero,self.faire,self.crop_haut,self.crop_gauche,self.largeur_bande,self.smooth,self.nb_ratures] | |
203 | |
204 def transform_image(self, image): | |
205 if self.faire == 0: #Rien faire !! | |
206 return image | |
207 | |
208 if self.fini == 0: #S'il faut rajouter des couches | |
209 patch_temp=self.patch | |
210 for w in xrange(1,self.nb_ratures): | |
211 self.regenerate_parameters(self.complexity,1) | |
212 for i in xrange(0,32): | |
213 for j in xrange(0,32): | |
214 patch_temp[i,j]=max(patch_temp[i,j],self.patch[i,j]) | |
215 self.fini=1 | |
216 self.patch=patch_temp | |
217 | |
218 for i in xrange(0,32): | |
219 for j in xrange(0,32): | |
220 image[i,j]=max(image[i,j],self.patch[i,j]) | |
221 self.patch*=0 #Remise a zero de la patch (pas necessaire) | |
222 return image | |
223 | |
224 | |
225 #---TESTS--- | |
226 | |
227 def _load_image(): | |
228 f = open('/home/sylvain/Dropbox/Msc/IFT6266/donnees/lower_test_data.ft') #Le jeu de donnees est en local. | |
229 d = ft.read(f) | |
230 w=numpy.asarray(d[0:1000]) | |
231 return (w/255.0).astype('float') | |
232 | |
233 def _test(complexite): | |
234 img=_load_image() | |
235 transfo = Rature() | |
236 for i in xrange(0,10): | |
237 img2=img[random.randint(0,1000)] | |
238 pylab.imshow(img2.reshape((32,32))) | |
239 pylab.show() | |
240 print transfo.get_settings_names() | |
241 print transfo.regenerate_parameters(complexite) | |
242 img2=img2.reshape((32,32)) | |
243 | |
244 img2_trans=transfo.transform_image(img2) | |
245 | |
246 pylab.imshow(img2_trans.reshape((32,32))) | |
247 pylab.show() | |
248 | |
249 | |
250 if __name__ == '__main__': | |
251 from pylearn.io import filetensor as ft | |
252 import pylab | |
253 _test(1) | |
254 | |
255 |