-
Notifications
You must be signed in to change notification settings - Fork 2
/
server.py
373 lines (345 loc) · 15.9 KB
/
server.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
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
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
from flask_cors import CORS # add this
import platform
from flask_socketio import SocketIO, emit, join_room
from flask import Flask, request, render_template, jsonify, session, redirect, url_for
import numpy as np
import time
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense
import tensorflow as tf
import pickle
import pyrebase
from functools import wraps
from collections import Counter
tf.config.set_visible_devices([], 'GPU')
app = Flask(__name__, static_folder='static')
config = {
"apiKey": "",
"authDomain": "",
"projectId": "",
"storageBucket": "",
"messagingSenderId": "",
"appId": "",
"measurementId": "",
'databaseURL':''
}
firebase = pyrebase.initialize_app(config=config)
auth = firebase.auth()
db = firebase.database()
app.config['SECRET_KEY'] = "SECRET_KEY"
CORS(app)
socketio = SocketIO(app, cors_allowed_origins="*")
users_in_room = {}
rooms_sid = {}
names_sid = {}
folder_counter = 0
request_counter = 0
is_resting = False # Trạng thái nghỉ
start_time = None
sequence = {}
sentence = []
sentence_char = []
old_char = None
right_hand_landmarks_X_Y = []
labels_dict = {0: 'た', 1: 'な', 2: 'か',3:'Enter',4:'Delete'}
threshold = 0.9
#Load model for detect character
model_dict = pickle.load(open('./modelv2.p', 'rb'))
model_char = model_dict['model']
# Actions that we try to detect
actions = np.array(['はじめまして', 'こんにちは', '私の名前は', 'ありがとうございます', 'と申します', 'よろしくおねがいします。'])
model = Sequential()
model.add(LSTM(64, return_sequences=True, activation='tanh', input_shape=(20,225)))
model.add(LSTM(128, return_sequences=True, activation='tanh'))
model.add(LSTM(64, return_sequences=False, activation='tanh'))
model.add(Dense(64, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Dense(32, activation='relu'))
model.add(Dense(actions.shape[0], activation='softmax'))
model.load_weights('webappmodelv3.h5')
json_counter = 0
def most_frequent_element(arr):
# Đếm số lần xuất hiện của mỗi phần tử trong mảng
count = Counter(arr)
# Tìm phần tử xuất hiện nhiều nhất
most_common_element = count.most_common(1)
# Kiểm tra xem phần tử đó có xuất hiện tối thiểu 6 lần hay không
if most_common_element and most_common_element[0][0] == 'Enter' and most_common_element[0][1] >= 8:
return most_common_element[0][0]
elif most_common_element and most_common_element[0][1] >= 6 and most_common_element[0][0] != 'Enter':
return most_common_element[0][0]
# Nếu không thoả mãn điều kiện, làm trống mảng và trả về None
arr.clear()
return None
def login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if 'localId' not in session:
return redirect(url_for('index'))
return f(*args, **kwargs)
return decorated_function
def checkHandLandmarksCoordinates(x_array,y_array):
maxX = max(x_array) * 426 #video width
maxY = max(y_array) * 320 #video height
# print('maxX: ',maxX,' maxY: ',maxY)
return maxX <= 160 and maxY <= 160 and maxX > 0 and maxY > 0
@app.route('/', methods=['POST','GET'])
def index():
if request.method == 'POST':
email = request.form.get('email')
password = request.form.get('password')
try:
user = auth.sign_in_with_email_and_password(email,password)
print(user['localId'])
session['localId'] = user['localId']
session['email'] = email
return redirect('/home')
except Exception as e:
print(e)
return 'Failed to login'
return render_template('login.html')
@app.route('/signup', methods=['POST', 'GET'])
def signup():
if request.method == 'POST':
name = request.form.get('name')
email = request.form.get('email')
password = request.form.get('password')
try:
user = auth.create_user_with_email_and_password(email, password)
user_id = user['localId']
# Lưu thông tin người dùng vào Firebase Database
data = {'name': name, 'email': email}
db.child('users').child(user_id).update(data)
return redirect('/')
except Exception as e:
print(e)
return 'Failed to sign up'
return render_template('signup.html')
@app.route('/forgot_password', methods=['POST', 'GET'])
def forgot_password():
if request.method == 'POST':
email = request.form.get('email')
try:
auth.send_password_reset_email(email)
return 'Password reset email sent'
except:
return 'Failed to send password reset email'
return render_template('forgot_password.html') # You'll need to create this template
@app.route('/logout')
def logout():
session.clear()
return redirect('/')
@app.route('/home')
@login_required
def home():
if 'localId' in session:
print(session)
print(session['localId'])
return render_template('home.html')
else:
return 'Please log in'
@app.route('/joinlink',methods=["GET"])
@login_required
def joinlink():
if 'localId' in session:
print(session)
print(session['localId'])
return render_template('joinlink.html')
else:
return 'Please log in'
@app.route("/join", methods=["GET"])
@login_required
def join():
if 'localId' in session:
user = db.child('users').child(session['localId']).get()
display_name = user.val()['name']
mute_audio = request.args.get('mute_audio') # 1 or 0
mute_video = request.args.get('mute_video') # 1 or 0
room_id = request.args.get('room_id')
session[room_id] = {"name": display_name,
"mute_audio": mute_audio, "mute_video": mute_video}
return render_template("join.html", room_id=room_id, display_name=session[room_id]["name"], mute_audio=session[room_id]["mute_audio"], mute_video=session[room_id]["mute_video"])
@app.route('/combined_landmark_endpoint', methods=['POST'])
def handle_landmark_data():
global folder_counter, request_counter, is_resting, start_time, sequence, sentence, sentence_char
global json_counter, right_hand_landmarks_X_Y, labels_dict, model_char, old_char
if request.method != 'POST':
return 'This endpoint accepts POST requests containing combined hand and pose landmark data.'
data = request.get_json()
handednesses = data.get('handLandmarks').get('handednesses')
left_hand_index = None
right_hand_index = None
for index, handedness in enumerate(handednesses):
if handedness[0]['categoryName'] == 'Right':
right_hand_index = index
elif handedness[0]['categoryName'] == 'Left':
left_hand_index = index
x_array = np.array([landmark['x'] for landmark in data.get('handLandmarks').get('landmarks')[right_hand_index]]).flatten() if right_hand_index is not None else np.zeros(21)
x_list = x_array.tolist()
y_array = np.array([landmark['y'] for landmark in data.get('handLandmarks').get('landmarks')[right_hand_index]]).flatten() if right_hand_index is not None else np.zeros(21)
y_list = y_array.tolist()
sid = data['sid']
room_id = rooms_sid[sid]
sender = names_sid[sid]
# print('X_ARRAY: ',x_array)
try:
if checkHandLandmarksCoordinates(x_list,y_list):
sequence[sender] = []
json_counter = 0
# Gửi sự kiện đến tất cả các clients trong phòng chung
socketio.emit('sentence', {'sentence': sentence, 'counter': "文字を認識中"}, room=room_id)
try:
for landmark in data.get('handLandmarks').get('landmarks')[right_hand_index]:
x = landmark['x']
y = landmark['y']
right_hand_landmarks_X_Y.append(x - min(x_list))
right_hand_landmarks_X_Y.append(y - min(y_list))
# Lấy xác suất dự đoán cho từng lớp
proba_predictions = model_char.predict_proba([np.asarray(right_hand_landmarks_X_Y)])
# print(proba_predictions)
right_hand_landmarks_X_Y = []
# Lấy xác suất dự đoán lớp có xác suất cao nhất
max_proba = np.max(proba_predictions)
# Nếu xác suất cao hơn ngưỡng, gán nhãn; nếu không, bạn có thể gán giá trị None hoặc chuỗi trống
if max_proba > 0.3:
predicted_label_index = np.argmax(proba_predictions)
predicted_character = labels_dict[predicted_label_index]
sentence_char.append(predicted_character)
print(sentence_char)
if len(sentence_char) == 8:
print("sentence_char10:",sentence_char)
result = most_frequent_element(sentence_char)
print("pred char :",result)
if result is None or result == old_char:
sentence_char = []
else:
# Gửi sự kiện đến tất cả các clients trong phòng chung
socketio.emit('message', {'message': result,'sender': sender, 'type': 'AI'}, room=room_id)
sentence_char = []
old_char = result
else:
predicted_character = 'NULL'
print('NULL')
except Exception as e:
print(e)
else:
# Convert left_hand_landmarks to a NumPy array
left_hand_landmarks_np = np.array([(landmark['x'], landmark['y'], landmark['z']) for landmark in data.get('handLandmarks').get('landmarks')[left_hand_index]]).flatten() if left_hand_index is not None else np.zeros(21*3)
# Convert right_hand_landmarks to a NumPy array
right_hand_landmarks_np = np.array([(landmark['x'], landmark['y'], landmark['z']) for landmark in data.get('handLandmarks').get('landmarks')[right_hand_index]]).flatten() if right_hand_index is not None else np.zeros(21*3)
# Concatenate left and right hand landmark arrays
hand_landmarks = np.concatenate([left_hand_landmarks_np, right_hand_landmarks_np])
# Process pose landmarks
pose_landmarks = data.get('poseLandmarks')
# Convert pose_landmarks to a NumPy array
pose_landmarks_np = np.array([(landmark['x'], landmark['y'], landmark['z']) for landmark in pose_landmarks[0]]).flatten() if pose_landmarks[0] else np.zeros(33*3)
if (left_hand_landmarks_np[0] != 0) or (right_hand_landmarks_np[0] != 0):
# Tăng biến đếm và kiểm tra nếu đạt đến 20
json_counter += 1
if json_counter > 20:
json_counter = 1
socketio.emit('sentence', {'counter': json_counter}, room=room_id)
# Concatenate the global variables
detect_landmarks = np.concatenate([pose_landmarks_np, hand_landmarks])
# print(detect_landmarks)
# Lưu array vào file
sequence[sender].append(detect_landmarks)
sequence[sender] = sequence[sender][-20:]
if len(sequence[sender]) == 20:
res = model.predict(np.expand_dims(sequence[sender], axis=0))[0]
sequence[sender] = []
if res[np.argmax(res)] > threshold:
print(actions[np.argmax(res)])
if len(sentence) > 0:
if actions[np.argmax(res)] != sentence[-1]:
sentence.append(actions[np.argmax(res)])
socketio.emit('message', {'message': sentence[-1],'sender': sender, 'type': 'AI'}, room=room_id)
else:
sentence.append(actions[np.argmax(res)])
socketio.emit('message', {'message': sentence[-1],'sender': sender, 'type': 'AI'}, room=room_id)
if len(sentence) > 5:
sentence = sentence[-5:]
print("LIST: ",sentence)
# Gửi sự kiện đến tất cả các clients trong phòng chung
socketio.emit('sentence', {'sentence': sentence}, room=room_id)
# Gửi sự kiện đến tất cả các clients trong phòng chung
elif (left_hand_landmarks_np[0] == 0) and (right_hand_landmarks_np[0] == 0):
# print('elif true')
sequence[sender] = []
json_counter = 0
# Gửi sự kiện đến tất cả các clients trong phòng chung
socketio.emit('sentence', {'sentence': sentence, 'counter': "手話の認識をお待ちしています。"}, room=room_id)
except:
print('No_poselandmark')
return jsonify({"status": "success"}), 200
@socketio.on("connect")
def on_connect():
sid = request.sid
print("New socket connected ", sid)
#nhận địa chỉ phòng room_id từ client rồi trả về sid tương ứng về client
#thông qua sự kiện user-connect
@socketio.on("join-room")
def on_join_room(data):
sid = request.sid
room_id = data["room_id"]
display_name = session[room_id]["name"]
# register sid to the room
join_room(room_id)
rooms_sid[sid] = room_id
names_sid[sid] = display_name
# broadcast to others in the room
print("[{}] New member joined: {}<{}>".format(room_id, display_name, sid))
emit("user-connect", {"sid": sid, "name": display_name},
broadcast=True, include_self=False, room=room_id)
# add to user list maintained on server
if room_id not in users_in_room:
users_in_room[room_id] = [sid]
emit("user-list", {"my_id": sid}) # send own id only
else:
usrlist = {u_id: names_sid[u_id] for u_id in users_in_room[room_id]}
# send list of existing users to the new member
emit("user-list", {"list": usrlist, "my_id": sid})
# add new member to user list maintained on server
users_in_room[room_id].append(sid)
print("\nusers: ", users_in_room, "\n")
# Khi người dùng kết nối vào một phòng cụ thể
@socketio.on('join-roomchat')
def handle_join_room(data):
room = data['room_id']
display_name = session[room]["name"]
join_room(room)
emit('message', {'sender': 'System', 'message': f'{display_name} has entered the room.', 'type':'OS'}, room=room)
# Khi người dùng gửi tin nhắnS
@socketio.on('send-message')
def handle_send_message(data):
room = data['room_id']
sender = data['sender']
message = data['message']
print(f'{sender} sent message: {message}')
emit('message', {'sender': sender, 'message': message, 'type':'human'}, room=room)
@socketio.on("disconnect")
def on_disconnect():
sid = request.sid
room_id = rooms_sid[sid]
display_name = names_sid[sid]
print("[{}] Member left: {}<{}>".format(room_id, display_name, sid))
emit("user-disconnect", {"sid": sid},
broadcast=True, include_self=False, room=room_id)
users_in_room[room_id].remove(sid)
if len(users_in_room[room_id]) == 0:
users_in_room.pop(room_id)
rooms_sid.pop(sid)
names_sid.pop(sid)
print("\nusers: ", users_in_room, "\n")
@socketio.on("data")
def on_data(data):
sender_sid = data['sender_id']
target_sid = data['target_id']
if sender_sid != request.sid:
print("[Not supposed to happen!] request.sid and sender_id don't match!!!")
if data["type"] != "new-ice-candidate":
print('{} message from {} to {}'.format(
data["type"], sender_sid, target_sid))
socketio.emit('data', data, room=target_sid)
# if __name__ == "__main__":
# socketio.run(app, debug=True,port=5000)