Stress / app.py
jaimin's picture
Update app.py
a2aec99 verified
import gradio as gr
from scipy.spatial import distance as dist
from imutils import face_utils
import numpy as np
import imutils
import time
import dlib
import cv2
from keras.preprocessing.image import img_to_array
from keras.models import load_model
from huggingface_hub import hf_hub_download
# Define global variables
points = []
emotion_classifier = None
# Define Hugging Face repository details
repo_id = "jaimin/Age_detection"
# Download model files from Hugging Face
predictor_path = hf_hub_download(repo_id=repo_id, filename="shape_predictor_68_face_landmarks.dat")
emotion_model_path = hf_hub_download(repo_id=repo_id, filename="XCEPTION.102-0.66.hdf5")
def eye_brow_distance(leye, reye):
global points
distq = dist.euclidean(leye, reye)
points.append(int(distq))
return distq
def emotion_finder(faces, frame):
global emotion_classifier
EMOTIONS = ["angry", "disgust", "scared", "happy", "sad", "surprised", "neutral"]
x, y, w, h = face_utils.rect_to_bb(faces)
frame = frame[y:y + h, x:x + w]
roi = cv2.resize(frame, (64, 64))
roi = roi.astype("float") / 255.0
roi = img_to_array(roi)
roi = np.expand_dims(roi, axis=0)
preds = emotion_classifier.predict(roi)[0]
emotion_probability = np.max(preds)
label = EMOTIONS[preds.argmax()]
return label
def normalize_values(points, disp):
normalized_value = abs(disp - np.min(points)) / abs(np.max(points) - np.min(points))
stress_value = np.exp(-(normalized_value))
return stress_value
def stress(video_path, duration):
global points, emotion_classifier
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)
emotion_classifier = load_model(emotion_model_path, compile=False)
# Open video file
cap = cv2.VideoCapture(video_path)
points = []
stress_labels = []
start_time = time.time()
while True:
current_time = time.time()
if current_time - start_time >= duration:
break
ret, frame = cap.read()
if not ret:
break
frame = cv2.flip(frame, 1)
frame = imutils.resize(frame, width=500, height=500)
(lBegin, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eyebrow"]
(rBegin, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eyebrow"]
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
try:
detections = detector(gray, 0)
for detection in detections:
emotion = emotion_finder(detection, gray)
shape = predictor(gray, detection)
shape = face_utils.shape_to_np(shape)
leyebrow = shape[lBegin:lEnd]
reyebrow = shape[rBegin:rEnd]
distq = eye_brow_distance(leyebrow[-1], reyebrow[0])
stress_value = normalize_values(points, distq)
# Determine stress label for this frame
if emotion in ['scared', 'sad', 'angry'] and stress_value >= 0.75:
stress_label = 'stressed'
else:
stress_label = 'not stressed'
# Store stress label in list
stress_labels.append(stress_label)
except Exception as e:
print(f'Error: {e}')
cap.release()
# Count occurrences of 'stressed' and 'not stressed'
stressed_count = stress_labels.count('stressed')
not_stressed_count = stress_labels.count('not stressed')
# Determine which label occurred more frequently
if stressed_count > not_stressed_count:
most_frequent_label = 'stressed'
else:
most_frequent_label = 'not stressed'
return stressed_count, not_stressed_count, most_frequent_label
def gradio_interface(video, duration):
stressed_count, not_stressed_count, most_frequent_label = stress(video, duration)
return f"Stressed frames: {stressed_count}", f"Not stressed frames: {not_stressed_count}", f"Most frequent state: {most_frequent_label}"
# Define Gradio interface for Heart and Stress Measurement
gr.Interface(
fn=gradio_interface,
inputs=[gr.Video(label="Upload a video file"), gr.Number(value=30, label="Duration (seconds)")],
outputs="json",
title="Heart Rate and Stress Measurement"
).launch(server_name="0.0.0.0")