-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathface_unlock.py
executable file
·164 lines (133 loc) · 6.45 KB
/
face_unlock.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
#!/usr/bin/env python3
# import the necessary packages
from imutils import face_utils
import numpy as np
import argparse
import imutils
import dlib
#import h5py
import pickle
import face_recognition
import os
import sys
import time
import json
import cv2 as cv
import paho.mqtt.client as mqtt
# mema oriented libraries
import memalib.mema_utility as mu
import logging
from configobj import ConfigObj
# FIXME: program should really be 'control by face', does sign out as well
def on_connect(client, userdata, flags, rc):
#print("Connected with result code "+str(rc))
client.subscribe("hermes/intent/Unlock")
client.subscribe("hermes/intent/Lock")
def on_message(client, userdata, msg):
#logging.debug(userdata)
decoded_message=str(msg.payload.decode("utf-8"))
intent_data =json.loads(decoded_message)
#logging.debug('intent name is ' + intent_data['intent']['intentName'])
if intent_data['intent']['intentName'] == 'Unlock':
#logging.debug('to here')
face_unlock(userdata)
elif intent_data['intent']['intentName'] == 'Lock':
logging.debug('intent name is ' + intent_data['intent']['intentName'])
#mu.run_sign_out(None,None) #FIXME: need to fix some of these function signatures
mu.curl_speak(userdata['en_prompts']['bye_bye'])
mu.open_url('static/offline.html', userdata)
#client.disconnect()
def face_unlock(config):
mu.curl_speak('please_look_directly_at_the_camera')
# mema integration
#FIXME: known_face_count face must be recognised 10 times, simplistic hack to deal with photos and relaxed recognition
#FIXME: if 10 unknowns, display privacy page and sign in as guest account
known_face_count = 0
unknown_face_count = 0
with open("/home/pi/mema/face_data/trained_knn_model.clf", 'rb') as f:
knn_clf = pickle.load(f)
cap = cv.VideoCapture(0)
#cv2.setWindowProperty(WindowName,cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)
if not cap.isOpened():
log.debugging('no image')
exit()
while True:
# Capture frame-by-frame
ret, frame = cap.read()
X_face_locations = face_recognition.face_locations(frame,1,model="hog")
#X_face_locations = face_recognition.face_locations(frame,no_of_times_to_upsample=1,model="cnn")
#logging.debug(X_face_locations)
title = 'Mema3 Unlock'
if len(X_face_locations) != 0:
# Find encodings for faces in the test iamge
faces_encodings = face_recognition.face_encodings(frame, known_face_locations=X_face_locations)
# Use the KNN model to find the best matches for the test face
closest_distances = knn_clf.kneighbors(faces_encodings, n_neighbors=1)
are_matches = [closest_distances[0][i][0] <= 0.4 for i in range(len(X_face_locations))]
# Predict classes and remove classifications that aren't within the threshold
predictions = [(pred, loc) if rec else ("unknown", loc) for pred, loc, rec in zip(knn_clf.predict(faces_encodings), X_face_locations, are_matches)]
for name, (top, right, bottom, left) in predictions:
# let's be polite shall we!
head_title = ''
if name not in "unknown":
head_title = name
else:
head_title = 'Honoured Guest'
cv.rectangle(frame, (left,bottom),(right,top), (0, 255, 0), 2)
# show the face number
cv.putText(frame, "{}".format(head_title), (left-10, top-10),cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
if name not in "unknown":
known_face_count += 1
cv.imshow(title,frame)
cv.setWindowProperty(title, cv.WND_PROP_TOPMOST, 1)
if cv.waitKey(20) == 'ESC':
break
if known_face_count == 10:
(first_name, last_name) = name.split()
mu.curl_speak('Hello_' + first_name)
mu.database_sign_in(first_name, last_name, config)
mu.declare_mema_health(config)
mu.curl_speak(config['en_prompts']['ok_going'])
cap.release()
cv.destroyAllWindows()
# Doesn't pass through privacy because, in principle onboarded
mu.open_url('memories.html',config)
else:
unknown_face_count += 1
cv.imshow(title,frame)
cv.setWindowProperty(title, cv.WND_PROP_TOPMOST, 1)
cv.waitKey(20)
if unknown_face_count == 30:
mu.curl_speak('Hello_honored_guest')
mu.database_sign_in('Guest', 'Account',config)
mu.declare_mema_health(config)
mu.curl_speak(config['en_prompts']['ok_going'])
cap.release()
cv.destroyAllWindows()
# Passes through privacy, since guest
mu.open_url('static/privacy.html',config)
continue
else:
continue
#logging.debug('reach here?')
mu.curl_speak('Sorry_no_human_faces_found')
# When everything done, release the capture
cap.release()
cv.destroyAllWindows()
return
def main():
#FIXME: started as systemd service, so needs full path?
try:
config = ConfigObj('/home/pi/mema/etc/mema.ini')
#print(config)
except:
print('config load failed in take_picture.py')
logging.basicConfig(filename=config['main']['logfile_name'], format='%(asctime)s %(message)s', encoding='utf-8', level=logging.DEBUG)
client = mqtt.Client(userdata=config)
client.connect('localhost',1883,60)
client.on_connect = on_connect
client.on_message = on_message
#FIXME: yes this is a small low load server, listening for log ins
client.loop_forever()
if __name__ == '__main__':
main()