dhikri commited on
Commit
acfe1ce
1 Parent(s): 68c424b

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +13 -0
  2. face_rec.py +207 -0
app.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+
4
+
5
+ st.set_page_config(page_title='Attendance System',layout='wide')
6
+
7
+ st.header('Attendance System using Face Recognition')
8
+
9
+ with st.spinner("Loading Models and Conneting to Redis db ..."):
10
+ import face_rec
11
+
12
+ st.success('Model loaded sucesfully')
13
+ st.success('Redis db sucessfully connected')
face_rec.py ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import pandas as pd
3
+ import cv2
4
+
5
+ import redis
6
+
7
+ # insight face
8
+ from insightface.app import FaceAnalysis
9
+ from sklearn.metrics import pairwise
10
+ # time
11
+ import time
12
+ from datetime import datetime
13
+
14
+ import os
15
+
16
+
17
+
18
+
19
+ # Connect to Redis Client
20
+ hostname = 'redis-11109.c321.us-east-1-2.ec2.cloud.redislabs.com'
21
+ portnumber = 11109
22
+ password = 'HI3acnzpSHJcssm7qtuuv7GmeakjIEKl'
23
+
24
+ r = redis.StrictRedis(host=hostname,
25
+ port=portnumber,
26
+ password=password)
27
+
28
+ # Retrive Data from database
29
+ def retrive_data(name):
30
+ retrive_dict= r.hgetall(name)
31
+ retrive_series = pd.Series(retrive_dict)
32
+ retrive_series = retrive_series.apply(lambda x: np.frombuffer(x,dtype=np.float32))
33
+ index = retrive_series.index
34
+ index = list(map(lambda x: x.decode(), index))
35
+ retrive_series.index = index
36
+ retrive_df = retrive_series.to_frame().reset_index()
37
+ retrive_df.columns = ['name_role','facial_features']
38
+ retrive_df[['Name','Role']] = retrive_df['name_role'].apply(lambda x: x.split('@')).apply(pd.Series)
39
+ return retrive_df[['Name','Role','facial_features']]
40
+
41
+
42
+ # configure face analysis
43
+ faceapp = FaceAnalysis(name='buffalo_sc',root='insightface_model', providers = ['CPUExecutionProvider'])
44
+ faceapp.prepare(ctx_id = 0, det_size=(640,640), det_thresh = 0.5)
45
+
46
+ # ML Search Algorithm
47
+ def ml_search_algorithm(dataframe,feature_column,test_vector,
48
+ name_role=['Name','Role'],thresh=0.5):
49
+ """
50
+ cosine similarity base search algorithm
51
+ """
52
+ # step-1: take the dataframe (collection of data)
53
+ dataframe = dataframe.copy()
54
+ # step-2: Index face embeding from the dataframe and convert into array
55
+ X_list = dataframe[feature_column].tolist()
56
+ x = np.asarray(X_list)
57
+
58
+ # step-3: Cal. cosine similarity
59
+ similar = pairwise.cosine_similarity(x,test_vector.reshape(1,-1))
60
+ similar_arr = np.array(similar).flatten()
61
+ dataframe['cosine'] = similar_arr
62
+
63
+ # step-4: filter the data
64
+ data_filter = dataframe.query(f'cosine >= {thresh}')
65
+ if len(data_filter) > 0:
66
+ # step-5: get the person name
67
+ data_filter.reset_index(drop=True,inplace=True)
68
+ argmax = data_filter['cosine'].argmax()
69
+ person_name, person_role = data_filter.loc[argmax][name_role]
70
+
71
+ else:
72
+ person_name = 'Unknown'
73
+ person_role = 'Unknown'
74
+
75
+ return person_name, person_role
76
+
77
+
78
+ ### Real Time Prediction
79
+ # we need to save logs for every 1 mins
80
+ class RealTimePred:
81
+ def __init__(self):
82
+ self.logs = dict(name=[],role=[],current_time=[])
83
+
84
+ def reset_dict(self):
85
+ self.logs = dict(name=[],role=[],current_time=[])
86
+
87
+ def saveLogs_redis(self):
88
+ # step-1: create a logs dataframe
89
+ dataframe = pd.DataFrame(self.logs)
90
+ # step-2: drop the duplicate information (distinct name)
91
+ dataframe.drop_duplicates('name',inplace=True)
92
+ # step-3: push data to redis database (list)
93
+ # encode the data
94
+ name_list = dataframe['name'].tolist()
95
+ role_list = dataframe['role'].tolist()
96
+ ctime_list = dataframe['current_time'].tolist()
97
+ encoded_data = []
98
+ for name, role, ctime in zip(name_list, role_list, ctime_list):
99
+ if name != 'Unknown':
100
+ concat_string = f"{name}@{role}@{ctime}"
101
+ encoded_data.append(concat_string)
102
+
103
+ if len(encoded_data) >0:
104
+ r.lpush('attendance:logs',*encoded_data)
105
+
106
+
107
+ self.reset_dict()
108
+
109
+
110
+ def face_prediction(self,test_image, dataframe,feature_column,
111
+ name_role=['Name','Role'],thresh=0.5):
112
+ # step-1: find the time
113
+ current_time = str(datetime.now())
114
+
115
+ # step-1: take the test image and apply to insight face
116
+ results = faceapp.get(test_image)
117
+ test_copy = test_image.copy()
118
+ # step-2: use for loop and extract each embedding and pass to ml_search_algorithm
119
+
120
+ for res in results:
121
+ x1, y1, x2, y2 = res['bbox'].astype(int)
122
+ embeddings = res['embedding']
123
+ person_name, person_role = ml_search_algorithm(dataframe,
124
+ feature_column,
125
+ test_vector=embeddings,
126
+ name_role=name_role,
127
+ thresh=thresh)
128
+ if person_name == 'Unknown':
129
+ color =(0,0,255) # bgr
130
+ else:
131
+ color = (0,255,0)
132
+
133
+ cv2.rectangle(test_copy,(x1,y1),(x2,y2),color)
134
+
135
+ text_gen = person_name
136
+ cv2.putText(test_copy,text_gen,(x1,y1),cv2.FONT_HERSHEY_DUPLEX,0.7,color,2)
137
+ cv2.putText(test_copy,current_time,(x1,y2+10),cv2.FONT_HERSHEY_DUPLEX,0.7,color,2)
138
+ # save info in logs dict
139
+ self.logs['name'].append(person_name)
140
+ self.logs['role'].append(person_role)
141
+ self.logs['current_time'].append(current_time)
142
+
143
+
144
+ return test_copy
145
+
146
+
147
+ #### Registration Form
148
+ class RegistrationForm:
149
+ def __init__(self):
150
+ self.sample = 0
151
+ def reset(self):
152
+ self.sample = 0
153
+
154
+ def get_embedding(self,frame):
155
+ # get results from insightface model
156
+ results = faceapp.get(frame,max_num=1)
157
+ embeddings = None
158
+ for res in results:
159
+ self.sample += 1
160
+ x1, y1, x2, y2 = res['bbox'].astype(int)
161
+ cv2.rectangle(frame, (x1,y1),(x2,y2),(0,255,0),1)
162
+ # put text samples info
163
+ text = f"samples = {self.sample}"
164
+ cv2.putText(frame,text,(x1,y1),cv2.FONT_HERSHEY_DUPLEX,0.6,(255,255,0),2)
165
+
166
+ # facial features
167
+ embeddings = res['embedding']
168
+
169
+ return frame, embeddings
170
+
171
+ def save_data_in_redis_db(self,name,role):
172
+ # validation name
173
+ if name is not None:
174
+ if name.strip() != '':
175
+ key = f'{name}@{role}'
176
+ else:
177
+ return 'name_false'
178
+ else:
179
+ return 'name_false'
180
+
181
+ # if face_embedding.txt exists
182
+ if 'face_embedding.txt' not in os.listdir():
183
+ return 'file_false'
184
+
185
+
186
+ # step-1: load "face_embedding.txt"
187
+ x_array = np.loadtxt('face_embedding.txt',dtype=np.float32) # flatten array
188
+
189
+ # step-2: convert into array (proper shape)
190
+ received_samples = int(x_array.size/512)
191
+ x_array = x_array.reshape(received_samples,512)
192
+ x_array = np.asarray(x_array)
193
+
194
+ # step-3: cal. mean embeddings
195
+ x_mean = x_array.mean(axis=0)
196
+ x_mean = x_mean.astype(np.float32)
197
+ x_mean_bytes = x_mean.tobytes()
198
+
199
+ # step-4: save this into redis database
200
+ # redis hashes
201
+ r.hset(name='academy:register',key=key,value=x_mean_bytes)
202
+
203
+ #
204
+ os.remove('face_embedding.txt')
205
+ self.reset()
206
+
207
+ return True