Graduate

Modify client GUI

...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
5 import tkinter as tk 5 import tkinter as tk
6 import tkinter.font 6 import tkinter.font
7 import tkinter.messagebox 7 import tkinter.messagebox
8 +import tkinter.scrolledtext
8 import threading 9 import threading
9 import torch 10 import torch
10 import numpy as np 11 import numpy as np
...@@ -48,9 +49,17 @@ class Client(tk.Frame): ...@@ -48,9 +49,17 @@ class Client(tk.Frame):
48 self.cap.set(3, self.cam_width) 49 self.cap.set(3, self.cam_width)
49 self.cap.set(4, self.cam_height) 50 self.cap.set(4, self.cam_height)
50 51
52 + # Application Function
53 +
54 + # cam에서 MTCNN 적용하는 영역
55 + self.detecting_square = (200, 200)
56 +
57 + # 영상 위에 사각형 색상 지정
58 + self.rectangle_color = (0, 0, 255)
59 +
51 # tkinter GUI 60 # tkinter GUI
52 self.width = 740 61 self.width = 740
53 - self.height = 640 62 + self.height = 700
54 self.parent = parent 63 self.parent = parent
55 self.parent.title("출석시스템") 64 self.parent.title("출석시스템")
56 self.parent.geometry("%dx%d+100+100" % (self.width, self.height)) 65 self.parent.geometry("%dx%d+100+100" % (self.width, self.height))
...@@ -74,13 +83,19 @@ class Client(tk.Frame): ...@@ -74,13 +83,19 @@ class Client(tk.Frame):
74 self.label = tk.Label(self, image=image) 83 self.label = tk.Label(self, image=image)
75 self.label.grid(row=1, column=0, columnspan=20) 84 self.label.grid(row=1, column=0, columnspan=20)
76 85
77 - self.log = tk.Text(self) 86 + self.log = tk.scrolledtext.ScrolledText(self, wrap = tk.WORD, state=tk.DISABLED, width = 96, height = 10)
78 self.log.grid(row=2, column=0, columnspan=20) 87 self.log.grid(row=2, column=0, columnspan=20)
79 88
80 89
81 self.quit = tk.Button(self, text="나가기", fg="red", command=self.stop) 90 self.quit = tk.Button(self, text="나가기", fg="red", command=self.stop)
82 - self.quit.grid(row=5, column=10) 91 + self.quit.grid(row=3, column=10)
83 92
93 + def logging(self, text):
94 + self.log.config(state=tk.NORMAL)
95 + self.log.insert(tkinter.CURRENT, text)
96 + self.log.insert(tkinter.CURRENT, '\n')
97 + self.log.config(state=tk.DISABLED)
98 +
84 99
85 def detect_face(self, frame): 100 def detect_face(self, frame):
86 results = self.mtcnn.detect(frame) 101 results = self.mtcnn.detect(frame)
...@@ -97,8 +112,6 @@ class Client(tk.Frame): ...@@ -97,8 +112,6 @@ class Client(tk.Frame):
97 x1, y1, x2, y2 = box 112 x1, y1, x2, y2 = box
98 if (x2-x1) * (y2-y1) < 15000: 113 if (x2-x1) * (y2-y1) < 15000:
99 # 얼굴 해상도가 너무 낮으면 무시 114 # 얼굴 해상도가 너무 낮으면 무시
100 - self.alert.config(text= "카메라에 더 가까이 접근해주세요.", fg="red")
101 - self.alert.update()
102 continue 115 continue
103 image = frame 116 image = frame
104 image_list.append(image) 117 image_list.append(image)
...@@ -109,24 +122,35 @@ class Client(tk.Frame): ...@@ -109,24 +122,35 @@ class Client(tk.Frame):
109 def mainthread(self): 122 def mainthread(self):
110 t = threading.currentThread() 123 t = threading.currentThread()
111 asyncio.set_event_loop(self.event_loop) 124 asyncio.set_event_loop(self.event_loop)
125 + x1 = int(self.cam_width / 2 - self.detecting_square[0] / 2)
126 + x2 = int(self.cam_width / 2 + self.detecting_square[0] / 2)
127 + y1 = int(self.cam_height / 2 - self.detecting_square[1] / 2)
128 + y2 = int(self.cam_height / 2 + self.detecting_square[1] / 2)
112 while getattr(t, "do_run", True): 129 while getattr(t, "do_run", True):
113 ret, frame = self.cap.read() 130 ret, frame = self.cap.read()
114 -
115 # model에 이용하기 위해 convert 131 # model에 이용하기 위해 convert
116 converted = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 132 converted = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
117 - face_list, image_list = self.detect_face(converted) 133 + face_list, image_list = self.detect_face(converted[y1:y2, x1:x2])
118 - 134 +
135 + # 얼굴이 인식되면 출석요청
136 + self.event_loop.run_until_complete(self.send_face(face_list, image_list))
137 +
119 # show image 138 # show image
139 + frame = cv2.rectangle(frame, (x1, y1), (x2, y2), self.rectangle_color, 3)
140 + converted = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
141 + # 거울상으로 보여준다
142 + converted = cv2.flip(converted,1)
120 image = Image.fromarray(converted) 143 image = Image.fromarray(converted)
121 image = ImageTk.PhotoImage(image) 144 image = ImageTk.PhotoImage(image)
122 self.label.configure(image=image) 145 self.label.configure(image=image)
123 self.label.image = image # kind of double buffering 146 self.label.image = image # kind of double buffering
124 147
125 - # 얼굴이 인식되면 요청 148 + @asyncio.coroutine
126 - if face_list: 149 + def set_rectangle(self):
127 - self.event_loop.run_until_complete(self.send_face(face_list, image_list)) 150 + self.rectangle_color = (255, 0, 0)
128 - 151 + yield from asyncio.sleep(1)
129 - 152 + self.rectangle_color = (0, 0, 255)
153 +
130 async def wait(self, n): 154 async def wait(self, n):
131 await asyncio.sleep(n) 155 await asyncio.sleep(n)
132 156
...@@ -141,16 +165,16 @@ class Client(tk.Frame): ...@@ -141,16 +165,16 @@ class Client(tk.Frame):
141 data = json.loads(recv) 165 data = json.loads(recv)
142 if data['status'] == 'success': 166 if data['status'] == 'success':
143 # 성공 167 # 성공
144 - self.log.insert(tkinter.CURRENT, data['student_id'] + 'is attend') 168 + self.logging('출석확인: ' + data['student_id'])
145 - self.log.insert(tkinter.CURRENT, '\n') 169 + asyncio.ensure_future(self.set_rectangle())
146 else: 170 else:
147 - self.log.insert(tkinter.CURRENT, 'verification failed:' + data['status'])
148 - self.log.insert(tkinter.CURRENT, '\n')
149 if data['status'] == 'failed': 171 if data['status'] == 'failed':
150 send = json.dumps({'action': 'save_image', 'image': image.tolist()}) 172 send = json.dumps({'action': 'save_image', 'image': image.tolist()})
173 + await websocket.send(send)
174 + elif data['status'] == 'already':
175 + asyncio.ensure_future(self.set_rectangle())
151 except Exception as e: 176 except Exception as e:
152 - self.log.insert(tkinter.CURRENT, e) 177 + self.logging(e)
153 - self.log.insert(tkinter.CURRENT, '\n')
154 178
155 def stop(self): 179 def stop(self):
156 self.thread.do_run = False 180 self.thread.do_run = False
...@@ -164,4 +188,4 @@ if __name__ == '__main__': ...@@ -164,4 +188,4 @@ if __name__ == '__main__':
164 root = tk.Tk() 188 root = tk.Tk()
165 Client(root) 189 Client(root)
166 root.mainloop() 190 root.mainloop()
167 -
...\ No newline at end of file ...\ No newline at end of file
191 +
......
...@@ -164,6 +164,8 @@ class Register(tk.Frame): ...@@ -164,6 +164,8 @@ class Register(tk.Frame):
164 164
165 # show image 165 # show image
166 converted = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 166 converted = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
167 + # 유저에게 보여줄 땐 거울상으로 보여준다
168 + converted = cv2.flip(converted,1)
167 image = Image.fromarray(converted) 169 image = Image.fromarray(converted)
168 image = ImageTk.PhotoImage(image) 170 image = ImageTk.PhotoImage(image)
169 self.label.configure(image=image) 171 self.label.configure(image=image)
......
...@@ -51,18 +51,18 @@ async def register(websocket): ...@@ -51,18 +51,18 @@ async def register(websocket):
51 global clients 51 global clients
52 async with lock: 52 async with lock:
53 clients.add(websocket) 53 clients.add(websocket)
54 - remote_ip = websocket.remote_address[0] 54 + #remote_ip = websocket.remote_address[0]
55 - msg='[{ip}] connected'.format(ip=remote_ip) 55 + #msg='[{ip}] connected'.format(ip=remote_ip)
56 - print(msg) 56 + #print(msg)
57 57
58 async def unregister(websocket): 58 async def unregister(websocket):
59 global lock 59 global lock
60 global clients 60 global clients
61 async with lock: 61 async with lock:
62 clients.remove(websocket) 62 clients.remove(websocket)
63 - remote_ip = websocket.remote_address[0] 63 + #remote_ip = websocket.remote_address[0]
64 - msg='[{ip}] disconnected'.format(ip=remote_ip) 64 + #msg='[{ip}] disconnected'.format(ip=remote_ip)
65 - print(msg) 65 + #print(msg)
66 66
67 async def thread(websocket, path): 67 async def thread(websocket, path):
68 await register(websocket) 68 await register(websocket)
......