Face / app.py
abeimam's picture
Upload 12 files
f9e4904 verified
import base64
import numpy as np
import cv2
from flask import Flask, render_template, request, jsonify
import tensorflow as tf
from PIL import Image
import io
from mtcnn import MTCNN
import os
app = Flask(__name__, static_folder='static', template_folder='templates')
app.secret_key = 'shamstabrez'
# Load Model
model_path = os.path.join("model", "RAFDB_Custom.h5")
if not os.path.exists(model_path):
raise FileNotFoundError(f"Model file not found: {model_path}")
model = tf.keras.models.load_model(model_path)
class_labels = ['Angry', 'Disgust', 'Fear', 'Happy', 'Neutral', 'Sad', 'Surprise']
IMG_SIZE = (48, 48)
detector = MTCNN()
streaming = False
def detect_and_classify(frame):
faces = detector.detect_faces(frame)
detected_faces = []
if faces:
for face in faces:
x, y, w, h = face['box']
x, y = max(0, x), max(0, y)
cropped_face = frame[y:y+h, x:x+w]
if cropped_face.shape[0] > 0 and cropped_face.shape[1] > 0:
face_rgb = cv2.resize(cropped_face, IMG_SIZE)
face_array = tf.keras.preprocessing.image.img_to_array(face_rgb) / 255.0
face_array = np.expand_dims(face_array, axis=0)
predictions = model.predict(face_array)[0]
top_indices = np.argsort(predictions)[-3:][::-1] # Get top 3 emotions
top_emotions = [(class_labels[i], round(predictions[i] * 100, 2)) for i in top_indices]
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 1) # Thin border
for i, (emotion, percentage) in enumerate(top_emotions):
text = f"{emotion} ({percentage}%)"
cv2.putText(frame, text, (x, y - (i * 20) - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
detected_faces.extend(top_emotions)
return frame, detected_faces
@app.route('/')
def index():
return render_template('index.html', top_emotions=None, img_base64=None, show_upload=True, show_camera=False, initial_image=True)
@app.route('/classify', methods=['POST'])
def classify_image():
image = request.files['image']
img = Image.open(image)
img = np.array(img)
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
processed_frame, top_emotions = detect_and_classify(img)
_, buffer = cv2.imencode('.png', processed_frame)
img_base64 = base64.b64encode(buffer).decode('utf-8')
return render_template('index.html', top_emotions=top_emotions, img_base64=img_base64, show_upload=True, show_camera=False, initial_image=False)
@app.route('/predict_video', methods=['POST'])
def predict_video():
data = request.json
image_data = data.get("image")
if not image_data:
return jsonify({"error": "No image data received"}), 400
image_data = image_data.split(",")[1]
image_bytes = base64.b64decode(image_data)
image = Image.open(io.BytesIO(image_bytes))
frame = np.array(image)
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
processed_frame, detected_faces = detect_and_classify(frame)
_, buffer = cv2.imencode(".jpg", processed_frame)
processed_image_base64 = base64.b64encode(buffer).decode("utf-8")
return jsonify({"processed_frame": processed_image_base64, "emotions": detected_faces})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860)