-
Notifications
You must be signed in to change notification settings - Fork 0
/
faceDetection.py
133 lines (107 loc) · 4.45 KB
/
faceDetection.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
# Erica Shepherd
# CS 5330
# Final Project
# Haar Cascade Face detection
# import statements
import cv2 as cv
import os
import sys
# draws rectangles in given color around detected features in given frame
def drawFeatures(frame, features, color):
for (x, y, w, h) in features:
frame = cv.rectangle(img=frame, pt1=(x,y), pt2=(x+w, y+h),
color=color, thickness=2)
# returns detected face features in face region of frame
def findFeatures(grayFrame, faces, featureCascade, scaleFactor=1.3,
minNeighbors=5, minSize=(0, 0)):
featuresFinal = []
for (x, y, w, h) in faces:
# checks for features only in face region
regionOfInterest = grayFrame[y:y+h, x:x+w]
features = featureCascade.detectMultiScale(regionOfInterest, scaleFactor=scaleFactor,
minNeighbors=minNeighbors, minSize=minSize)
# re-adjusts values back into frame values
for (fx, fy, fw, fh) in features:
feature = (fx+x, fy+y, fw, fh)
featuresFinal.append(feature)
return featuresFinal
# creates folder if path does not exist
def checkDirectory(path):
if os.path.exists(path)==False:
os.makedirs(path)
print("Creating", path)
# load and return pre-trained classifier from OpenCV directory (https://github.com/opencv/opencv/tree/master/data/haarcascades)
def loadCascades():
faceCascade = cv.CascadeClassifier("cascades/haarcascade_frontalface_default.xml")
eyeCascade = cv.CascadeClassifier("cascades/haarcascade_eye_tree_eyeglasses.xml")
smileCascade = cv.CascadeClassifier("cascades/haarcascade_smile.xml")
return faceCascade, eyeCascade, smileCascade
# main function
def main(argv):
if len(argv) == 0:
capdev = cv.VideoCapture(0)
if len(argv) == 1:
if argv[1] == 'windows':
capdev = cv.VideoCapture(0, cv.CAP_DSHOW)
elif argv[1] == 'webcam':
capdev = cv.VideoCapture(1)
else:
print("Invalid number of arguments. Expected 0 or 1. See readme.md for details.")
if not capdev.isOpened():
print("Error: unable to open camera")
exit()
# load cascades
faceCascade, eyeCascade, smileCascade = loadCascades()
# used for saving images
userID = ""
imageCount = 1
# video stream
while(1):
# captures frame
ret, frame = capdev.read()
# ret checks for correct frame read
if ret is not True:
print("Error: frame not read correctly")
exit()
grayFrame = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# finds features // note: scale factors, min neighbors, and min size may need
# // adjustment to optimize detection
faces = faceCascade.detectMultiScale(grayFrame, scaleFactor=1.3,
minNeighbors=5, minSize=(30,30))
eyes = findFeatures(grayFrame, faces, eyeCascade, scaleFactor=1.3,
minNeighbors=3, minSize=(3, 3))
smile = findFeatures(grayFrame, faces, smileCascade, scaleFactor=2,
minNeighbors=30, minSize=(50, 50))
# draws features on frame
drawFeatures(frame, faces, (255, 0, 0))
drawFeatures(frame, eyes, (0, 255, 0))
drawFeatures(frame, smile, (0, 0, 255))
cv.imshow("Video", frame)
# key commands
key = cv.waitKey(1)
# saves face region of original image if user presses s
if key == ord('s'):
# obtains userID if none already assigned
if userID == "":
userID = input("Please enter your name: ")
print("Now saving images for", userID)
# creates path directory if not already made
dirPath = "dataset"
checkDirectory(dirPath)
dirPath += "/" + userID
checkDirectory(dirPath)
# saves grayscale images of all faces
for (x, y, w, h) in faces:
path = dirPath + "/" + str(imageCount) + ".jpg"
cv.imwrite(path, grayFrame[y:y+h, x:x+w])
imageCount += 1
# quits if user presses q
elif key == ord('q'):
break
# end video stream
capdev.release()
cv.destroyAllWindows()
return
# runs code only if in file
if __name__ == "__main__":
main(sys.argv)