File size: 2,643 Bytes
156a467
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import os
os.environ["KERAS_BACKEND"] = "jax"

import gradio as gr
import keras
import numpy as np
import cv2
from PIL import Image
import io
from huggingface_hub import hf_hub_download

# Load model and set desired emotions
model = None
desired_emotions = ['happy', 'sad', 'neutral']
original_emotion_labels = ['angry', 'disgust', 'fear', 'happy', 'sad', 'surprise', 'neutral']
desired_indices = [original_emotion_labels.index(emotion) for emotion in desired_emotions]

# Load model from Hugging Face Hub
def load_emotion_model():
    global model
    try:
        print("πŸ”„ Downloading model from HuggingFace Hub...")
        model_path = hf_hub_download(repo_id="Shees7/facial_model", filename="emotion_model.keras")
        print("βœ… Model file downloaded at:", model_path)
        model = keras.saving.load_model(model_path)
        print("βœ… Model loaded successfully.")
    except Exception as e:
        print("❌ Failed to load model:", str(e))

# Call model loader on startup
load_emotion_model()

# Preprocess uploaded image to extract and prepare face
def preprocess_face(image):
    try:
        np_img = np.array(image.convert('RGB'))
        face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
        gray = cv2.cvtColor(np_img, cv2.COLOR_RGB2GRAY)
        faces = face_cascade.detectMultiScale(gray, 1.1, 4)

        if len(faces) == 0:
            return None

        x, y, w, h = faces[0]
        face = np_img[y:y+h, x:x+w]
        face_resized = cv2.resize(face, (224, 224))
        face_normalized = face_resized / 255.0
        face_expanded = np.expand_dims(face_normalized, axis=0)
        return face_expanded
    except Exception as e:
        print("❌ Error during preprocessing:", str(e))
        return None

# Inference function for Gradio
def predict_emotion(image):
    if model is None:
        return "Model not loaded."

    processed_face = preprocess_face(image)
    if processed_face is None:
        return "neutral"

    predictions = model.predict(processed_face)[0]
    filtered_predictions = [predictions[i] for i in desired_indices]
    predicted_index = np.argmax(filtered_predictions)
    predicted_emotion = desired_emotions[predicted_index]
    return predicted_emotion

# Gradio UI
iface = gr.Interface(
    fn=predict_emotion,
    inputs=gr.Image(type="pil"),
    outputs=gr.Text(label="Predicted Emotion"),
    title="Facial Emotion Recognition",
    description="Upload an image with a visible face. The model predicts one of: happy, sad, or neutral."
)

# Launch for Hugging Face Spaces
if __name__ == "__main__":
    iface.launch()