Spaces:
Sleeping
Sleeping
Niharmahesh
commited on
Update app.py
Browse files
app.py
CHANGED
@@ -5,6 +5,8 @@ import mediapipe as mp
|
|
5 |
import joblib
|
6 |
import pandas as pd
|
7 |
from numpy.linalg import norm
|
|
|
|
|
8 |
|
9 |
# Function to load the Random Forest model
|
10 |
@st.cache_resource
|
@@ -33,18 +35,11 @@ mp_drawing = mp.solutions.drawing_utils
|
|
33 |
|
34 |
# Function to normalize landmarks
|
35 |
def normalize_landmarks(landmarks):
|
36 |
-
# Center the landmarks
|
37 |
center = np.mean(landmarks, axis=0)
|
38 |
landmarks_centered = landmarks - center
|
39 |
-
|
40 |
-
# Scale the landmarks to unit variance
|
41 |
std_dev = np.std(landmarks_centered, axis=0)
|
42 |
landmarks_normalized = landmarks_centered / std_dev
|
43 |
-
|
44 |
-
# Replace NaN values with 0 (in case of division by zero)
|
45 |
-
landmarks_normalized = np.nan_to_num(landmarks_normalized)
|
46 |
-
|
47 |
-
return landmarks_normalized
|
48 |
|
49 |
# Function to calculate angles between landmarks
|
50 |
def calculate_angles(landmarks):
|
@@ -57,51 +52,76 @@ def calculate_angles(landmarks):
|
|
57 |
angles.extend([angle_x, angle_y])
|
58 |
return angles
|
59 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
# Streamlit app
|
61 |
st.title("ASL Recognition App")
|
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 |
-
top_indices = np.argsort(probabilities)[::-1][:5]
|
94 |
-
top_probabilities = probabilities[top_indices]
|
95 |
-
top_classes = model.classes_[top_indices]
|
96 |
-
|
97 |
-
# Display the top 5 predictions
|
98 |
-
st.write("Top 5 Predicted Alphabets:")
|
99 |
-
for i in range(5):
|
100 |
-
st.write(f"{top_classes[i]}: {top_probabilities[i]:.2f}")
|
101 |
-
|
102 |
-
# Display the image with landmarks
|
103 |
-
st.image(image, caption="Processed Image with Landmarks", use_column_width=True)
|
104 |
-
else:
|
105 |
-
st.write("No hands detected. Please try another image.")
|
106 |
-
except Exception as e:
|
107 |
-
st.error(f"Error processing image: {e}")
|
|
|
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 |
# Function to load the Random Forest model
|
12 |
@st.cache_resource
|
|
|
35 |
|
36 |
# Function to normalize landmarks
|
37 |
def normalize_landmarks(landmarks):
|
|
|
38 |
center = np.mean(landmarks, axis=0)
|
39 |
landmarks_centered = landmarks - center
|
|
|
|
|
40 |
std_dev = np.std(landmarks_centered, axis=0)
|
41 |
landmarks_normalized = landmarks_centered / std_dev
|
42 |
+
return np.nan_to_num(landmarks_normalized)
|
|
|
|
|
|
|
|
|
43 |
|
44 |
# Function to calculate angles between landmarks
|
45 |
def calculate_angles(landmarks):
|
|
|
52 |
angles.extend([angle_x, angle_y])
|
53 |
return angles
|
54 |
|
55 |
+
# Function to process image and predict alphabet
|
56 |
+
def process_and_predict(image_path):
|
57 |
+
image = cv2.imread(image_path)
|
58 |
+
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
59 |
+
results = hands.process(image_rgb)
|
60 |
+
|
61 |
+
if results.multi_hand_landmarks:
|
62 |
+
landmarks = np.array([[lm.x, lm.y] for lm in results.multi_hand_landmarks[0].landmark])
|
63 |
+
landmarks_normalized = normalize_landmarks(landmarks)
|
64 |
+
angles = calculate_angles(landmarks_normalized)
|
65 |
+
|
66 |
+
angle_columns = [f'angle_{i}' for i in range(len(angles))]
|
67 |
+
angles_df = pd.DataFrame([angles], columns=angle_columns)
|
68 |
+
|
69 |
+
probabilities = model.predict_proba(angles_df)[0]
|
70 |
+
predicted_class = model.classes_[np.argmax(probabilities)]
|
71 |
+
|
72 |
+
return predicted_class, probabilities, landmarks
|
73 |
+
|
74 |
+
return None, None, None
|
75 |
+
|
76 |
+
# Function to plot hand landmarks
|
77 |
+
def plot_hand_landmarks(landmarks, title):
|
78 |
+
fig, ax = plt.subplots()
|
79 |
+
ax.scatter(landmarks[:, 0], landmarks[:, 1], c='blue')
|
80 |
+
for connection in mp.solutions.hands.HAND_CONNECTIONS:
|
81 |
+
start_idx = connection[0]
|
82 |
+
end_idx = connection[1]
|
83 |
+
ax.plot([landmarks[start_idx, 0], landmarks[end_idx, 0]],
|
84 |
+
[landmarks[start_idx, 1], landmarks[end_idx, 1]], 'r-')
|
85 |
+
ax.invert_yaxis()
|
86 |
+
ax.set_title(title)
|
87 |
+
ax.axis('off')
|
88 |
+
return fig
|
89 |
+
|
90 |
# Streamlit app
|
91 |
st.title("ASL Recognition App")
|
92 |
|
93 |
+
# Define available alphabets
|
94 |
+
all_alphabets = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
95 |
+
excluded_alphabets = 'DMNPTUVXZ'
|
96 |
+
available_alphabets = ''.join(set(all_alphabets) - set(excluded_alphabets))
|
97 |
|
98 |
+
# Multi-select for alphabets
|
99 |
+
selected_alphabets = st.multiselect("Select alphabets to recognize:", list(available_alphabets))
|
100 |
+
|
101 |
+
if selected_alphabets:
|
102 |
+
num_selected = len(selected_alphabets)
|
103 |
+
cols = min(3, num_selected) # Maximum 3 columns
|
104 |
+
rows = (num_selected + cols - 1) // cols
|
105 |
+
|
106 |
+
for i in range(0, num_selected, cols):
|
107 |
+
row_alphabets = selected_alphabets[i:i+cols]
|
108 |
+
cols_in_row = st.columns(len(row_alphabets))
|
109 |
|
110 |
+
for j, alphabet in enumerate(row_alphabets):
|
111 |
+
with cols_in_row[j]:
|
112 |
+
image_path = f'asl test set/{alphabet}.jpg'
|
113 |
+
if os.path.exists(image_path):
|
114 |
+
predicted_class, probabilities, landmarks = process_and_predict(image_path)
|
115 |
+
if predicted_class is not None:
|
116 |
+
st.write(f"Alphabet: {alphabet}")
|
117 |
+
st.write(f"Predicted: {predicted_class}")
|
118 |
+
st.write(f"Confidence: {probabilities[model.classes_.tolist().index(predicted_class)]:.2f}")
|
119 |
+
fig = plot_hand_landmarks(landmarks, f"Hand Landmarks for {alphabet}")
|
120 |
+
st.pyplot(fig)
|
121 |
+
else:
|
122 |
+
st.write(f"No hand detected for {alphabet}")
|
123 |
+
else:
|
124 |
+
st.write(f"Image not found for {alphabet}")
|
125 |
+
|
126 |
+
else:
|
127 |
+
st.write("Please select at least one alphabet to recognize.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|