1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 __all__ = ['FrontalFace_CDataGenerator', 'RotatedFrontalFace_CDataGenerator',
26 'NoScale_RotatedFrontalFace_CDataGenerator']
27
28
29 from math import pi
30 from numpy import zeros
31 from os.path import join
32 from random import randint
33
34 from pycv.cs import arrayd
35 from pycv.cs.cv import fromIplImage, integral
36 from pycv.cs.cv.patch import FrontalFaceGenerator, NonObjectGenerator
37 from pycv.cs.ml.cla import CDataGenerator
38 from pycv.interfaces.opencv import cvCreateImage, CvSize, IPL_DEPTH_8U, \
39 cvReleaseImage
40
41 from pycv.ext import frontalface_dset_class_to_location as _c2l
42 from pycv.ext import frontalface_dset_class_to_location2 as _c2l2
43
44
45
46
47
49 """Generate face and non-face image patches of size N-by-N.
50 """
51
53 CDataGenerator.__init__(self,(N*N,),2,'float64')
54 self.patch = cvCreateImage(CvSize(N,N),IPL_DEPTH_8U,1)
55 self.patch_array = fromIplImage(self.patch)
56 self.patch_vi = zeros((N,N))
57 self.ffgenerator = FrontalFaceGenerator(
58 join(database_path, 'frontal-face'))
59 self.nogenerator = NonObjectGenerator(join(database_path,'non-object'))
60
61 self.cnt = 2
62 self.toflip = True
63
66
68 """
69 Generate a random face or non-face, vectorized-integrated.
70
71 Input:
72 j: class j
73 Output:
74 input_point: a point of class j.
75 """
76 j = int(j)
77 if j < 0 or j > 1:
78 raise IndexError('j must be 0 or 1')
79 elif j > 0:
80 def perturb_func(iview, *args, **kwds):
81
82 if self.cnt > 0:
83 self.cnt -= 1
84 else:
85 self.cnt = 2
86 self.toflip = not self.toflip
87
88 iview.flip = self.toflip
89 if self.toflip:
90 iview.angle = pi
91
92 self.ffgenerator.generate(self.patch,perturb_func)
93
94 else:
95 self.nogenerator.generate(self.patch)
96
97 integral(self.patch_array,self.patch_vi)
98 return self.patch_vi.ravel()
99
100
101
102
103
105 """Generate face and non-face image patches of size 32-by-32.
106
107 Frontal faces can have:
108 - a : rotation angle in multiples of 45 degree, clockwise
109 a = (M_PI / 4) * (i_a - 4), where i_a \in {0..7}
110 - s : size 19x19, 21x21, 23x23, 25x25
111 s = 19 + 2 * i_s, where i_s \in {0..3}
112 - x : shift in x in {-3.5, -2.5, ..., 2.5, 3.5} pixels
113 x = i_x - 3.5, where i_x \in {0..7}
114 - y : shift in y in {-3.5, -2.5, ..., 2.5, 3.5} pixels
115 y = i_y - 3.5, where i_y \in {0..7}
116
117 We have in total 8*4*8*8 = 2048 face locations (a,s,x,y). Use static method
118 class_to_location() to convert from class to location.
119
120 Neighboring patches:
121 - Translation: move by 8 pixels.
122 - Scaling: scale down with scaling factor 1.5
123
124 Compared to traditional methods:
125 Shifting: traditional 1.5 pixel, ours 1.0 pixel
126 Scaling: traditional 1.2-1.5, ours 1.02-1.12
127 Overall: we consider 2-4 times more locations than traditional methods
128
129
130 """
131
132 @staticmethod
134 """Convert from class j to location (a,s,x,y)
135
136 :Parameters:
137 j : integer
138 class, if j = 0, None is returned
139 :Returns:
140 (a,s,x,y) : location
141 the corresponding location of j, or None if j == 0
142 """
143 z = zeros(4)
144 if _c2l(int(j),z) != 0:
145 return z
146 return None
147
149 """Initalize the class.
150
151 :Parameters:
152 database_path : string
153 path to a folder equivalent to 'm:/facedata'
154 """
155 N = 32
156 CDataGenerator.__init__(self,(N*N,),2,'float64')
157 self.patch = cvCreateImage(CvSize(N,N),IPL_DEPTH_8U,1)
158 self.patch_array = fromIplImage(self.patch)
159 self.patch_vi = zeros((N,N))
160 self.ffgenerator = FrontalFaceGenerator(
161 join(database_path, 'frontal-face'))
162 self.nogenerator = NonObjectGenerator(join(database_path,'non-object'))
163
166
168 """
169 Generate a random face or non-face, vectorized-integrated.
170
171 Input:
172 j: class j
173 Output:
174 input_point: a point of class j.
175 """
176 j = int(j)
177 if j < 0 or j > 2048:
178 raise IndexError('j must be from 0 to 2048')
179 elif j > 0:
180 def perturb_func(iview, *args, **kwds):
181 z = self.class_to_location(j)
182 iview.dparam[1] *= 32.0 / z[1]
183 if randint(0,1):
184 iview.iparam[2] = 1
185 iview.dparam[0] += pi
186 iview.dparam[0] += z[0]
187 else:
188 iview.dparam[0] -= z[0]
189 iview.slide(-z[2], -z[3])
190
191 self.ffgenerator.generate(self.patch,perturb_func, j=j)
192
193 else:
194 self.nogenerator.generate(self.patch)
195
196 integral(self.patch_array,self.patch_vi)
197 return self.patch_vi.ravel()
198
199
200
201
203 """Generate face and non-face image patches of size 26-by-26.
204
205 Frontal faces can have:
206 - a : rotation angle in multiples of 45 degree, clockwise
207 a = (M_PI / 4) * (i_a - 4), where i_a \in {0..7}
208 - s : size 19x19 (fixed)
209 - x : shift in x in {-3.5, -2.5, ..., 2.5, 3.5} pixels
210 x = i_x - 3.5, where i_x \in {0..7}
211 - y : shift in y in {-3.5, -2.5, ..., 2.5, 3.5} pixels
212 y = i_y - 3.5, where i_y \in {0..7}
213
214 We have in total 8*8*8 = 512 face locations (a,x,y). Use static method
215 class_to_location() to convert from class to location.
216
217 Correspondence between a class and a location
218 class j,
219 Location a = (a2, a1, a0), y = (y2, y1, y0), x = (x2, x1, x0),
220 then: j = (a2, a1, a0, y2, x2, y1, x1, y0, x0) + 1
221
222 Neighboring patches:
223 - Translation: move by 8 pixels.
224
225 Compared to traditional methods:
226 Shifting: traditional 1.5 pixel, ours 1.0 pixel
227
228 """
229
230 @staticmethod
232 """Convert from class j to location (a,s,x,y)
233
234 :Parameters:
235 j : integer
236 class, if j = 0, None is returned
237 :Returns:
238 (a,s,x,y) : location
239 the corresponding location of j, or None if j == 0
240 """
241 z = zeros(4)
242 if _c2l2(int(j),z) != 0:
243 return z
244 return None
245
247 """Initalize the class.
248
249 :Parameters:
250 database_path : string
251 path to a folder equivalent to 'm:/facedata'
252 """
253 N = 26
254 CDataGenerator.__init__(self,(N*N,),2,'float64')
255 self.patch = cvCreateImage(CvSize(N,N),IPL_DEPTH_8U,1)
256 self.patch_array = fromIplImage(self.patch)
257 self.patch_vi = zeros((N,N))
258 self.ffgenerator = FrontalFaceGenerator(
259 join(database_path, 'frontal-face'))
260 self.nogenerator = NonObjectGenerator(join(database_path,'non-object'))
261
264
266 """
267 Generate a random face or non-face, vectorized-integrated.
268
269 Input:
270 j: class j
271 Output:
272 input_point: a point of class j.
273 """
274 j = int(j)
275 if j < 0 or j > 512:
276 raise IndexError('j must be from 0 to 512')
277 elif j > 0:
278 def perturb_func(iview, *args, **kwds):
279 z = self.class_to_location(j)
280 iview.dparam[1] *= 26.0 / z[1]
281 if randint(0,1):
282 iview.iparam[2] = 1
283 iview.dparam[0] += pi
284 iview.dparam[0] += z[0]
285 else:
286 iview.dparam[0] -= z[0]
287 iview.slide(-z[2], -z[3])
288
289 self.ffgenerator.generate(self.patch,perturb_func, j=j)
290
291 else:
292 self.nogenerator.generate(self.patch)
293
294 integral(self.patch_array,self.patch_vi)
295 return self.patch_vi.ravel()
296