Showing
1 changed file
with
46 additions
and
35 deletions
... | @@ -8,7 +8,7 @@ import websockets | ... | @@ -8,7 +8,7 @@ import websockets |
8 | from io import BytesIO | 8 | from io import BytesIO |
9 | 9 | ||
10 | import pymysql | 10 | import pymysql |
11 | -import datetime | 11 | +from datetime import datetime |
12 | 12 | ||
13 | from PIL import Image, ImageDraw | 13 | from PIL import Image, ImageDraw |
14 | from IPython import display | 14 | from IPython import display |
... | @@ -23,7 +23,7 @@ model = InceptionResnetV1().eval().to(device) | ... | @@ -23,7 +23,7 @@ model = InceptionResnetV1().eval().to(device) |
23 | attendance_db = pymysql.connect( | 23 | attendance_db = pymysql.connect( |
24 | user='root', | 24 | user='root', |
25 | passwd='5978', | 25 | passwd='5978', |
26 | - host='localhost', | 26 | + host='127.0.0.1', |
27 | db='attendance', | 27 | db='attendance', |
28 | charset='utf8' | 28 | charset='utf8' |
29 | ) | 29 | ) |
... | @@ -39,7 +39,7 @@ async def get_embeddings(face_list): | ... | @@ -39,7 +39,7 @@ async def get_embeddings(face_list): |
39 | return yhat | 39 | return yhat |
40 | 40 | ||
41 | async def get_distance(arr1, arr2): | 41 | async def get_distance(arr1, arr2): |
42 | - distance = (arr1 - arr2).norm().item() | 42 | + distance = np.linalg.norm(arr1 - arr2) |
43 | return distance | 43 | return distance |
44 | 44 | ||
45 | def get_argmin(someone, database): | 45 | def get_argmin(someone, database): |
... | @@ -67,10 +67,8 @@ async def unregister(websocket): | ... | @@ -67,10 +67,8 @@ async def unregister(websocket): |
67 | print(msg) | 67 | print(msg) |
68 | 68 | ||
69 | async def thread(websocket, path): | 69 | async def thread(websocket, path): |
70 | - # register(websocket) sends user_event() to websocket | ||
71 | await register(websocket) | 70 | await register(websocket) |
72 | try: | 71 | try: |
73 | - # await websocket.send(state_event()) | ||
74 | async for message in websocket: | 72 | async for message in websocket: |
75 | data = json.loads(message) | 73 | data = json.loads(message) |
76 | remote_ip = websocket.remote_address[0] | 74 | remote_ip = websocket.remote_address[0] |
... | @@ -89,79 +87,92 @@ async def thread(websocket, path): | ... | @@ -89,79 +87,92 @@ async def thread(websocket, path): |
89 | cursor = attendance_db.cursor(pymysql.cursors.DictCursor) | 87 | cursor = attendance_db.cursor(pymysql.cursors.DictCursor) |
90 | 88 | ||
91 | # 학생을 찾음 | 89 | # 학생을 찾음 |
92 | - sql = "SELECT student_id FROM student WHERE student_id = %s;" | 90 | + sql = "SELECT student_id FROM student WHERE student_id = %s;" |
93 | cursor.execute(sql, (student_id)) | 91 | cursor.execute(sql, (student_id)) |
94 | 92 | ||
95 | # DB에 학생이 없으면 등록 | 93 | # DB에 학생이 없으면 등록 |
96 | if not cursor.fetchone(): | 94 | if not cursor.fetchone(): |
97 | - sql = "insert into student(student_id, student_name) values (%s, %s)" | 95 | + sql = "INSERT INTO student(student_id, student_name) VALUES (%s, %s)" |
98 | cursor.execute(sql, (student_id, student_name)) | 96 | cursor.execute(sql, (student_id, student_name)) |
99 | attendance_db.commit() | 97 | attendance_db.commit() |
98 | + msg='[{ip}] {id} is registered'.format(ip=remote_ip, id=student_id) | ||
99 | + print(msg) | ||
100 | 100 | ||
101 | # student_embedding Table에 등록 | 101 | # student_embedding Table에 등록 |
102 | embedding = await get_embeddings(face) | 102 | embedding = await get_embeddings(face) |
103 | embedding = embedding.detach().numpy().tobytes() | 103 | embedding = embedding.detach().numpy().tobytes() |
104 | - embedding_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S') | 104 | + embedding_date = datetime.now().strftime('%Y-%m-%d') |
105 | - sql = "insert into student_embedding(student_id, embedding_date, embedding) values (%s, %s, %s)" | 105 | + sql = "insert into student_embedding(student_id, embedding_date, embedding) values (%s, %s, _binary %s)" |
106 | cursor.execute(sql, (student_id, embedding_date, embedding)) | 106 | cursor.execute(sql, (student_id, embedding_date, embedding)) |
107 | attendance_db.commit() | 107 | attendance_db.commit() |
108 | - await websocket.send('{id} registered'.format(id=student_id)) | 108 | + send = json.dumps({'status': 'success', 'student_id': student_id}) |
109 | - elif data['action'] == "verify": | 109 | + await websocket.send(send) |
110 | + | ||
111 | + elif data['action'] == 'verify': | ||
110 | # log | 112 | # log |
111 | msg='[{ip}] verify face'.format(ip=remote_ip) | 113 | msg='[{ip}] verify face'.format(ip=remote_ip) |
112 | print(msg) | 114 | print(msg) |
113 | - ############### | ||
114 | 115 | ||
115 | # load json | 116 | # load json |
116 | face = np.asarray(data['MTCNN'], dtype = np.float32) | 117 | face = np.asarray(data['MTCNN'], dtype = np.float32) |
117 | face = face.reshape((1,3,160,160)) | 118 | face = face.reshape((1,3,160,160)) |
118 | 119 | ||
119 | - # embedding 구하기 | ||
120 | embedding = await get_embeddings(face) | 120 | embedding = await get_embeddings(face) |
121 | embedding = embedding.detach().numpy() | 121 | embedding = embedding.detach().numpy() |
122 | - # embedding.numpy() | ||
123 | - # [1, 512] numpy()임 | ||
124 | - # np.frombuffer()로 불러오는 것이 좋을 듯. | ||
125 | - # DB에 연결 | ||
126 | - cursor = attendance_db.cursor(pymysql.cursors.DictCursor) | ||
127 | 122 | ||
128 | - # 학생을 찾음 | 123 | + # 가장 비슷한 Embedding을 찾는 SQL |
124 | + cursor = attendance_db.cursor(pymysql.cursors.DictCursor) | ||
129 | sql = "SELECT student_id, embedding FROM student_embedding;" | 125 | sql = "SELECT student_id, embedding FROM student_embedding;" |
130 | cursor.execute(sql) | 126 | cursor.execute(sql) |
131 | result = cursor.fetchall() | 127 | result = cursor.fetchall() |
132 | - verified_id = '0000000000' | 128 | + verified_id = '0' |
133 | - distance_min = 1 | 129 | + distance_min = 1.0 |
134 | for row_data in result: | 130 | for row_data in result: |
135 | db_embedding = np.frombuffer(row_data['embedding'], dtype=np.float32) | 131 | db_embedding = np.frombuffer(row_data['embedding'], dtype=np.float32) |
136 | db_embedding = db_embedding.reshape((1,512)) | 132 | db_embedding = db_embedding.reshape((1,512)) |
137 | - distance = get_distance(embedding, db_embedding) | 133 | + distance = await get_distance(embedding, db_embedding) |
138 | if (distance < distance_min): | 134 | if (distance < distance_min): |
139 | verified_id = row_data['student_id'] | 135 | verified_id = row_data['student_id'] |
140 | distance_min = distance | 136 | distance_min = distance |
141 | 137 | ||
142 | # 출석 데이터 전송 | 138 | # 출석 데이터 전송 |
143 | - data = '' | 139 | + send = '' |
140 | + print('[debug] distance:', distance_min) | ||
144 | if distance_min >= 0.6: | 141 | if distance_min >= 0.6: |
145 | # 해당하는 사람 DB에 없음 | 142 | # 해당하는 사람 DB에 없음 |
146 | - print('verification failed: not in DB') | 143 | + msg='[{ip}] verification failed'.format(ip=remote_ip) |
147 | - data = json.dumps({'state': 'fail'}) | 144 | + print(msg) |
145 | + send = json.dumps({'status': 'fail'}) | ||
148 | else: | 146 | else: |
149 | # 해당하는 사람 DB에 있음 | 147 | # 해당하는 사람 DB에 있음 |
150 | - print('verification success:', verified_id) | 148 | + # logging |
151 | - data = json.dumps({'state': 'success', 'id': verified_id}) | 149 | + msg='[{ip}] verification success {id}'.format(ip=remote_ip, id=verified_id) |
152 | - await websocket.send(data) | 150 | + print(msg) |
151 | + | ||
152 | + # TODO: lecture DB에 tuple 삽입해야 아래 코드가 돌아감 | ||
153 | + # 해당하는 사람이 DB에 있으면 출석 처리 | ||
154 | + #date = datetime.now().strftime('%Y-%m-%d') | ||
155 | + #sql = "INSERT INTO student_attendance(lecture_id, student_id, date) VALUES (%s, %s, %s)" | ||
156 | + #cursor.execute(sql, ('0', verified_id, date)) | ||
157 | + | ||
158 | + # client에 전달 | ||
159 | + send = json.dumps({'status': 'success', 'student_id': verified_id}) | ||
160 | + await websocket.send(send) | ||
153 | elif data['action'] == "save_image": | 161 | elif data['action'] == "save_image": |
154 | # 출석이 제대로 이뤄지지 않으면 이미지를 저장하여 | 162 | # 출석이 제대로 이뤄지지 않으면 이미지를 저장하여 |
155 | # 나중에 교강사가 출석을 확인할 수 있도록 한다 | 163 | # 나중에 교강사가 출석을 확인할 수 있도록 한다 |
156 | - arr = np.asarray(data['image'], dtype = np.uint8) | ||
157 | - # 이 데이터는 데이터베이스(과목명/일자/undefined)에 저장하는 것이 좋을듯 | ||
158 | - # image = Image.fromarray(arr) | ||
159 | - # image.save('face.jpg')# storage에 데이터 저장 | ||
160 | - remote_ip = websocket.remote_address[0] | ||
161 | msg='[{ip}] save image'.format(ip=remote_ip) | 164 | msg='[{ip}] save image'.format(ip=remote_ip) |
162 | print(msg) | 165 | print(msg) |
163 | - ### | 166 | + |
164 | - await websocket.send('정해갑') | 167 | + arr = np.asarray(data['image'], dtype = np.uint8) |
168 | + blob = arr.tobytes() | ||
169 | + date = datetime.now().strftime('%Y-%m-%d') | ||
170 | + | ||
171 | + # TODO: lecture DB에 tuple 삽입해야 아래 코드가 돌아감 | ||
172 | + #cursor = attendance_db.cursor(pymysql.cursors.DictCursor) | ||
173 | + #sql = "INSERT INTO undefined_image(lecture_id, date, image, width, height) VALUES (%s, %s, _binary %s, %s, %s)" | ||
174 | + #cursor.execute(sql, ('0', date, blob, arr.shape[0], arr.shape[1])) | ||
175 | + #attendance_db.commit() | ||
165 | else: | 176 | else: |
166 | print("unsupported event: {}", data) | 177 | print("unsupported event: {}", data) |
167 | finally: | 178 | finally: | ... | ... |
-
Please register or login to post a comment