Niharmahesh commited on
Commit
de96b0e
·
verified ·
1 Parent(s): b475e79

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -51
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
- # Upload image using Streamlit's file uploader
64
- uploaded_file = st.file_uploader("Upload an image of an ASL sign", type=["jpg", "jpeg", "png"])
 
 
65
 
66
- if uploaded_file is not None:
67
- try:
68
- # Read the image
69
- image = cv2.imdecode(np.frombuffer(uploaded_file.read(), np.uint8), cv2.IMREAD_COLOR)
70
- image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
71
-
72
- # Process the image and find hand landmarks
73
- results = hands.process(image_rgb)
 
 
 
74
 
75
- if results.multi_hand_landmarks:
76
- for hand_landmarks in results.multi_hand_landmarks:
77
- # Draw landmarks on the image
78
- mp_drawing.draw_landmarks(image, hand_landmarks, mp.solutions.hands.HAND_CONNECTIONS)
79
-
80
- # Extract and normalize landmarks
81
- landmarks = np.array([[lm.x, lm.y] for lm in hand_landmarks.landmark])
82
- landmarks_normalized = normalize_landmarks(landmarks)
83
-
84
- # Calculate angles using normalized landmarks
85
- angles = calculate_angles(landmarks_normalized)
86
-
87
- # Prepare input with feature names
88
- angle_columns = [f'angle_{i}' for i in range(len(angles))]
89
- angles_df = pd.DataFrame([angles], columns=angle_columns)
90
-
91
- # Predict the alphabet
92
- probabilities = model.predict_proba(angles_df)[0]
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.")