-
Notifications
You must be signed in to change notification settings - Fork 2
/
face_example.py
executable file
·133 lines (92 loc) · 3.96 KB
/
face_example.py
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env python
# Made by Jesse Panganiban (http://gist.github.com/jpanganiban)
from pygame import camera
import pygame
import time
import cv
import os
# Recognition
HAAR_PATH = "/usr/share/opencv/haarcascades/"
# Face
FACE_HAAR = os.path.join(HAAR_PATH, "haarcascade_frontalface_default.xml")
FACE_HAAR = cv.Load(FACE_HAAR)
# Eye
EYE_HAAR = os.path.join(HAAR_PATH, "haarcascade_mcs_righteye.xml")
EYE_HAAR = cv.Load(EYE_HAAR)
# Nose
NOSE_HAAR = os.path.join(HAAR_PATH, "haarcascade_mcs_nose.xml")
NOSE_HAAR = cv.Load(NOSE_HAAR)
# Mouth
MOUTH_HAAR = os.path.join(HAAR_PATH, "haarcascade_mcs_mouth.xml")
MOUTH_HAAR = cv.Load(MOUTH_HAAR)
# Screen settings
SCREEN = [640, 480]
def surface_to_string(surface):
"""Convert a pygame surface into string"""
return pygame.image.tostring(surface, 'RGB')
def pygame_to_cvimage(surface):
"""Convert a pygame surface into a cv image"""
cv_image = cv.CreateImageHeader(surface.get_size(), cv.IPL_DEPTH_8U, 3)
image_string = surface_to_string(surface)
cv.SetData(cv_image, image_string)
return cv_image
def cvimage_grayscale(cv_image):
"""Converts a cvimage into grayscale"""
grayscale = cv.CreateImage(cv.GetSize(cv_image), 8, 1)
cv.CvtColor(cv_image, grayscale, cv.CV_RGB2GRAY)
return grayscale
def cvimage_to_pygame(image):
"""Convert cvimage into a pygame image"""
image_rgb = cv.CreateMat(image.height, image.width, cv.CV_8UC3)
cv.CvtColor(image, image_rgb, cv.CV_BGR2RGB)
return pygame.image.frombuffer(image.tostring(), cv.GetSize(image_rgb),
"RGB")
def detect_faces(cv_image, storage):
"""Detects faces based on haar. Returns points"""
return cv.HaarDetectObjects(cvimage_grayscale(cv_image), FACE_HAAR,
storage)
def detect_eyes(cv_image, storage):
"""Detects eyes based on haar. Returns points"""
return cv.HaarDetectObjects(cvimage_grayscale(cv_image), EYE_HAAR,
storage)
def detect_nose(cv_image, storage):
"""Detects nose based on haar. Returns ponts"""
return cv.HaarDetectObjects(cvimage_grayscale(cv_image), NOSE_HAAR,
storage)
def detect_mouth(cv_image, storage):
"""Detects mouth based on haar. Returns points"""
return cv.HaarDetectObjects(cvimage_grayscale(cv_image), MOUTH_HAAR,
storage)
def draw_from_points(cv_image, points):
"""Takes the cv_image and points and draws a rectangle based on the points.
Returns a cv_image."""
for (x, y, w, h), n in points:
cv.Rectangle(cv_image, (x, y), (x + w, y + h), 255)
return cv_image
if __name__ == '__main__':
# Set game screen
screen = pygame.display.set_mode(SCREEN)
pygame.init() # Initialize pygame
camera.init() # Initialize camera
# Load camera source then start
cam = camera.Camera('/dev/video0', SCREEN)
cam.start()
while 1: # Ze loop
time.sleep(1 / 120) # 60 frames per second
image = cam.get_image() # Get current webcam image
cv_image = pygame_to_cvimage(image) # Create cv image from pygame image
# Detect faces then draw points on image
# FIXME: Current bottleneck. Image has to be Grayscale to make it faster.
# One solution would be to use opencv instead of pygame for
# capturing images.
storage = cv.CreateMemStorage(-1) # Create storage
#points = detect_eyes(cv_image, storage) + \
# detect_nose(cv_image, storage) + \
# detect_mouth(cv_image, storage)
points = detect_faces(cv_image, storage) # Get points of faces.
cv_image = draw_from_points(cv_image, points) # Draw points
screen.fill([0, 0, 0]) # Blank fill the screen
screen.blit(cvimage_to_pygame(cv_image), (0, 0)) # Load new image on screen
pygame.display.update() # Update pygame display
if pygame.event.peek(pygame.QUIT):
break