Package pycv :: Package cs :: Package cv :: Package face :: Module frontalface_dset
[hide private]
[frames] | no frames]

Source Code for Module pycv.cs.cv.face.frontalface_dset

  1  # PyCV - A Computer Vision Package for Python Incorporating Fast Training of Face Detection 
  2   
  3  # Copyright 2007 Nanyang Technological University, Singapore. 
  4  # Authors: Minh-Tri Pham, Viet-Dung D. Hoang, and Tat-Jen Cham. 
  5   
  6  # This file is part of PyCV. 
  7   
  8  # PyCV is free software: you can redistribute it and/or modify 
  9  # it under the terms of the GNU General Public  
 10  # License as published by the Free Software Foundation, either version  
 11  # 3 of the License, or (at your option) any later version. 
 12   
 13  # PyCV is distributed in the hope that it will be useful, 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 16  # GNU General Public License for more details. 
 17   
 18  # You should have received a copy of the GNU General Public License 
 19  # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 20   
 21  # --------------------------------------------------------------------- 
 22  #!/usr/bin/env python 
 23   
 24   
 25  __all__ = ['FrontalFace_CDataGenerator', 'RotatedFrontalFace_CDataGenerator', 
 26      'NoScale_RotatedFrontalFace_CDataGenerator'] 
 27   
 28  # import the necessary things 
 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  # Frontal Face and Non-Face generator 
 47  # ============================================================================= 
48 -class FrontalFace_CDataGenerator(CDataGenerator):
49 """Generate face and non-face image patches of size N-by-N. 50 """ 51
52 - def __init__(self,database_path,N):
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
64 - def __del__(self):
66
67 - def generate(self,j):
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: # frontal face 80 def perturb_func(iview, *args, **kwds): 81 # randomly flip 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: # non-face 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 # Rotated Frontal Face and Non-Face generator 103 # =============================================================================
104 -class RotatedFrontalFace_CDataGenerator(CDataGenerator):
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
133 - def class_to_location(j):
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
148 - def __init__(self,database_path):
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
164 - def __del__(self):
166
167 - def generate(self,j):
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: # rotated frontal face 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): # to flip? 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: # non-face 194 self.nogenerator.generate(self.patch) 195 196 integral(self.patch_array,self.patch_vi) 197 return self.patch_vi.ravel()
198 199 # ============================================================================= 200 # Rotated Frontal Face and Non-Face generator without scaling 201 # =============================================================================
202 -class NoScale_RotatedFrontalFace_CDataGenerator(CDataGenerator):
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
231 - def class_to_location(j):
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
246 - def __init__(self,database_path):
247 """Initalize the class. 248 249 :Parameters: 250 database_path : string 251 path to a folder equivalent to 'm:/facedata' 252 """ 253 N = 26 # 19 + 7 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
262 - def __del__(self):
264
265 - def generate(self,j):
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: # rotated frontal face 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): # to flip? 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: # non-face 292 self.nogenerator.generate(self.patch) 293 294 integral(self.patch_array,self.patch_vi) 295 return self.patch_vi.ravel()
296