Spaces:
Sleeping
Sleeping
Niharmahesh
commited on
Commit
•
365e773
1
Parent(s):
04eb0d0
Update app.py
Browse files
app.py
CHANGED
@@ -7,9 +7,14 @@ import pandas as pd
|
|
7 |
from numpy.linalg import norm
|
8 |
import matplotlib.pyplot as plt
|
9 |
import os
|
10 |
-
import base64
|
11 |
|
12 |
st.set_page_config(layout="wide")
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
# Function to load the Random Forest model
|
14 |
@st.cache_resource
|
15 |
def load_model():
|
@@ -67,37 +72,49 @@ def process_and_predict(image):
|
|
67 |
|
68 |
# Function to plot hand landmarks
|
69 |
def plot_hand_landmarks(landmarks, title):
|
70 |
-
fig, ax = plt.subplots(figsize=(
|
71 |
-
ax.scatter(landmarks[:, 0], landmarks[:, 1], c='blue', s=
|
72 |
mp_hands = mp.solutions.hands
|
73 |
for connection in mp_hands.HAND_CONNECTIONS:
|
74 |
start_idx = connection[0]
|
75 |
end_idx = connection[1]
|
76 |
ax.plot([landmarks[start_idx, 0], landmarks[end_idx, 0]],
|
77 |
-
[landmarks[start_idx, 1], landmarks[end_idx, 1]], 'r-', linewidth=
|
78 |
ax.invert_yaxis()
|
79 |
-
ax.set_title(title, fontsize=
|
80 |
ax.axis('off')
|
81 |
return fig
|
82 |
|
83 |
-
#
|
84 |
-
|
85 |
-
|
86 |
-
data = f.read()
|
87 |
-
bin_str = base64.b64encode(data).decode()
|
88 |
-
href = f'<a href="data:application/octet-stream;base64,{bin_str}" download="{os.path.basename(bin_file)}">Download {file_label}</a>'
|
89 |
-
return href
|
90 |
|
91 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
st.title("ASL Recognition App")
|
94 |
|
95 |
-
#
|
96 |
-
|
97 |
-
with readme_col1:
|
98 |
-
st.markdown("## How it works")
|
99 |
-
with readme_col2:
|
100 |
-
st.markdown(get_binary_file_downloader_html('readme.md', 'README'), unsafe_allow_html=True)
|
101 |
|
102 |
# Create tabs for different functionalities
|
103 |
tab1, tab2 = st.tabs(["Predict ASL Sign", "View Hand Landmarks"])
|
@@ -110,14 +127,18 @@ with tab1:
|
|
110 |
try:
|
111 |
image = cv2.imdecode(np.frombuffer(uploaded_file.read(), np.uint8), 1)
|
112 |
if image is not None:
|
113 |
-
|
|
|
|
|
|
|
114 |
probabilities, landmarks = process_and_predict(image)
|
115 |
|
116 |
if probabilities is not None and landmarks is not None:
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
|
|
121 |
|
122 |
fig = plot_hand_landmarks(landmarks, "Detected Hand Landmarks")
|
123 |
st.pyplot(fig)
|
@@ -130,18 +151,14 @@ with tab1:
|
|
130 |
|
131 |
with tab2:
|
132 |
st.header("View Hand Landmarks")
|
133 |
-
all_alphabets = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
134 |
-
excluded_alphabets = 'DMNPTUVXZ'
|
135 |
-
available_alphabets = ''.join(set(all_alphabets) - set(excluded_alphabets))
|
136 |
|
137 |
-
selected_alphabets = st.multiselect("Select alphabets to view landmarks:", list(
|
138 |
|
139 |
if selected_alphabets:
|
140 |
-
cols = st.columns(
|
141 |
for idx, alphabet in enumerate(selected_alphabets):
|
142 |
-
with cols[idx %
|
143 |
image_path = os.path.join('asl test set', f'{alphabet.lower()}.jpeg')
|
144 |
-
st.write(f"Attempting to load: {image_path}")
|
145 |
if os.path.exists(image_path):
|
146 |
try:
|
147 |
image = cv2.imread(image_path)
|
@@ -153,8 +170,8 @@ with tab2:
|
|
153 |
else:
|
154 |
st.error(f"No hand detected for {alphabet}")
|
155 |
else:
|
156 |
-
st.error(f"Failed to load image for {alphabet}
|
157 |
except Exception as e:
|
158 |
-
st.error(f"
|
159 |
else:
|
160 |
st.error(f"Image not found for {alphabet}")
|
|
|
7 |
from numpy.linalg import norm
|
8 |
import matplotlib.pyplot as plt
|
9 |
import os
|
|
|
10 |
|
11 |
st.set_page_config(layout="wide")
|
12 |
+
|
13 |
+
# Define the alphabets
|
14 |
+
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():
|
|
|
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
|
|
|
|
|
|
|
|
|
91 |
|
92 |
+
This ASL Recognition App uses image processing and machine learning to recognize American Sign Language (ASL) hand signs.
|
93 |
+
|
94 |
+
1. **Image Upload**: Users can upload an image of an ASL hand sign.
|
95 |
+
2. **Hand Detection**: The app uses MediaPipe to detect hand landmarks in the image.
|
96 |
+
3. **Feature Extraction**: Angles between hand landmarks are calculated and normalized.
|
97 |
+
4. **Prediction**: A Random Forest model predicts the ASL sign based on the extracted features.
|
98 |
+
5. **Visualization**: The app displays the detected hand landmarks and top predictions.
|
99 |
+
|
100 |
+
### Supported Alphabets
|
101 |
+
|
102 |
+
The app currently works for the following ASL alphabets:
|
103 |
+
{', '.join(working_alphabets)}
|
104 |
|
105 |
+
The app does not support or may not work correctly for:
|
106 |
+
{', '.join(excluded_alphabets)}
|
107 |
+
|
108 |
+
Note: The model's performance may vary and is subject to improvement.
|
109 |
+
|
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 |
|
116 |
+
# Display README content
|
117 |
+
st.sidebar.markdown(readme_content)
|
|
|
|
|
|
|
|
|
118 |
|
119 |
# Create tabs for different functionalities
|
120 |
tab1, tab2 = st.tabs(["Predict ASL Sign", "View Hand Landmarks"])
|
|
|
127 |
try:
|
128 |
image = cv2.imdecode(np.frombuffer(uploaded_file.read(), np.uint8), 1)
|
129 |
if image is not None:
|
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)
|
|
|
151 |
|
152 |
with tab2:
|
153 |
st.header("View Hand Landmarks")
|
|
|
|
|
|
|
154 |
|
155 |
+
selected_alphabets = st.multiselect("Select alphabets to view landmarks:", list(working_alphabets))
|
156 |
|
157 |
if selected_alphabets:
|
158 |
+
cols = st.columns(4) # 4 columns for smaller images
|
159 |
for idx, alphabet in enumerate(selected_alphabets):
|
160 |
+
with cols[idx % 4]:
|
161 |
image_path = os.path.join('asl test set', f'{alphabet.lower()}.jpeg')
|
|
|
162 |
if os.path.exists(image_path):
|
163 |
try:
|
164 |
image = cv2.imread(image_path)
|
|
|
170 |
else:
|
171 |
st.error(f"No hand detected for {alphabet}")
|
172 |
else:
|
173 |
+
st.error(f"Failed to load image for {alphabet}")
|
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}")
|