-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathwebcam_continuous_face.py
178 lines (137 loc) · 4.57 KB
/
webcam_continuous_face.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import time
from datetime import datetime
import json
import subprocess
import cv2
import cv2.cv as cv
import numpy as np
from PIL import Image
"""
Take images from a webcam,
look for faces.
All photos go into raw/
Photos with faces go into faces/
Basic workflow:
* Take photo with webcam every N seconds
* Put into raw/
* Look for faces
* If faces found, put into faces/
"""
def main():
N = 3
raw_dir = "raw/"
faces_dir = "faces/"
face_settings = {
'scaleFactor' : 1.3,
'minNeighbors' : 1,
'minSize' : (10,10),
'flags' : cv2.cv.CV_HAAR_SCALE_IMAGE|cv2.cv.CV_HAAR_DO_ROUGH_SEARCH
}
# Other flags:
# cv2.cv.CV_HAAR_SCALE_IMAGE
# cv2.cv.CV_HAAR_FIND_BIGGEST_OBJECT
# cv2.cv.CV_HAAR_DO_ROUGH_SEARCH
camera_port = 0
camera = cv2.VideoCapture(camera_port)
subprocess.call(["mkdir","-p",raw_dir])
subprocess.call(["mkdir","-p",faces_dir])
write_index(faces_dir, False)
while(True):
# Take photo every N seconds
time.sleep(N)
print("Photobomb!")
img = take_photo(camera)
# Create a timestamp on each image
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%m-%S")
filename = "img_"+timestamp+".jpg"
# Save image to raw/
save_image(raw_dir+filename, img)
# If faces, save image to faces/
# (ideally, save location of faces to json file - not implemented)
jsonfilename = "img_"+timestamp+".json"
faces_were_found = save_faces(img, faces_dir+filename, faces_dir+jsonfilename, face_settings)
# If we found faces, create symlink to latest face capture
if(faces_were_found):
subprocess.call(["ln", "-fs", filename, faces_dir+"last_face.jpg"])
write_index(faces_dir, True)
def take_photo(camera):
"""
Captures an image from a web camera using OpenCV
"""
# Wait, otherwise the image will be over-dark
time.sleep(0.3)
return_value, image = camera.read()
### imageT = transpose_photo(image)
return image
def transpose_photo(image):
"""
Transposes the first two axes of an image (diagonal reflection)
"""
imageT = np.transpose(image, axes=(1,0,2))
return imageT
def save_image(filename, image):
"""
Saves an image array to a file
"""
cv2.imwrite(filename, image)
def save_faces(image, filename, jsonfilename, face_settings):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.equalizeHist(gray)
face_classifier0 = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
face_classifier1 = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
face_classifier2 = cv2.CascadeClassifier("haarcascade_frontalface_alt2.xml")
# Get rectangle for entire face
rects = detect(gray, face_classifier2, face_settings)
if len(rects) != 0:
# Found a face:
# Draw face rectangles
print("Found a face")
vis = image.copy()
draw_rects(vis, rects, (255, 0, 0))
save_image(filename, vis)
## rects is a numpy array, not serializable
# with open(jsonfilename,'a') as f:
# json.dumps({'boundaries':rects})
return True
else:
return False
def detect(img, cascade, settings):
"""
Given an image and a cascade object,
detect features.
"""
# Parameters taken verbatim from OpenCV 2.4 example:
# https://github.com/opencv/opencv/blob/2.4/samples/python2/facedetect.py
rects = cascade.detectMultiScale(img,
**settings)
if len(rects) == 0:
return []
# Turn width and height of box
# into plot-ready image coordinates.
# rects contains (x,y),(w,h), return (x,y),(x+w,x+h)
rects[:,2:] += rects[:,:2]
return rects
def draw_rects(img, rects, color):
"""
Use OpenCV to draw rectangles
on top of image
"""
for x1, y1, x2, y2 in rects:
cv2.rectangle(img, (x1, y1), (x2, y2), color, 2)
def write_index(faces_dir, face_is_present):
"""Write an index file to display the last face present.
If face_is_present is False,
no faces have been found yet,
so use an empty placeholder.
"""
with open(faces_dir+"index.html", "w") as f:
f.write("<html>")
f.write("<body>")
if(face_is_present):
f.write('<img width="500px" src="last_face.jpg" />')
else:
f.write("<p>No faces found yet.</p>")
f.write("</body>")
f.write("</html>")
if __name__=="__main__":
main()