Spaces:
Sleeping
Sleeping
Niharmahesh
commited on
Commit
•
d1c5054
1
Parent(s):
ec7574f
Update app.py
Browse files
app.py
CHANGED
@@ -1,7 +1,11 @@
|
|
1 |
import streamlit as st
|
2 |
-
|
3 |
-
|
4 |
-
|
|
|
|
|
|
|
|
|
5 |
import os
|
6 |
|
7 |
st.set_page_config(layout="wide")
|
@@ -11,100 +15,83 @@ all_alphabets = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
11 |
excluded_alphabets = 'DMNPTUVXZ'
|
12 |
working_alphabets = ''.join(set(all_alphabets) - set(excluded_alphabets))
|
13 |
|
14 |
-
#
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
### Supported Alphabets
|
27 |
-
|
28 |
-
The app currently works for the following ASL alphabets:
|
29 |
-
{', '.join(working_alphabets)}
|
30 |
-
|
31 |
-
The app does not support or may not work correctly for:
|
32 |
-
{', '.join(excluded_alphabets)}
|
33 |
-
|
34 |
-
Note: The model's performance may vary and is subject to improvement.
|
35 |
-
|
36 |
-
The "View Hand Landmarks" tab allows users to see hand landmarks for pre-loaded ASL signs.
|
37 |
-
"""
|
38 |
-
|
39 |
-
# Load the model
|
40 |
model = load_model()
|
41 |
|
42 |
# Ensure the model is loaded before proceeding
|
43 |
if model is None:
|
44 |
st.stop()
|
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 |
-
selected_alphabets = st.multiselect("Select alphabets to view landmarks:", list(working_alphabets))
|
89 |
-
|
90 |
-
if selected_alphabets:
|
91 |
-
cols = st.columns(4) # 4 columns for smaller images
|
92 |
-
for idx, alphabet in enumerate(selected_alphabets):
|
93 |
-
with cols[idx % 4]:
|
94 |
-
image_path = os.path.join('asl test set', f'{alphabet.lower()}.jpeg')
|
95 |
-
if os.path.exists(image_path):
|
96 |
-
try:
|
97 |
-
image = cv2.imread(image_path)
|
98 |
-
if image is not None:
|
99 |
-
probabilities, landmarks = process_and_predict(image)
|
100 |
-
if landmarks is not None:
|
101 |
-
fig = plot_hand_landmarks(landmarks, f"Hand Landmarks for {alphabet}")
|
102 |
-
st.pyplot(fig)
|
103 |
-
else:
|
104 |
-
st.error(f"No hand detected for {alphabet}")
|
105 |
-
else:
|
106 |
-
st.error(f"Failed to load image for {alphabet}")
|
107 |
-
except Exception as e:
|
108 |
-
st.error(f"Error processing image for {alphabet}")
|
109 |
-
else:
|
110 |
-
st.error(f"Image not found for {alphabet}")
|
|
|
1 |
import streamlit as st
|
2 |
+
import cv2
|
3 |
+
import numpy as np
|
4 |
+
import mediapipe as mp
|
5 |
+
import joblib
|
6 |
+
import pandas as pd
|
7 |
+
from numpy.linalg import norm
|
8 |
+
import matplotlib.pyplot as plt
|
9 |
import os
|
10 |
|
11 |
st.set_page_config(layout="wide")
|
|
|
15 |
excluded_alphabets = 'DMNPTUVXZ'
|
16 |
working_alphabets = ''.join(set(all_alphabets) - set(excluded_alphabets))
|
17 |
|
18 |
+
# Function to load the Random Forest model
|
19 |
+
@st.cache_resource
|
20 |
+
def load_model():
|
21 |
+
"""Load the Random Forest model from a file."""
|
22 |
+
try:
|
23 |
+
return joblib.load('best_random_forest_model.pkl')
|
24 |
+
except Exception as e:
|
25 |
+
st.error(f"Error loading model: {e}")
|
26 |
+
return None
|
27 |
+
|
28 |
+
# Load the model using the cached function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
model = load_model()
|
30 |
|
31 |
# Ensure the model is loaded before proceeding
|
32 |
if model is None:
|
33 |
st.stop()
|
34 |
|
35 |
+
# Function to normalize landmarks
|
36 |
+
def normalize_landmarks(landmarks):
|
37 |
+
"""Normalize the hand landmarks by centering and scaling.
|
38 |
+
|
39 |
+
Args:
|
40 |
+
landmarks (np.ndarray): Array of hand landmarks.
|
41 |
+
|
42 |
+
Returns:
|
43 |
+
np.ndarray: Normalized landmarks.
|
44 |
+
"""
|
45 |
+
center = np.mean(landmarks, axis=0)
|
46 |
+
landmarks_centered = landmarks - center
|
47 |
+
std_dev = np.std(landmarks_centered, axis=0)
|
48 |
+
landmarks_normalized = landmarks_centered / std_dev
|
49 |
+
return np.nan_to_num(landmarks_normalized)
|
50 |
+
|
51 |
+
# Function to calculate angles between landmarks
|
52 |
+
def calculate_angles(landmarks):
|
53 |
+
"""Calculate angles between hand landmarks.
|
54 |
+
|
55 |
+
Args:
|
56 |
+
landmarks (np.ndarray): Array of normalized hand landmarks.
|
57 |
+
|
58 |
+
Returns:
|
59 |
+
list: List of calculated angles.
|
60 |
+
"""
|
61 |
+
angles = []
|
62 |
+
for i in range(20):
|
63 |
+
for j in range(i + 1, 21):
|
64 |
+
vector = landmarks[j] - landmarks[i]
|
65 |
+
angle_x = np.arccos(np.clip(vector[0] / norm(vector), -1.0, 1.0))
|
66 |
+
angle_y = np.arccos(np.clip(vector[1] / norm(vector), -1.0, 1.0))
|
67 |
+
angles.extend([angle_x, angle_y])
|
68 |
+
return angles
|
69 |
+
|
70 |
+
# Function to process image and predict alphabet
|
71 |
+
def process_and_predict(image):
|
72 |
+
"""Process the input image and predict the ASL sign.
|
73 |
+
|
74 |
+
Args:
|
75 |
+
image (np.ndarray): The input image containing a hand sign.
|
76 |
+
|
77 |
+
Returns:
|
78 |
+
tuple: (probabilities, landmarks) where probabilities are
|
79 |
+
the predicted probabilities for each class and landmarks
|
80 |
+
are the detected hand landmarks.
|
81 |
+
"""
|
82 |
+
mp_hands = mp.solutions.hands
|
83 |
+
with mp_hands.Hands(static_image_mode=True, max_num_hands=1, min_detection_confidence=0.5) as hands:
|
84 |
+
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
85 |
+
results = hands.process(image_rgb)
|
86 |
+
|
87 |
+
if results.multi_hand_landmarks:
|
88 |
+
landmarks = np.array([[lm.x, lm.y] for lm in results.multi_hand_landmarks[0].landmark])
|
89 |
+
landmarks_normalized = normalize_landmarks(landmarks)
|
90 |
+
angles = calculate_angles(landmarks_normalized)
|
91 |
+
|
92 |
+
angle_columns = [f'angle_{i}' for i in range(len(angles))]
|
93 |
+
angles_df = pd.DataFrame([angles], columns=angle_columns)
|
94 |
+
|
95 |
+
probabilities = model.predict_proba(angles_df)[0]
|
96 |
+
return probabilities, landmarks
|
97 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|