diff --git a/code/new_models/app_local_streamlit_deepface.py b/code/new_models/app_local_streamlit_deepface.py new file mode 100644 index 0000000..f6f00a1 --- /dev/null +++ b/code/new_models/app_local_streamlit_deepface.py @@ -0,0 +1,220 @@ +# Required versions: +# protobuf==3.20.3, tensorflow==2.10 + +import streamlit as st +import cv2 +from deepface import DeepFace +import numpy as np +import webbrowser +import requests +import re +import os +import time + +# App config +st.set_page_config(page_title="Emotion-Based Music Player", layout="centered") +st.title("Facial Emotion Recognition App") +st.write("This app detects your facial expression, displays the predicted emotion, and plays a suitable song.") + +#Footer +st.markdown( + """ + + + + """, + unsafe_allow_html=True +) + +#st.title("🧠 Detected Emotion KPI") + +# App state +if "last_emotion" not in st.session_state: + st.session_state.last_emotion = "Neutral" +if "show_video" not in st.session_state: + st.session_state.show_video = False + +# Function to detect emotion +def detect_emotion(frame): + try: + results = DeepFace.analyze(frame, actions=["emotion"], enforce_detection=False) + + # Handle single or multiple face results + if not isinstance(results, list): + results = [results] + + for result in results: + emotion = result['dominant_emotion'] + region = result['region'] + x, y, w, h = region['x'], region['y'], region['w'], region['h'] + + # Draw bounding box around the detected face + cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) + + # label the detected emotion above the face + cv2.putText(frame, emotion, (x, y - 10), + cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 0), 2) + + # Assume first emotion as dominant for app state + st.session_state.last_emotion = results[0]['dominant_emotion'] + + except Exception as e: + emotion = st.session_state.last_emotion + print("DeepFace failed:", e) + + return frame, st.session_state.last_emotion + +# ------------------------------ +# 🎥 Live Camera Detection Mode +# ------------------------------ +if not st.session_state.show_video: + col1, col2 = st.columns([1, 2]) + + with col1: + st.subheader("📊 Current Emotion") + emotion_placeholder = st.empty() + + cap = cv2.VideoCapture(0) + capture = False + + with col2: + st.subheader("📷 Live Feed") + image_placeholder = st.empty() + st.markdown("
", unsafe_allow_html=True) + capture = st.button("🎵 Play Song on Captured Emotion") + + + st.markdown("---") + + while cap.isOpened() and not capture: + ret, frame = cap.read() + if not ret: + break + + frame = cv2.resize(frame, (320, 240)) + frame, detected_emotion = detect_emotion(frame) + st.session_state.last_emotion = detected_emotion + + # Update live KPI and video feed + + emotion_colors = { + "Happy": "#DFF2BF", + "Sad": "#FFBABA", + "Angry": "#FFAAAA", + "Surprise": "#FFFFBA", + "Neutral": "#E0E0E0", + "Fear": "#D0BAFF", + "Disgust": "#B0FFBA" + } + + bg_color = emotion_colors.get(detected_emotion, "#f9fff9") + + emotion_placeholder.markdown( + f""" +
+ {detected_emotion} +
+ """, + unsafe_allow_html=True + ) + + + image_placeholder.image(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB), channels="RGB") + + if cv2.waitKey(1) & 0xFF == ord('q'): + break + time.sleep(0.1) # Limit refresh rate + + cap.release() + st.session_state.show_video = True # switch mode + +# ------------------------------ +# 🎧 Play Song For Detected Mood +# ------------------------------ +if st.session_state.show_video: + st.markdown("## 🎧 Now Playing Music For Your Mood") + st.markdown(f"**Detected Mood:** `{st.session_state.last_emotion}`") + + if st.button("🔁 Detect Emotions Again"): + st.session_state.show_video = False + st.rerun() + + search_query = f"https://www.youtube.com/results?search_query={st.session_state.last_emotion}+background+tunes" + + # to fetch the search results page + response = requests.get(search_query) + + # HTTP status code 200 = request was successful + if response.status_code != 200: + print("Failed to retrieve YouTube search results. Status code:", response.status_code) + + html_content = response.text + + match = re.search(r'/watch\?v=([^\"]+)', html_content) + if match: + video_id = match.group(1) + #video_url = f"https://www.youtube.com/watch?v={video_id}" + video_url = f"https://www.youtube.com/watch?v={video_id.encode('utf-8').decode('unicode_escape')}" + + # printing the video URL for debugging purposes + st.video(video_url) + print("Opening YouTube video:", video_url) + + +# Benchmark: Compare DeepFace Inference Time (Optional) +with st.expander("📊 Benchmark Inference Time"): + if st.button("📸 Capture Frame and Benchmark DeepFace"): + cap = cv2.VideoCapture(0) + ret, frame = cap.read() + cap.release() + + if ret: + start_time = time.time() + try: + result = DeepFace.analyze(frame, actions=["emotion"], enforce_detection=False) + end_time = time.time() + + detected_emotion = result[0]['dominant_emotion'] + st.image(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB), caption="Captured Frame", channels="RGB") + st.success(f"✅ DeepFace Inference Time: `{round(end_time - start_time, 3)}s`") + st.write("🎭 Detected Emotion:", detected_emotion) + except Exception as e: + st.error(f"❌ DeepFace failed: {str(e)}") + else: + st.error("❌ Failed to capture frame from webcam.") + + + + + diff --git a/code/new_models/app_local_streamlit_with_benchmark.py b/code/new_models/app_local_streamlit_with_benchmark.py new file mode 100644 index 0000000..b8d8ae9 --- /dev/null +++ b/code/new_models/app_local_streamlit_with_benchmark.py @@ -0,0 +1,220 @@ +import streamlit as st +import cv2 +from keras.models import load_model # Assuming you have Keras installed +import numpy as np +import webbrowser +import requests +import re +import os +import time + +# Load model and labels +model = load_model("code/model/fer2013_mini_XCEPTION.102-0.66.hdf5") +emotions = ['Angry', 'Disgust', 'Fear', 'Happy', 'Sad', 'Surprise', 'Neutral'] +face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') + +def preprocess_for_hdf(frame): + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + face_img = cv2.resize(gray, (64, 64)) + face_img = face_img.astype("float32") / 255.0 + face_img = np.expand_dims(face_img, axis=0) + face_img = np.expand_dims(face_img, axis=-1) # shape: (1, 48, 48, 1) + return face_img + +# App config +st.set_page_config(page_title="Emotion-Based Music Player", layout="centered") +st.title("Facial Emotion Recognition App") +st.write("This app detects your facial expression, displays the predicted emotion, and plays a suitable song.") + +#Footer +st.markdown( + """ + + + + """, + unsafe_allow_html=True +) + +#st.title("🧠 Detected Emotion KPI") + +# App state +if "last_emotion" not in st.session_state: + st.session_state.last_emotion = "Neutral" +if "show_video" not in st.session_state: + st.session_state.show_video = False + +# Function to detect emotion +def detect_emotion(frame): + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + faces = face_cascade.detectMultiScale(gray, 1.3, 5) + + emotion = st.session_state.last_emotion + for (x, y, w, h) in faces: + roi_gray = gray[y:y+h, x:x+w] + roi_gray = cv2.resize(roi_gray, (64, 64)) + roi = roi_gray.astype("float") / 255.0 + roi = np.expand_dims(roi, axis=0) + roi = np.expand_dims(roi, axis=-1) + preds = model.predict(roi)[0] + emotion = emotions[np.argmax(preds)] + cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) + cv2.putText(frame, emotion, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (36, 255, 12), 2) + break + return frame, emotion + +# ------------------------------ +# 🎥 Live Camera Detection Mode +# ------------------------------ +if not st.session_state.show_video: + col1, col2 = st.columns([1, 2]) + + with col1: + st.subheader("📊 Current Emotion") + emotion_placeholder = st.empty() + + cap = cv2.VideoCapture(0) + capture = False + + with col2: + st.subheader("📷 Live Feed") + image_placeholder = st.empty() + st.markdown("
", unsafe_allow_html=True) + capture = st.button("🎵 Play Song on Captured Emotion") + + + st.markdown("---") + + while cap.isOpened() and not capture: + ret, frame = cap.read() + if not ret: + break + + frame = cv2.resize(frame, (320, 240)) + frame, detected_emotion = detect_emotion(frame) + st.session_state.last_emotion = detected_emotion + + # Update live KPI and video feed + + emotion_colors = { + "Happy": "#DFF2BF", + "Sad": "#FFBABA", + "Angry": "#FFAAAA", + "Surprise": "#FFFFBA", + "Neutral": "#E0E0E0", + "Fear": "#D0BAFF", + "Disgust": "#B0FFBA" + } + + bg_color = emotion_colors.get(detected_emotion, "#f9fff9") + + emotion_placeholder.markdown( + f""" +
+ {detected_emotion} +
+ """, + unsafe_allow_html=True + ) + + + image_placeholder.image(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB), channels="RGB") + + if cv2.waitKey(1) & 0xFF == ord('q'): + break + time.sleep(0.1) # Limit refresh rate + + cap.release() + st.session_state.show_video = True # switch mode + +# ------------------------------ +# 🎧 Play Song For Detected Mood +# ------------------------------ +if st.session_state.show_video: + st.markdown("## 🎧 Now Playing Music For Your Mood") + st.markdown(f"**Detected Mood:** `{st.session_state.last_emotion}`") + + if st.button("🔁 Detect Emotions Again"): + st.session_state.show_video = False + st.rerun() + + search_query = f"https://www.youtube.com/results?search_query={st.session_state.last_emotion}+background+tunes" + + # to fetch the search results page + response = requests.get(search_query) + + # HTTP status code 200 = request was successful + if response.status_code != 200: + print("Failed to retrieve YouTube search results. Status code:", response.status_code) + + html_content = response.text + + match = re.search(r'/watch\?v=([^\"]+)', html_content) + if match: + video_id = match.group(1) + #video_url = f"https://www.youtube.com/watch?v={video_id}" + video_url = f"https://www.youtube.com/watch?v={video_id.encode('utf-8').decode('unicode_escape')}" + + # printing the video URL for debugging purposes + st.video(video_url) + print("Opening YouTube video:", video_url) + + + + +# In your expander section: +with st.expander("📊 Benchmark Inference Time"): + if st.button("📸 Capture Frame and Benchmark HDF5 Model"): + cap = cv2.VideoCapture(0) + ret, frame = cap.read() + cap.release() + + if ret: + face_img = preprocess_for_hdf(frame) + + start_time = time.time() + prediction = model.predict(face_img) + end_time = time.time() + + predicted_emotion = emotions[np.argmax(prediction)] + + st.image(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB), caption="Captured Frame", channels="RGB") + st.success(f"✅ HDF5 Inference Time: `{round(end_time - start_time, 3)}s`") + st.write("🎭 Detected Emotion:", predicted_emotion) + else: + st.error("❌ Failed to capture frame from webcam.") + + + +