Spaces:
Sleeping
Sleeping
Niharmahesh
commited on
Commit
•
c7f34f1
1
Parent(s):
4fd4e67
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import cv2
|
3 |
+
import numpy as np
|
4 |
+
import mediapipe as mp
|
5 |
+
import pickle
|
6 |
+
import os
|
7 |
+
|
8 |
+
# Define the models directory
|
9 |
+
models_dir = 'models'
|
10 |
+
|
11 |
+
# Load models
|
12 |
+
def load_model(file_path):
|
13 |
+
try:
|
14 |
+
with open(file_path, 'rb') as file:
|
15 |
+
return pickle.load(file)
|
16 |
+
except FileNotFoundError:
|
17 |
+
st.error(f"Error: Model file not found at {file_path}")
|
18 |
+
except Exception as e:
|
19 |
+
st.error(f"Error loading model from {file_path}: {e}")
|
20 |
+
return None
|
21 |
+
|
22 |
+
models = {
|
23 |
+
'Random Forest': load_model(os.path.join(models_dir, 'random_forest_model.pkl')),
|
24 |
+
'SVM': load_model(os.path.join(models_dir, 'svm_model.pkl')),
|
25 |
+
'Hard Voting': load_model(os.path.join(models_dir, 'hard_voting_classifier.pkl')),
|
26 |
+
'Soft Voting': load_model(os.path.join(models_dir, 'soft_voting_classifier.pkl'))
|
27 |
+
}
|
28 |
+
|
29 |
+
# Load label encoder
|
30 |
+
label_encoder = load_model(os.path.join(models_dir, 'label_encoder.pkl'))
|
31 |
+
if label_encoder is None:
|
32 |
+
st.error("Failed to load label encoder. Exiting.")
|
33 |
+
st.stop()
|
34 |
+
|
35 |
+
# Initialize MediaPipe Hands
|
36 |
+
mp_hands = mp.solutions.hands
|
37 |
+
hands = mp_hands.Hands(static_image_mode=True, max_num_hands=1, min_detection_confidence=0.5)
|
38 |
+
|
39 |
+
def process_landmarks(hand_landmarks):
|
40 |
+
x_ = [landmark.x for landmark in hand_landmarks.landmark]
|
41 |
+
y_ = [landmark.y for landmark in hand_landmarks.landmark]
|
42 |
+
min_x, min_y = min(x_), min(y_)
|
43 |
+
return [coord - min_val for landmark in hand_landmarks.landmark for coord, min_val in zip((landmark.x, landmark.y), (min_x, min_y))]
|
44 |
+
|
45 |
+
def get_model_predictions(data_aux, model):
|
46 |
+
if hasattr(model, 'predict_proba'):
|
47 |
+
probabilities = model.predict_proba([data_aux])[0]
|
48 |
+
elif hasattr(model, 'decision_function'):
|
49 |
+
scores = model.decision_function([data_aux])[0]
|
50 |
+
probabilities = (scores - scores.min()) / (scores.max() - scores.min())
|
51 |
+
else:
|
52 |
+
class_pred = model.predict([data_aux])[0]
|
53 |
+
probabilities = np.zeros(len(label_encoder.classes_))
|
54 |
+
probabilities[class_pred] = 1
|
55 |
+
|
56 |
+
top_index = np.argmax(probabilities)
|
57 |
+
return label_encoder.inverse_transform([top_index])[0], probabilities[top_index]
|
58 |
+
|
59 |
+
def predict_alphabet(image):
|
60 |
+
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
61 |
+
results = hands.process(image_rgb)
|
62 |
+
|
63 |
+
if not results.multi_hand_landmarks:
|
64 |
+
return None, None
|
65 |
+
|
66 |
+
data_aux = process_landmarks(results.multi_hand_landmarks[0])
|
67 |
+
predictions = {}
|
68 |
+
|
69 |
+
for model_name, model in models.items():
|
70 |
+
if model is None:
|
71 |
+
continue
|
72 |
+
prediction, probability = get_model_predictions(data_aux, model)
|
73 |
+
predictions[model_name] = (prediction, probability)
|
74 |
+
|
75 |
+
return predictions, results.multi_hand_landmarks[0]
|
76 |
+
|
77 |
+
def draw_hand_landmarks(image, hand_landmarks):
|
78 |
+
for landmark in hand_landmarks.landmark:
|
79 |
+
h, w, _ = image.shape
|
80 |
+
cx, cy = int(landmark.x * w), int(landmark.y * h)
|
81 |
+
cv2.circle(image, (cx, cy), 5, (0, 255, 0), -1)
|
82 |
+
return image
|
83 |
+
|
84 |
+
# Streamlit App
|
85 |
+
st.title("ASL Hand Shape Recognition App")
|
86 |
+
|
87 |
+
uploaded_file = st.file_uploader("Choose a hand image...", type=["jpg", "jpeg", "png"])
|
88 |
+
|
89 |
+
if uploaded_file is not None:
|
90 |
+
image = cv2.imdecode(np.frombuffer(uploaded_file.read(), np.uint8), 1)
|
91 |
+
st.image(image, channels="BGR", caption="Uploaded Hand Image")
|
92 |
+
|
93 |
+
predictions, hand_landmarks = predict_alphabet(image)
|
94 |
+
|
95 |
+
if predictions and hand_landmarks:
|
96 |
+
st.subheader("Predictions:")
|
97 |
+
for model_name, (prediction, probability) in predictions.items():
|
98 |
+
st.write(f"{model_name}: {prediction} (Probability: {probability:.2f})")
|
99 |
+
|
100 |
+
st.subheader("Hand Landmarks:")
|
101 |
+
landmark_image = draw_hand_landmarks(image.copy(), hand_landmarks)
|
102 |
+
st.image(landmark_image, channels="BGR", caption="Hand Landmarks")
|
103 |
+
else:
|
104 |
+
st.write("No hand detected in the image.")
|
105 |
+
|
106 |
+
# User input to draw hand sign (placeholder)
|
107 |
+
user_input = st.text_input("Enter alphabet to draw hand sign:")
|
108 |
+
if user_input:
|
109 |
+
if len(user_input) == 1 and user_input.isalpha():
|
110 |
+
st.write(f"Drawing hand sign for alphabet: {user_input.upper()}")
|
111 |
+
# Placeholder for drawing hand sign
|
112 |
+
st.write("(Hand sign drawing functionality not implemented)")
|
113 |
+
else:
|
114 |
+
st.error("Please enter a single alphabet.")
|
115 |
+
|
116 |
+
# Release MediaPipe resources
|
117 |
+
hands.close()
|