Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
SpeakEzy_Backend
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Shehan Liyanage
SpeakEzy_Backend
Commits
ee27b181
Commit
ee27b181
authored
May 18, 2024
by
Shehan Liyanage
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
all changes done
parent
3b6c555b
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
108 additions
and
54 deletions
+108
-54
.DS_Store
.DS_Store
+0
-0
sign_language_backend/app.py
sign_language_backend/app.py
+100
-54
sign_language_backend/requirements.txt
sign_language_backend/requirements.txt
+8
-0
No files found.
.DS_Store
View file @
ee27b181
No preview for this file type
sign_language_backend/app.py
View file @
ee27b181
from
flask
import
Flask
,
request
,
jsonify
from
flask
import
Flask
,
request
import
base64
from
flask_socketio
import
SocketIO
,
emit
,
send
import
cv2
import
cv2
import
io
import
numpy
as
np
import
numpy
as
np
import
mediapipe
as
mp
import
base64
import
tensorflow
as
tf
import
tensorflow
as
tf
import
logging
from
tensorflow.keras.models
import
load_model
import
mediapipe
as
mp
app
=
Flask
(
__name__
)
# Load the model
model
=
tf
.
keras
.
models
.
load_model
(
'./finalModel.h5'
)
mp_holistic
=
mp
.
solutions
.
holistic
mp_holistic
=
mp
.
solutions
.
holistic
holistic
=
mp_holistic
.
Holistic
(
min_detection_confidence
=
0.5
,
min_tracking_confidence
=
0.5
)
mp_drawing
=
mp
.
solutions
.
drawing_utils
actions
=
([
"haloo"
,
"dannwa"
,
"mama"
,
"obata"
,
"puluwan"
,
"suba"
,
"udaasanak"
])
# Load the saved model
model
=
load_model
(
r'./finalModel.h5'
)
sequence
=
[]
sequence
=
[]
sentence
=
[]
sentence
=
[]
predictions
=
[]
predictions
=
[]
threshold
=
0.7
threshold
=
0.7
actions
=
[
"haloo"
,
"dannwa"
,
"mama"
,
"obata"
,
"puluwan"
,
"suba"
,
"udaasanak"
]
count
=
31
def
mediapipe_detection
(
image
,
model
):
def
mediapipe_detection
(
image
,
model
):
image
=
cv2
.
cvtColor
(
image
,
cv2
.
COLOR_BGR2RGB
)
image
=
cv2
.
cvtColor
(
image
,
cv2
.
COLOR_BGR2RGB
)
# COLOR CONVERSION BGR 2 RGB
image
.
flags
.
writeable
=
False
image
.
flags
.
writeable
=
False
# Image is no longer writeable
results
=
model
.
process
(
image
)
results
=
model
.
process
(
image
)
# Make prediction
image
.
flags
.
writeable
=
True
image
.
flags
.
writeable
=
True
# Image is now writeable
image
=
cv2
.
cvtColor
(
image
,
cv2
.
COLOR_RGB2BGR
)
image
=
cv2
.
cvtColor
(
image
,
cv2
.
COLOR_RGB2BGR
)
# COLOR COVERSION RGB 2 BGR
return
image
,
results
return
image
,
results
def
draw_landmarks
(
image
,
results
):
# Draw face connections
mp_drawing
.
draw_landmarks
(
image
,
results
.
face_landmarks
,
mp_holistic
.
FACEMESH_TESSELATION
,
mp_drawing
.
DrawingSpec
(
color
=
(
70
,
110
,
10
),
thickness
=
1
,
circle_radius
=
1
),
mp_drawing
.
DrawingSpec
(
color
=
(
70
,
256
,
121
),
thickness
=
1
,
circle_radius
=
1
))
# Draw pose connections
mp_drawing
.
draw_landmarks
(
image
,
results
.
pose_landmarks
,
mp_holistic
.
POSE_CONNECTIONS
,
mp_drawing
.
DrawingSpec
(
color
=
(
70
,
22
,
10
),
thickness
=
2
,
circle_radius
=
4
),
mp_drawing
.
DrawingSpec
(
color
=
(
70
,
44
,
121
),
thickness
=
2
,
circle_radius
=
2
))
# Draw left hand connections
mp_drawing
.
draw_landmarks
(
image
,
results
.
left_hand_landmarks
,
mp_holistic
.
HAND_CONNECTIONS
,
mp_drawing
.
DrawingSpec
(
color
=
(
121
,
22
,
76
),
thickness
=
2
,
circle_radius
=
4
),
mp_drawing
.
DrawingSpec
(
color
=
(
121
,
44
,
250
),
thickness
=
2
,
circle_radius
=
2
))
# Draw right hand connections
mp_drawing
.
draw_landmarks
(
image
,
results
.
right_hand_landmarks
,
mp_holistic
.
HAND_CONNECTIONS
,
mp_drawing
.
DrawingSpec
(
color
=
(
245
,
117
,
66
),
thickness
=
2
,
circle_radius
=
4
),
mp_drawing
.
DrawingSpec
(
color
=
(
245
,
66
,
230
),
thickness
=
2
,
circle_radius
=
2
))
def
extract_keypoints
(
results
):
def
extract_keypoints
(
results
):
pose
=
np
.
array
([[
res
.
x
,
res
.
y
,
res
.
z
,
res
.
visibility
]
for
res
in
results
.
pose_landmarks
.
landmark
])
.
flatten
()
if
results
.
pose_landmarks
else
np
.
zeros
(
33
*
4
)
pose
=
np
.
array
([[
res
.
x
,
res
.
y
,
res
.
z
,
res
.
visibility
]
for
res
in
results
.
pose_landmarks
.
landmark
])
.
flatten
()
if
results
.
pose_landmarks
else
np
.
zeros
(
33
*
4
)
face
=
np
.
array
([[
res
.
x
,
res
.
y
,
res
.
z
]
for
res
in
results
.
face_landmarks
.
landmark
])
.
flatten
()
if
results
.
face_landmarks
else
np
.
zeros
(
468
*
3
)
face
=
np
.
array
([[
res
.
x
,
res
.
y
,
res
.
z
]
for
res
in
results
.
face_landmarks
.
landmark
])
.
flatten
()
if
results
.
face_landmarks
else
np
.
zeros
(
468
*
3
)
...
@@ -35,54 +54,81 @@ def extract_keypoints(results):
...
@@ -35,54 +54,81 @@ def extract_keypoints(results):
rh
=
np
.
array
([[
res
.
x
,
res
.
y
,
res
.
z
]
for
res
in
results
.
right_hand_landmarks
.
landmark
])
.
flatten
()
if
results
.
right_hand_landmarks
else
np
.
zeros
(
21
*
3
)
rh
=
np
.
array
([[
res
.
x
,
res
.
y
,
res
.
z
]
for
res
in
results
.
right_hand_landmarks
.
landmark
])
.
flatten
()
if
results
.
right_hand_landmarks
else
np
.
zeros
(
21
*
3
)
return
np
.
concatenate
([
pose
,
face
,
lh
,
rh
])
return
np
.
concatenate
([
pose
,
face
,
lh
,
rh
])
@
app
.
route
(
'/endpoint'
,
methods
=
[
'POST'
])
def
pad_sequence
(
sequence
,
target_length
):
def
process_frame
():
if
len
(
sequence
)
<
target_length
:
try
:
padding
=
np
.
zeros
((
target_length
-
len
(
sequence
),
sequence
.
shape
[
1
]))
data
=
request
.
json
sequence
=
np
.
vstack
((
padding
,
sequence
))
frame_data
=
data
[
'frame'
]
return
sequence
# Fix incorrect padding for base64 string
def
PredictSign
(
frame
):
frame_data
+=
"="
*
((
4
-
len
(
frame_data
)
%
4
)
%
4
)
with
mp_holistic
.
Holistic
(
min_detection_confidence
=
0.5
,
min_tracking_confidence
=
0.5
)
as
holistic
:
global
sequence
# Decode the base64 string to an image
global
sentence
decoded_data
=
base64
.
b64decode
(
frame_data
)
global
predictions
np_data
=
np
.
frombuffer
(
decoded_data
,
dtype
=
np
.
uint8
)
global
threshold
frame
=
cv2
.
imdecode
(
np_data
,
cv2
.
IMREAD_COLOR
)
global
count
if
frame
is
None
:
raise
ValueError
(
"Failed to decode image"
)
# Process the frame with Mediapipe and your model
image
,
results
=
mediapipe_detection
(
frame
,
holistic
)
image
,
results
=
mediapipe_detection
(
frame
,
holistic
)
draw_landmarks
(
image
,
results
)
keypoints
=
extract_keypoints
(
results
)
keypoints
=
extract_keypoints
(
results
)
sequence
.
append
(
keypoints
)
sequence
.
append
(
keypoints
)
sequence
=
sequence
[
-
50
:]
sequence
=
sequence
[
-
50
:]
# Keep the last 50 keypoints
if
len
(
sequence
)
==
50
:
if
len
(
sequence
)
==
50
:
res
=
model
.
predict
(
np
.
expand_dims
(
sequence
,
axis
=
0
))[
0
]
padded_sequence
=
pad_sequence
(
np
.
array
(
sequence
),
50
)
res
=
model
.
predict
(
np
.
expand_dims
(
padded_sequence
,
axis
=
0
))[
0
]
predictions
.
append
(
np
.
argmax
(
res
))
predictions
.
append
(
np
.
argmax
(
res
))
if
np
.
unique
(
predictions
[
-
3
:])[
0
]
==
np
.
argmax
(
res
):
# Implement your prediction logic
if
np
.
unique
(
predictions
[
-
25
:])[
0
]
==
np
.
argmax
(
res
):
if
res
[
np
.
argmax
(
res
)]
>
threshold
:
if
res
[
np
.
argmax
(
res
)]
>
threshold
:
if
len
(
sentence
)
>
0
:
if
len
(
sentence
)
>
0
:
if
actions
[
np
.
argmax
(
res
)]
!=
sentence
[
-
1
]:
if
actions
[
np
.
argmax
(
res
)]
!=
sentence
[
-
1
]:
sentence
.
append
(
actions
[
np
.
argmax
(
res
)])
sentence
.
append
(
actions
[
np
.
argmax
(
res
)])
return
sentence
[
-
1
]
else
:
else
:
sentence
.
append
(
actions
[
np
.
argmax
(
res
)])
sentence
.
append
(
actions
[
np
.
argmax
(
res
)])
return
sentence
[
-
1
]
if
len
(
sentence
)
>
5
:
else
:
sentence
=
sentence
[
-
5
:]
pass
else
:
# Print predictions and sentence to the console
count
-=
1
print
(
f
"Predicted: {actions[np.argmax(res)]}"
)
print
(
f
"Sentence: {sentence}"
)
app
=
Flask
(
__name__
)
app
.
config
[
'SECRET_KEY'
]
=
'mysecretkey'
return
jsonify
({
'message'
:
'Frame processed'
,
'sentence'
:
sentence
}),
200
socketio
=
SocketIO
(
app
,
cors_allowed_origins
=
'*'
)
except
Exception
as
e
:
@
app
.
route
(
'/'
)
logging
.
exception
(
"Exception in /endpoint"
)
def
index
():
return
jsonify
({
'message'
:
'Error processing frame'
,
'error'
:
str
(
e
)}),
500
return
'Running'
@
socketio
.
on
(
'connect'
)
def
on_connect
():
emit
(
'me'
,
request
.
sid
)
@
socketio
.
on
(
'disconnect'
)
def
on_disconnect
():
send
(
'callEnded'
,
broadcast
=
True
)
@
socketio
.
on
(
'predictionVideo'
)
def
on_prediction_video
(
data
):
global
actions
img_bytes
=
base64
.
b64decode
(
data
.
split
(
','
)[
1
])
np_arr
=
np
.
frombuffer
(
img_bytes
,
np
.
uint8
)
img
=
cv2
.
imdecode
(
np_arr
,
cv2
.
IMREAD_COLOR
)
ans
=
PredictSign
(
img
)
print
(
ans
)
emit
(
'predictionVideo'
,
ans
)
@
socketio
.
on
(
'callUser'
)
def
on_call_user
(
data
):
from_user
=
data
[
'from'
]
userToCall
=
data
[
'userToCall'
]
caller_name
=
data
[
'name'
]
signal
=
data
[
'signalData'
]
emit
(
'callUser'
,
{
'from'
:
from_user
,
'name'
:
caller_name
,
'signal'
:
signal
},
room
=
userToCall
)
@
socketio
.
on
(
'answerCall'
)
def
on_answer_call
(
data
):
emit
(
'callAccepted'
,
data
[
'signal'
],
room
=
data
[
'to'
])
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
app
.
run
(
debug
=
True
,
port
=
8
000
)
socketio
.
run
(
app
,
debug
=
True
,
port
=
5
000
)
sign_language_backend/requirements.txt
0 → 100644
View file @
ee27b181
Flask==3.0.0
flask-socketio
python-socketio==5.10.0
opencv-python==4.9.0.80
mediapipe==0.10.3
scikit-learn==1.3.1
matplotlib==3.8.3
tensorflow==2.13.0
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment