-
Notifications
You must be signed in to change notification settings - Fork 0
/
face_recognition.py
194 lines (141 loc) · 5.87 KB
/
face_recognition.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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
####################################################
# Modified by Nazmi Asri #
# Original code: http://thecodacus.com/ #
# All right reserved to the respective owner #
####################################################
# Import OpenCV2 for image processing
import cv2
# Import numpy for matrices calculations
import numpy as np
import os
subjects = ["", "Gopikishan", "Namrata","Mummy"]
def detect_face(img):
#convert the test image to gray image as opencv face detector expects gray images
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#gray=cv2.resize(gray,(600,400))
#load OpenCV face detector, I am using LBP which is fast
#there is also a more accurate but slow Haar classifier
face_cascade = cv2.CascadeClassifier('opencv-files/lbpcascade_frontalface.xml')
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5);
#if no faces are detected then return original img
if (len(faces) == 0):
return None, None
#under the assumption that there will be only one face,
#extract the face area
(x, y, w, h) = faces[0]
#gray=gray[y:y+w, x:x+h]
#return only the face part of the image
return gray[y:y+w, x:x+h], faces[0]
def prepare_training_data(data_folder_path):
#------STEP-1--------
#get the directories (one directory for each subject) in data folder
dirs = os.listdir(data_folder_path)
#list to hold all subject faces
faces = []
#list to hold labels for all subjects
labels = []
#let's go through each directory and read images within it
for dir_name in dirs:
#our subject directories start with letter 's' so
#ignore any non-relevant directories if any
if not dir_name.startswith("s"):
continue;
#------STEP-2--------
#extract label number of subject from dir_name
#format of dir name = slabel
#, so removing letter 's' from dir_name will give us label
label = int(dir_name.replace("s", ""))
#build path of directory containin images for current subject subject
#sample subject_dir_path = "training-data/s1"
subject_dir_path = data_folder_path + "/" + dir_name
#get the images names that are inside the given subject directory
subject_images_names = os.listdir(subject_dir_path)
#------STEP-3--------
#go through each image name, read image,
#detect face and add face to list of faces
for image_name in subject_images_names:
#ignore system files like .DS_Store
if image_name.startswith("."):
continue;
#build image path
#sample image path = training-data/s1/1.pgm
image_path = subject_dir_path + "/" + image_name
#read image
image = cv2.imread(image_path)
#display an image window to show the image
print("training datset")
#cv2.imshow("Training on image...", cv2.resize(image, (400, 500)))
cv2.waitKey(100)
#detect face
face, rect = detect_face(image)
#------STEP-4--------
#for the purpose of this tutorial
#we will ignore faces that are not detected
if face is not None:
#add face to list of faces
faces.append(face)
#add label for this face
labels.append(label)
cv2.destroyAllWindows()
cv2.waitKey(1)
cv2.destroyAllWindows()
return faces, labels
print("Preparing data...")
faces, labels = prepare_training_data("training-data")
print("Data prepared")
#print total faces and labels
print("Total faces: ", len(faces))
print("Total labels: ", len(labels))
#def assure_path_exists(path):
# dir = os.path.dirname(path)
# if not os.path.exists(dir):
## os.makedirs(dir)
# Create Local Binary Patterns Histograms for face recognization
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.train(faces, np.array(labels))
#assure_path_exists("trainer/")
# Load the trained mode
#recognizer.read('trainer/trainer.yml')
# Load prebuilt model for Frontal Face
#cascadePath = "_frontalface_default.xml"
# Create classifier from prebuilt model
faceCascade = cv2.CascadeClassifier('opencv-files/lbpcascade_frontalface.xml');
# Set the font style
font = cv2.FONT_HERSHEY_SIMPLEX
# Initialize and start the video frame capture
cam = cv2.VideoCapture(0)
# Loop
while True:
# Read the video frame
ret, im =cam.read()
# Convert the captured frame into grayscale
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
# Get all face from the video frame
faces = faceCascade.detectMultiScale(gray, 1.2,5)
# For each face in faces
for(x,y,w,h) in faces:
# Create rectangle around the face
cv2.rectangle(im, (x-20,y-20), (x+w+20,y+h+20), (0,255,0), 4)
# Recognize the face belongs to which ID
Id, confidence = recognizer.predict(gray[y:y+h,x:x+w])
# Check the ID if exist
if(Id == 1):
Id = "Gopikishan {0:.2f}%".format(round(100 - confidence, 2))
elif(Id==2):
Id = "Namrata {0:.2f}%".format(round(100 - confidence, 2))
elif(Id==3):
Id = "Mummy {0:.2f}%".format(round(100 - confidence, 2))
else:
Id = "Unknown {0:.2f}%".format(round(100 - confidence, 2))
# Put text describe who is in the picture
cv2.rectangle(im, (x-22,y-90), (x+w+22, y-22), (0,255,0), -1)
cv2.putText(im, str(Id), (x,y-40), font, 1, (255,255,255), 3)
# Display the video frame with the bounded rectangle
cv2.imshow('im',im)
# If 'q' is pressed, close program
if cv2.waitKey(10) & 0xFF == ord('q'):
break
# Stop the camera
cam.release()
# Close all windows
cv2.destroyAllWindows()