File size: 3,915 Bytes
c7f34f1
 
 
 
 
 
3c0e7f6
 
 
 
 
 
 
 
 
d08637a
 
c7f34f1
 
3c0e7f6
 
 
 
c7f34f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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
94
95
96
97
98
99
100
101
102
103
104
105
106
import streamlit as st
import cv2
import numpy as np
import mediapipe as mp
import pickle

# Load models directly
with open('random_forest_model.pkl', 'rb') as file:
    random_forest_model = pickle.load(file)
with open('svm_model.pkl', 'rb') as file:
    svm_model = pickle.load(file)
with open('hard_voting_classifier.pkl', 'rb') as file:
    hard_voting_model = pickle.load(file)
with open('soft_voting_classifier.pkl', 'rb') as file:
    soft_voting_model = pickle.load(file)
label_classes = np.load('label_classes.npy', allow_pickle=True)


models = {
    'Random Forest': random_forest_model,
    'SVM': svm_model,
    'Hard Voting': hard_voting_model,
    'Soft Voting': soft_voting_model
}

# Initialize MediaPipe Hands
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(static_image_mode=True, max_num_hands=1, min_detection_confidence=0.5)

def process_landmarks(hand_landmarks):
    x_ = [landmark.x for landmark in hand_landmarks.landmark]
    y_ = [landmark.y for landmark in hand_landmarks.landmark]
    min_x, min_y = min(x_), min(y_)
    return [coord - min_val for landmark in hand_landmarks.landmark for coord, min_val in zip((landmark.x, landmark.y), (min_x, min_y))]

def get_model_predictions(data_aux, model):
    if hasattr(model, 'predict_proba'):
        probabilities = model.predict_proba([data_aux])[0]
    elif hasattr(model, 'decision_function'):
        scores = model.decision_function([data_aux])[0]
        probabilities = (scores - scores.min()) / (scores.max() - scores.min())
    else:
        class_pred = model.predict([data_aux])[0]
        probabilities = np.zeros(len(label_encoder.classes_))
        probabilities[class_pred] = 1

    top_index = np.argmax(probabilities)
    return label_encoder.inverse_transform([top_index])[0], probabilities[top_index]

def predict_alphabet(image):
    image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    results = hands.process(image_rgb)

    if not results.multi_hand_landmarks:
        return None, None

    data_aux = process_landmarks(results.multi_hand_landmarks[0])
    predictions = {}

    for model_name, model in models.items():
        prediction, probability = get_model_predictions(data_aux, model)
        predictions[model_name] = (prediction, probability)

    return predictions, results.multi_hand_landmarks[0]

def draw_hand_landmarks(image, hand_landmarks):
    for landmark in hand_landmarks.landmark:
        h, w, _ = image.shape
        cx, cy = int(landmark.x * w), int(landmark.y * h)
        cv2.circle(image, (cx, cy), 5, (0, 255, 0), -1)
    return image

# Streamlit App
st.title("ASL Hand Shape Recognition App")

uploaded_file = st.file_uploader("Choose a hand image...", type=["jpg", "jpeg", "png"])

if uploaded_file is not None:
    image = cv2.imdecode(np.frombuffer(uploaded_file.read(), np.uint8), 1)
    st.image(image, channels="BGR", caption="Uploaded Hand Image")

    predictions, hand_landmarks = predict_alphabet(image)

    if predictions and hand_landmarks:
        st.subheader("Predictions:")
        for model_name, (prediction, probability) in predictions.items():
            st.write(f"{model_name}: {prediction} (Probability: {probability:.2f})")

        st.subheader("Hand Landmarks:")
        landmark_image = draw_hand_landmarks(image.copy(), hand_landmarks)
        st.image(landmark_image, channels="BGR", caption="Hand Landmarks")
    else:
        st.write("No hand detected in the image.")

# User input to draw hand sign (placeholder)
user_input = st.text_input("Enter alphabet to draw hand sign:")
if user_input:
    if len(user_input) == 1 and user_input.isalpha():
        st.write(f"Drawing hand sign for alphabet: {user_input.upper()}")
        # Placeholder for drawing hand sign
        st.write("(Hand sign drawing functionality not implemented)")
    else:
        st.error("Please enter a single alphabet.")

# Release MediaPipe resources
hands.close()