-
Notifications
You must be signed in to change notification settings - Fork 0
/
script2.pyw
249 lines (226 loc) · 8.68 KB
/
script2.pyw
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
import numpy as np
import pickle
import cv2
#from Tkinter import *
import tkinter as Tk
#Functions:#Data Manipulation Functions:
def loadDictionary():
'''Opens the pickle file and returns
the dictionary of names'''
pickle_in=open("faces.pickle","rb")
dictionaryofnames=pickle.load(pickle_in)
pickle_in.close()
return dictionaryofnames
def rewriteDictionary():
'''Opens the pickle file and stores the dictionary of
names overwriting the previous value'''
#print(names)
pickle_out = open("faces.pickle","wb")
pickle.dump(names, pickle_out)
pickle_out.close()
def clearRecords():
'''Opens the pickle file and rewrites it with an empty
dictionary and also resets other variables'''
global facenumber
global names
global dataf
global labels
pickle_out = open("faces.pickle","wb")
pickle.dump({}, pickle_out)
pickle_out.close()
facenumber=0
names={}
dataf=[]
labels=[]
def loadLists(names):
'''Loads the faces from the numpyarrays and then
concatenates it into an array dataf and also initialises the labels
INPUT:Dictionary of names
OUTPUT:dataf and labels
'''
if(len(names)==0):
return ([],[])
filelist=[]
for i in range(len(names)):
npfname="FACE"+str(i)+'.npy'
tmpobj=np.load(npfname).reshape((20,50*50*3)) #FACE i
filelist.append(tmpobj)
#Create a Matrix to store labels:
labels=np.zeros((20*len(names),1))
for i in range(len(names)):
for j in range(20):
labels[j+20*i]=float(i)
listoffiles=[]
for i in range(len(names)):
listoffiles.append(filelist[i])
#Combine into one array:
if(len(listoffiles)!=0):
dataf=np.concatenate(listoffiles)
return (dataf,labels)
#Face recording function:
def recordFaces():
'''Detects and saves the face being detected to use for recognition'''
global entry
global facenumber
global names
global dataf
global labels
#Create a new camera object:
camera=cv2.VideoCapture('http://192.168.60.51:8080/video')
#Counter for counting the current frame:
framecount=0
#A list for storing data extracted from faces while recording:
data=[]
while True:
#Read the frame and ret value:
ret,frame=camera.read()
#ret ==1 for a working camera and 0 if not
if ret:
#Convert the given frame into grayscale:
grayframe=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
#Apply the haar cascade to detect the face:
facecoord=face_cascade.detectMultiScale(grayframe,1.3,5)
#facecoord contains the top left corner's coordinates aswell as the height and width of the face
for (x,y,width,height) in facecoord:
#Extract the face from the frame:
face_component=frame[y:y+height,x:x+width,:]
#Resize the frame:
faceresized=cv2.resize(face_component,(50,50))
#Store the data every 10 frames till the data is complete:
if framecount%10==0 and len(data)<20:
data.append(faceresized)
#Draw a rectangle to show the face in the frame:
cv2.rectangle(frame,(x,y),(x+width,y+height),(0,255,255),2)
#Putting the:
info="CAPTURING:"+str((len(data)/20.0)*100)+"%"
cv2.putText(frame,info,(0,30),font,1,(0,255,255),1)
#Increment the framecounter
framecount+=1
#Display the frame:
cv2.imshow('FACE_RECOGNITION_FRAME',frame)
#Stop recording if the escape key is presed or 20 frames have been captured:
if cv2.waitKey(1)==27 or len(data)>=20:
break
else:
#Camera not working:
print("ERROR WHILE OPENING CAMERA")
#Release the camera:
camera.release()
#Destroy all windows created:
cv2.destroyAllWindows()
#Convert data into a numpy array:
data=np.asarray(data)
#Save the face into memory:
savestr="FACE"+str(facenumber)
np.save(savestr,data)
#Add the new face to the dictionary,using the name from the entry field in the tkinter GUI:
names[facenumber]=entry.get()
#Rewrite the dictionary in memory:
rewriteDictionary()
#Reload the dictionary:
names=loadDictionary()
#Readjust the value of the number of faces stored:
facenumber=len(names)
#Reset other variables used:
(dataf,labels)=loadLists(names)
#Face recognition functions:
def distance(x1,x2):
'''Returns the distance'''
return np.sqrt(((x1-x2)**2).sum())
def knn(x, train, targets, k=5):
'''Applys the knn algorithm to determine which face is being detected
INPUT:detected face, dataf, labels
OUTPUT:key
'''
m = train.shape[0]
dist = []
for ix in range(m):
#COMPUTE THE DISTANCE FROM EACH POINT AND STORE IN dist
dist.append(distance(x, train[ix]))
dist = np.asarray(dist)
indx = np.argsort(dist)
sorted_labels = labels[indx][:k]
counts = np.unique(sorted_labels, return_counts=True)
return counts[0][np.argmax(counts[1])]
def recogniseFaces():
'''Detects the faces and recognises the faces present'''
global listofrecognised
listofrecognised=[]
#Check if there are faces to recognise
if(len(names)==0):
return
#Initialise the camera
camera=cv2.VideoCapture('http://192.168.60.51:8080/video')
while True:
#Get the frame:
ret,frame=camera.read()
inframe=[]
if ret==True:
#Convert to grayscale and extract the face:
grayframe=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
facecoord=face_cascade.detectMultiScale(grayframe,1.3,5)
#For each frame:
for (x,y,width,height) in facecoord:
face_component=frame[y:y+height,x:x+width,:]
faceresized=cv2.resize(face_component,(50,50))
#After resizing and processing it is passed to the knn function:
lab=knn(faceresized.flatten(),dataf,labels)
#Name of the detected face is taken from the knn library:
Detected_face=names[int(lab)]
#Adding it to the list of people recognised:
if Detected_face not in listofrecognised:
listofrecognised.append(Detected_face)
if Detected_face not in inframe:
#Display the name:
cv2.putText(frame,Detected_face,(x,y),font,1,(255,143,121),2)
#Draw a rectangle over the face:
cv2.rectangle(frame,(x,y),(x+width,y+height),(255,143,121),2)
inframe.append(Detected_face)
cv2.imshow('FACE_RECOGNITION',frame)
if cv2.waitKey(10)==27:
break;
else:
print("ERROR OPENING CAMERA")
#Stop Recording:
camera.release()
#Terminate the window:
cv2.destroyAllWindows()
def saveRecognised():
'''Saves the list of recognised people into a text file after a recognition session'''
global listofrecognised
f=open('RecognisedList.txt','w')
f.write('List of people recognised:')
for names in listofrecognised:
f.write('\n'+names)
f.close
listofrecognised=[]
##FUNCTIONS END##
listofrecognised=[]
#Load the haar cascade for facial feature detection:
face_cascade=cv2.CascadeClassifier('./haarcascade_ff.xml')
#Font to be used for text in the opencv gui:
font=cv2.FONT_HERSHEY_SIMPLEX
#Load the records:
names=loadDictionary()
#Set the facenumber:
facenumber=len(names)
print(names)
if(facenumber!=0):
(dataf,labels)=loadLists(names)
#GUI using Tkinter:
root=Tk.Tk()
root.title("FACE DETECTION AND RECOGNITION")
label=Tk.Label(text="ENTER THE NAME IN THE ENTRY FIELD BEFORE RECORDING:")
entry=Tk.Entry(root)
record_button=Tk.Button(text="Record Faces",fg="red",command=recordFaces)
detect_button=Tk.Button(text="Recognise Faces",fg="green",command=recogniseFaces)
clear_button=Tk.Button(text="Clear Records",fg="purple",command=clearRecords)
list_button=Tk.Button(text="Save Recognised",fg="blue",command=saveRecognised)
label.grid(row=0)
entry.grid(row=1,columnspan=100)
record_button.grid(row=2,columnspan=100)
detect_button.grid(row=3,columnspan=100)
clear_button.grid(row=4,columnspan=100)
list_button.grid(row=5,columnspan=100)
root.mainloop()
#-------------------#-------------------#-------------------#-------------------#-------------------#