def find_eyes(self): """Try to detect eyes and return if successful.""" if self.face is None: return False # Only search eyes in the upper half of the face bottom = self.face.top + 1. / 2. * self.face.height if self.nose: bottom = min(bottom, self.nose.top) # If no eyes at all if self.eyes[0] is None and self.eyes[1] is None: # Search them both face_patch = self.frame[self.face.top:bottom, self.face.left:self.face.right] eyes = self.eyeCascade.detectMultiScale(face_patch, 1.2, 2, minSize=(5, 2), maxSize=(200, 200)) # We found 2 eyes. Sort eyes by x coordinate if len(eyes) >= 2: eyes = [ Rect._make(eye).translate(dx=self.face.left, dy=self.face.top) for eye in eyes ] if eyes[0].center.x > eyes[1].center.x: eyes[0], eyes[1] = eyes[1], eyes[0] self.eyes = eyes return True # We found an eye, but which one? # Let's compare its position to the face center elif len(eyes) == 1: eye = Rect._make(eyes[0]).translate(self.face.left, self.face.top) if eye.center.x < self.face.center.x: self.eyes[0] = eye else: self.eyes[1] = eye return True else: return False else: # Handle both eyes on their own self.find_single_eye(0) self.find_single_eye(1)
def find_face(self): """Perform face recognition and return if successful""" if self.frame is not None: faces = self.faceCascade.detectMultiScale( self.frame, 1.2, 1, minSize=(100, 100), flags=cv2.cv.CV_HAAR_DO_CANNY_PRUNING) if len(faces) > 0: face = faces[0] self.face = Rect._make(face) assert (face is not None) return True return False
def find_single_eye(self, index): """Find one of the eyes. index = 0 => left eye index = 1 => right eye .""" assert (0 <= index < 2) if self.face is None: return False # Set search region top = self.face.top bottom = self.face.top + 1. / 2. * self.face.height left = self.face.left right = self.face.right if self.nose: bottom = self.nose.top # Adapt search region for individual eyes if index == 1: left = self.face.center.x if self.eyes[0] is not None: left = max(left, self.eyes[0].right) else: right = self.face.center.x if self.eyes[1] is not None: right = min(right, self.eyes[1].left) face_patch = self.frame[top:bottom, left:right] if left < right: eyes = self.eyeCascade.detectMultiScale(face_patch, 1.2, 1, minSize=(5, 2), maxSize=(200, 200)) else: return False if len(eyes) > 0: eye = eyes[0] self.eyes[index] = Rect._make(eye).translate(left, self.face.top) return True else: return False
def find_nose(self): """Perform nose recognition and return if successful.""" if self.face is not None: # Specify region of interest left = self.face.left + self.face.width / 4 right = self.face.right - self.face.width / 4 top = self.face.top + self.face.height / 6 bottom = self.face.bottom - self.face.height / 6 # Nose should be above the mouth if self.mouth is not None: bottom = self.mouth.top # Nose should be below the eyes for eye in self.eyes: if eye is not None: top = max(top, eye.bottom) # Search the nose face_patch = self.frame[top:bottom, left:right] if face_patch.size > 0: noses = self.noseCascade.detectMultiScale( face_patch, 1.2, 1, minSize=(10, 10), maxSize=(self.face[2] / 4, self.face[3] / 2), flags=cv2.cv.CV_HAAR_DO_CANNY_PRUNING) # Convert the found nose back to absolute coordinates if (len(noses) > 0): self.nose = Rect._make(noses[0]).translate(left, top) return True # If we didn't find anything if self.nose_timeout > 0: self.nose_timeout -= 1 else: self.nose = None self.nose_timeout = 10 return False
def find_mouth(self): """Perform mouth recognition and return if successful.""" if self.face is not None: # Specify region of interest left = self.face.left + self.face.width / 3 right = self.face.right - self.face.width / 3 top = self.face.top + self.face.height / 2 bottom = self.face.bottom # Mouth should be below the nose if self.nose is not None: top = self.nose.bottom face_patch = self.frame[top:bottom, left:right] # Mouth should be wider than nose if self.nose is not None: minwidth = int(.7 * self.nose.width) else: minwidth = 30 # Search for the mouth if face_patch.size > 0: mouths = self.mouthCascade.detectMultiScale(face_patch, 1.2, 1, minSize=(minwidth, 5)) # Convert the result if len(mouths) > 0: self.mouth = Rect._make(mouths[0]).translate(left, top) return True # If we didn't find anything if self.mouth_timeout > 0: self.mouth_timeout -= 1 else: self.mouth = None self.mouth_timeout = 10 return False