Spaces:
Sleeping
Sleeping
Niharmahesh
commited on
Commit
•
cd5769d
1
Parent(s):
a12833f
Update app.py
Browse files
app.py
CHANGED
@@ -1,11 +1,7 @@
|
|
1 |
import streamlit as st
|
2 |
-
import
|
3 |
-
import
|
4 |
-
|
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,76 +11,6 @@ all_alphabets = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
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 |
-
try:
|
22 |
-
return joblib.load('best_random_forest_model.pkl')
|
23 |
-
except Exception as e:
|
24 |
-
st.error(f"Error loading model: {e}")
|
25 |
-
return None
|
26 |
-
|
27 |
-
# Load the model using the cached function
|
28 |
-
model = load_model()
|
29 |
-
|
30 |
-
# Ensure the model is loaded before proceeding
|
31 |
-
if model is None:
|
32 |
-
st.stop()
|
33 |
-
|
34 |
-
# Function to normalize landmarks
|
35 |
-
def normalize_landmarks(landmarks):
|
36 |
-
center = np.mean(landmarks, axis=0)
|
37 |
-
landmarks_centered = landmarks - center
|
38 |
-
std_dev = np.std(landmarks_centered, axis=0)
|
39 |
-
landmarks_normalized = landmarks_centered / std_dev
|
40 |
-
return np.nan_to_num(landmarks_normalized)
|
41 |
-
|
42 |
-
# Function to calculate angles between landmarks
|
43 |
-
def calculate_angles(landmarks):
|
44 |
-
angles = []
|
45 |
-
for i in range(20):
|
46 |
-
for j in range(i + 1, 21):
|
47 |
-
vector = landmarks[j] - landmarks[i]
|
48 |
-
angle_x = np.arccos(np.clip(vector[0] / norm(vector), -1.0, 1.0))
|
49 |
-
angle_y = np.arccos(np.clip(vector[1] / norm(vector), -1.0, 1.0))
|
50 |
-
angles.extend([angle_x, angle_y])
|
51 |
-
return angles
|
52 |
-
|
53 |
-
# Function to process image and predict alphabet
|
54 |
-
def process_and_predict(image):
|
55 |
-
mp_hands = mp.solutions.hands
|
56 |
-
with mp_hands.Hands(static_image_mode=True, max_num_hands=1, min_detection_confidence=0.5) as hands:
|
57 |
-
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
58 |
-
results = hands.process(image_rgb)
|
59 |
-
|
60 |
-
if results.multi_hand_landmarks:
|
61 |
-
landmarks = np.array([[lm.x, lm.y] for lm in results.multi_hand_landmarks[0].landmark])
|
62 |
-
landmarks_normalized = normalize_landmarks(landmarks)
|
63 |
-
angles = calculate_angles(landmarks_normalized)
|
64 |
-
|
65 |
-
angle_columns = [f'angle_{i}' for i in range(len(angles))]
|
66 |
-
angles_df = pd.DataFrame([angles], columns=angle_columns)
|
67 |
-
|
68 |
-
probabilities = model.predict_proba(angles_df)[0]
|
69 |
-
return probabilities, landmarks
|
70 |
-
|
71 |
-
return None, None
|
72 |
-
|
73 |
-
# Function to plot hand landmarks
|
74 |
-
def plot_hand_landmarks(landmarks, title):
|
75 |
-
fig, ax = plt.subplots(figsize=(5, 5))
|
76 |
-
ax.scatter(landmarks[:, 0], landmarks[:, 1], c='blue', s=20)
|
77 |
-
mp_hands = mp.solutions.hands
|
78 |
-
for connection in mp_hands.HAND_CONNECTIONS:
|
79 |
-
start_idx = connection[0]
|
80 |
-
end_idx = connection[1]
|
81 |
-
ax.plot([landmarks[start_idx, 0], landmarks[end_idx, 0]],
|
82 |
-
[landmarks[start_idx, 1], landmarks[end_idx, 1]], 'r-', linewidth=1)
|
83 |
-
ax.invert_yaxis()
|
84 |
-
ax.set_title(title, fontsize=12)
|
85 |
-
ax.axis('off')
|
86 |
-
return fig
|
87 |
-
|
88 |
# README content
|
89 |
readme_content = f"""
|
90 |
## How it works
|
@@ -110,6 +36,13 @@ Note: The model's performance may vary and is subject to improvement.
|
|
110 |
The "View Hand Landmarks" tab allows users to see hand landmarks for pre-loaded ASL signs.
|
111 |
"""
|
112 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
# Streamlit app
|
114 |
st.title("ASL Recognition App")
|
115 |
|
@@ -130,16 +63,16 @@ with tab1:
|
|
130 |
col1, col2 = st.columns(2)
|
131 |
with col1:
|
132 |
st.image(image, caption="Uploaded Image", use_column_width=True)
|
133 |
-
|
134 |
-
probabilities, landmarks = process_and_predict(image)
|
135 |
-
|
136 |
if probabilities is not None and landmarks is not None:
|
137 |
with col2:
|
138 |
st.subheader("Top 5 Predictions:")
|
139 |
top_indices = np.argsort(probabilities)[::-1][:5]
|
140 |
for i in top_indices:
|
141 |
st.write(f"{model.classes_[i]}: {probabilities[i]:.2f}")
|
142 |
-
|
143 |
fig = plot_hand_landmarks(landmarks, "Detected Hand Landmarks")
|
144 |
st.pyplot(fig)
|
145 |
else:
|
@@ -163,7 +96,7 @@ with tab2:
|
|
163 |
try:
|
164 |
image = cv2.imread(image_path)
|
165 |
if image is not None:
|
166 |
-
probabilities, landmarks = process_and_predict(image)
|
167 |
if landmarks is not None:
|
168 |
fig = plot_hand_landmarks(landmarks, f"Hand Landmarks for {alphabet}")
|
169 |
st.pyplot(fig)
|
@@ -174,4 +107,4 @@ with tab2:
|
|
174 |
except Exception as e:
|
175 |
st.error(f"Error processing image for {alphabet}")
|
176 |
else:
|
177 |
-
st.error(f"Image not found for {alphabet}")
|
|
|
1 |
import streamlit as st
|
2 |
+
from model import load_model, process_and_predict
|
3 |
+
from landmarks import normalize_landmarks, calculate_angles
|
4 |
+
from visualization import plot_hand_landmarks
|
|
|
|
|
|
|
|
|
5 |
import os
|
6 |
|
7 |
st.set_page_config(layout="wide")
|
|
|
11 |
excluded_alphabets = 'DMNPTUVXZ'
|
12 |
working_alphabets = ''.join(set(all_alphabets) - set(excluded_alphabets))
|
13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
# README content
|
15 |
readme_content = f"""
|
16 |
## How it works
|
|
|
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 |
# Streamlit app
|
47 |
st.title("ASL Recognition App")
|
48 |
|
|
|
63 |
col1, col2 = st.columns(2)
|
64 |
with col1:
|
65 |
st.image(image, caption="Uploaded Image", use_column_width=True)
|
66 |
+
|
67 |
+
probabilities, landmarks = process_and_predict(image, model)
|
68 |
+
|
69 |
if probabilities is not None and landmarks is not None:
|
70 |
with col2:
|
71 |
st.subheader("Top 5 Predictions:")
|
72 |
top_indices = np.argsort(probabilities)[::-1][:5]
|
73 |
for i in top_indices:
|
74 |
st.write(f"{model.classes_[i]}: {probabilities[i]:.2f}")
|
75 |
+
|
76 |
fig = plot_hand_landmarks(landmarks, "Detected Hand Landmarks")
|
77 |
st.pyplot(fig)
|
78 |
else:
|
|
|
96 |
try:
|
97 |
image = cv2.imread(image_path)
|
98 |
if image is not None:
|
99 |
+
probabilities, landmarks = process_and_predict(image, model)
|
100 |
if landmarks is not None:
|
101 |
fig = plot_hand_landmarks(landmarks, f"Hand Landmarks for {alphabet}")
|
102 |
st.pyplot(fig)
|
|
|
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}")
|