-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp_redal.py
More file actions
256 lines (246 loc) · 14.8 KB
/
app_redal.py
File metadata and controls
256 lines (246 loc) · 14.8 KB
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
250
251
252
253
254
255
256
"""
Author: Redal
Date: 2025/03/03
TODO: 系统函数框架设计,手动选择输入功能
Homepage: https://github.com/Rtwotwo/MMchat.git
"""
import os
import json
import sys
import cv2
import torch
import time
import argparse
import threading
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
from models.face_cls_model import FaceRecognition, face_config
from utils.face_cls import FaceVisiblity, DeciderCenter
from utils.top_mes import GetFaceName, CreateMessageBox
from facenet_pytorch import MTCNN
from app_authorization import LoginInterface
from app_sysfunc import Gesture_Style_APP
current_path = os.path.abspath(os.path.dirname(__file__))
sys.path.append(current_path)
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
######################## 配置tkinter的界面配置 ###########################
def Tkinter_Config():
"""The GUI is defined for tkinter configuration"""
parser = argparse.ArgumentParser(description='MMChat GUI configuration',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument_group('GUI Main Window Settings')
parser.add_argument('--gui_title', type=str, default='MMChat', help='The title of the GUI window')
parser.add_argument('--gui_width', type=str, default='800', help='The width of the GUI window')
parser.add_argument('--gui_height', type=str, default='512', help='The height of the GUI window')
parser.add_argument('--coverimg_path', type=str, default='assets/MMChat_app.jpg', help='The audio shower of the GUI window')
parser.add_argument_group('Facial Authoriation Settings')
parser.add_argument('--face_emb_savepath', type=str, default='./data_cached/', help='Save Facial Embedding SavePath')
parser.add_argument('--face_emb_jsonname', type=str, default='face_emb.json', help='Save Facial Embedding JsonName')
parser.add_argument('--password_emb_savepath', type=str, default='./data_cached/', help='Save Password Embedding SavePath')
parser.add_argument('--password_emb_jsonname', type=str, default='password_emb.json', help='Save Password Embedding JsonName')
args = parser.parse_args()
return args
######################## 构造基本GUI界面框架 ###########################
class MMChatTkinter(tk.Frame):
"""The GUI is designed to interact with multi_models tkinter"""
def __init__(self, root, args):
super().__init__(root)
self.root = root
self.args = args
self.__set_flags__()
self.__set_params__()
self.__widgets__()
# Initialize video capture and threading
self.camera_lock = threading.Lock()
# Initialize functions
self.FaceRe = FaceRecognition(face_config())
self.mtcnn = MTCNN(image_size=512, margin=0, keep_all=False, post_process=True)
def __set_flags__(self):
self.main_window_show = False
self.face_authentication_flag = False
self.button_interaction_flag = False
self.button_funcrelated_flag = False
self.button_systemfunc_flag = False
def __set_params__(self):
with open('data_cached/face_emb.json', 'r', encoding='utf-8') as f:
self.facial_info = json.load(f)
with open('data_cached/password_emb.json', 'r', encoding='utf-8') as f:
self.password_info = json.load(f)
# self.facial_info = {}
# self.password_info = {}
self.name = None
def __widgets__(self):
self.root.title('MMChat-Redal')
self.root.geometry(f'{self.args.gui_width}x{self.args.gui_height}')
self.root.configure(bg='white')
self.main_label = tk.Label(self.root,width=512, height=512); self.main_label.place(x=0, y=0)
# Set the background image for main label
img_tk = ImageTk.PhotoImage(Image.open(self.args.coverimg_path).resize((512,512)))
self.main_label.config(image=img_tk)
self.main_label.image = img_tk
# Set MMChat App Introduction label
self.introduction_label = tk.Label(self.root, font='Arial',bg='white', width=25, height=5)
self.introduction_label.place(x=550, y=0)
self.introduction_label.config(text='MMChat App Introduction')
# Functional Button Related MMchat mode
self.button_authentication = tk.Button(self.root, text='用户注册', font=('Arial',8),
bg='white', fg='black',width=10, height=2, command=self.__button_authentication__)
self.button_authentication.place(x=580, y=300)
self.button_interaction = tk.Button(self.root, text='身份验证', font=('Arial',8),
bg='white', fg='black',width=10, height=2, command=self.__button_interaction__)
self.button_interaction.place(x=680, y=300)
self.button_funcrelated = tk.Button(self.root, text='功能关于', font=('Arial',8),
bg='white', fg='black', width=10, height=2, command=self.__button_funcrelated__)
self.button_funcrelated.place(x=580, y=340)
self.button_systemfunc = tk.Button(self.root, text='系统功能', font=('Arial',8),
bg='white', fg='black', width=10, height=2, command=self.__button_systemfunc__)
self.button_systemfunc.place(x=680, y=340)
self.button_user_information = tk.Button(self.root, text='用户信息', font=('Arial',8),
bg='white', fg='black', width=10, height=2, command=self.__button_user_information__)
self.button_user_information.place(x=580, y=380)
self.button_clear_cached = tk.Button(self.root, text='清除缓存', font=('Arial',8),
bg='white', fg='black', width=10, height=2, command=self.__button_clear_cached__)
self.button_clear_cached.place(x=680, y=380)
self.button_exitsystem = tk.Button(self.root, text='退出系统', font=('Arial',8),
bg='white', fg='black', width=10, height=2, command=self.__button_exitsystem__)
self.button_exitsystem.place(x=580, y=420)
# Set the main app's information
self.Label_info = tk.Label(self.root, font=('Arial',8),bg='white', width=40, height=10)
self.Label_info.place(x=540, y=100)
self.Label_info.config(text='Welcome to MMChat App' +
'\n1.MMChat是一款用于人机交互的软件系统,\n集成了一系列的多模态交互功能'+
'\n2.软件主要包括手势识别控制、语音控制、\n模型交互、环境感知等一系列功能' +
'\n3.用户首先需要注册信息才可进入系统')
def __video_loop__(self):
while self.video_cap.isOpened():
with self.camera_lock:
ret, frame = self.video_cap.read()
self.frame = cv2.flip( cv2.resize(cv2.cvtColor(frame,
cv2.COLOR_BGR2RGB), (512, 512)), 1 )
if ret:
"""Program main execution logic"""
if self.face_authentication_flag:
# Plot the circle aera for embedding
cv2.circle(self.frame, (256,256), 200, (0, 0, 255), 2)
cv2.circle(self.frame, (256,256), 100, (0, 0, 255), 2)
try:
if DeciderCenter(self.mtcnn, frame):
# Facial Recognition
face_emb_path = os.path.join(self.args.face_emb_savepath, self.args.face_emb_jsonname)
password_emb_path = os.path.join(self.args.password_emb_savepath, self.args.password_emb_jsonname)
# Extract facial embedding and save it into json file
_, face_embedding = self.FaceRe.__extract__(frame, all_faces=False)
topmessage = GetFaceName(self.root)
# warning: the face embeding cosists list[array[]]
self.facial_info[topmessage.name] = face_embedding[0].tolist()
self.password_info[topmessage.name] = topmessage.password
if topmessage.name and topmessage.password is not None:
with open(face_emb_path, 'w+',encoding='utf-8') as jf:
self.facial_info = dict(filter(lambda item: item[0] is not None, self.facial_info.items()))
jf.write(json.dumps(self.facial_info, ensure_ascii=False, indent=4))
with open(password_emb_path, 'w+',encoding='utf-8') as jf:
self.password_info = dict(filter(lambda item: item[0] is not None, self.password_info.items()))
jf.write(json.dumps(self.password_info, ensure_ascii=False, indent=4))
# Close Facial Authentication windows
self.face_authentication_flag = not self.face_authentication_flag
self.main_window_show = not self.main_window_show
self.video_cap.release()
self.frame = FaceVisiblity(self.mtcnn, self.frame)
except: pass
self.__video_show__()
else: # No functions activated
self.__video_show__()
else: break
def __video_show__(self):
if self.main_window_show:
img_tk = ImageTk.PhotoImage(Image.fromarray(self.frame))
else: img_tk = ImageTk.PhotoImage(Image.open(self.args.coverimg_path).resize((512,512)))
self.main_label.config(image=img_tk)
self.main_label.image = img_tk
self.after(10)
def __button_authentication__(self):
self.main_window_show = not self.main_window_show
self.face_authentication_flag = not self.face_authentication_flag
if self.main_window_show:
self.video_cap = cv2.VideoCapture(0)
self.threading = threading.Thread(target=self.__video_loop__)
self.threading.daemon = True
self.threading.start()
else:
self.main_window_show = not self.main_window_show
img_tk = ImageTk.PhotoImage(Image.open(self.args.coverimg_path).resize((512,512)))
self.main_label.config(image=img_tk)
self.main_label.image = img_tk
def __button_interaction__(self):
self.button_interaction_flag = not self.button_interaction_flag
login_window = tk.Toplevel(self.root)
login_interface = LoginInterface(login_window)
# 等待子界面关闭
self.root.wait_window(login_window)
with open('./data_cached/detected_user.txt', 'r') as f:
self.name = f.read()
self.introduction_label.config(text=f'MMChat App Introduction\nWelcome {self.name}')
def __button_funcrelated__(self):
self.button_funcrelated_flag = not self.button_funcrelated_flag
message_box = CreateMessageBox(self.root)
if message_box.Is_exit:
self.button_funcrelated_flag = not self.button_funcrelated_flag
def __button_systemfunc__(self):
self.button_systemfunc_flag = not self.button_systemfunc_flag
if self.name is not None and self.button_systemfunc_flag:
system_root = tk.Toplevel(self.root)
system_interface = Gesture_Style_APP(system_root)
self.root.wait_window(system_root)
else:
tmp_root = tk.Toplevel(self.root)
tmp_root.title('Warning')
tmp_root.geometry('300x100')
tmp_label = tk.Label(tmp_root, text='Please login first!'); tmp_label.pack()
tmp_button = tk.Button(tmp_root, text='OK', command=tmp_root.destroy); tmp_button.pack()
def __button_user_information__(self):
"""显示用户信息状态"""
with open('./data_cached/password_emb.json', 'r') as f:
users = json.load(f)
if users:
tmp_root = tk.Toplevel(self.root)
tmp_root.title("Users' Information")
tmp_root.geometry('300x100')
tmp_label = tk.Label(tmp_root,); tmp_label.pack()
users = users.keys()
tmp_label.config(text=f'Users:{users}')
tmp_button = tk.Button(tmp_root, text='OK', command=tmp_root.destroy); tmp_button.pack()
self.root.wait_window(tmp_root)
else:
tmp_root = tk.Toplevel(self.root)
tmp_root.title("Users' Information")
tmp_root.geometry('300x100')
tmp_label = tk.Label(tmp_root, text='Please registrate first!'); tmp_label.pack()
tmp_button = tk.Button(tmp_root, text='OK', command=tmp_root.destroy); tmp_button.pack()
self.root.wait_window(tmp_root)
def __button_clear_cached__(self):
"""清除缓存数据"""
with open('./data_cached/face_emb.json', 'w') as f:
json.dump({}, f)
with open('./data_cached/password_emb.json', 'w') as f:
json.dump({}, f)
# 清除缓存变量
self.facial_info = {}
self.password_info = {}
# 设置提示清除成功messagebox
tmp_root = tk.Toplevel(self.root)
tmp_root.title('Warning')
tmp_root.geometry('300x100')
tmp_label = tk.Label(tmp_root, text='Clear cached data successfully!'); tmp_label.pack()
tmp_button = tk.Button(tmp_root, text='OK', command=tmp_root.destroy); tmp_button.pack()
self.root.wait_window(tmp_root)
def __button_exitsystem__(self):
self.root.quit()
######################## 主函数测试分析 ###########################
if __name__ == '__main__':
args = Tkinter_Config()
root = tk.Tk()
app = MMChatTkinter(root, args)
app.mainloop()