finalproject / utils /page_handlers.py
jarondon82's picture
Eliminada la imagen grande que aparece debajo de About the Detection Methods
c408c63
"""
Page Handlers Module for EmotionMirror application.
This module contains handler functions for different pages in the EmotionMirror application.
Following the principle of modularization, each page's logic is separated into its own function.
"""
import logging
import streamlit as st
import cv2
import numpy as np
from utils.preprocessing_ui import show_preprocessing_ui, get_processing_image
from utils.image_visualization import display_image_with_controls, create_image_tabs, handle_image_viewer
from PIL import Image
import io
import os
import json
import time
from typing import Dict, Any
from datetime import datetime
from utils.export_utils import export_to_json, export_to_csv, get_download_link, generate_emotion_summary
logger = logging.getLogger(__name__)
def handle_visual_analysis(agent_manager, image_service, db_service, uploaded_file=None):
"""
Handle the Visual Analysis page logic.
Args:
agent_manager: The agent manager instance
image_service: The image service instance
db_service: The database service instance
uploaded_file: The uploaded file, if any
"""
st.header("Visual Emotion Analysis")
st.markdown("""
Upload an image to analyze emotions.
For best results, use a clear image of a face with good lighting.
""")
# Ensure agent_manager is properly initialized
if not agent_manager:
st.error("Agent manager is not initialized correctly. Please refresh the page.")
return
# Initialize the visual agent at the start
visual_agent = agent_manager.get_agent("VisualAgent")
if not visual_agent:
st.warning("Visual agent not available. The system is initializing or there is a configuration issue.")
logger.error("Failed to get VisualAgent from agent_manager")
# Create numbered sections to match local version
st.subheader("1. Upload an Image")
# Add reset button for clearing current image
if "original_image" in st.session_state:
col1, col2 = st.columns([3, 1])
with col2:
if st.button("Clear Current Image", key="clear_image"):
# Clear the session state
if "original_image" in st.session_state:
del st.session_state["original_image"]
if "processed_image" in st.session_state:
del st.session_state["processed_image"]
if "current_image_path" in st.session_state:
del st.session_state["current_image_path"]
st.experimental_rerun()
# Create file uploader
if uploaded_file is None:
uploaded_file = st.file_uploader(
"Choose an image...",
type=["jpg", "jpeg", "png"],
help="Upload a clear image of a face for analysis."
)
# Display information about detection methods
with st.expander("About the Detection Methods", expanded=False):
st.markdown("""
### About the Detection Methods
Currently using: **Advanced Detection**
* **Basic detection** is faster but less accurate. It works by analyzing simple facial features.
* **Advanced detection (DeepFace)** uses deep learning models that are trained on thousands of faces to recognize subtle emotional cues.
You can change the default detection method in the sidebar settings.
""")
# Display image and interface when uploaded
if uploaded_file is not None:
try:
# Process the uploaded file
file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)
uploaded_file.seek(0) # Reset the file pointer for further processing
# Validate image file - includes format, size, and dimensions
validation_result = image_service.validate_image_file(
uploaded_file,
check_content=True,
check_dimensions=True
)
# If the image is valid, process it
if validation_result["valid"]:
# Process the uploaded image to improve quality if possible
try:
# Load image for processing with OpenCV (this will be in BGR format)
img = cv2.imdecode(file_bytes, cv2.IMREAD_COLOR)
# Convert from BGR to RGB for preprocessing display
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# Store original RGB image for display
if "original_image" not in st.session_state:
st.session_state.original_image = img_rgb.copy()
# Determine which image to process based on preprocessing settings
use_improved = st.session_state.get("use_improved_image", False)
# Choose image for processing
img_to_process = get_processing_image(img_rgb, image_service, use_improved)
# Comentamos esta sección para eliminar la imagen grande
"""
# Check if we have both original and processed images
if "processed_image" in st.session_state:
# Create tabs to display original and processed images
image_tabs_result = create_image_tabs(
st.session_state.original_image,
st.session_state.processed_image
)
else:
# Display just the original image
display_result = display_image_with_controls(
st.session_state.original_image,
title="Uploaded Image",
allow_zoom=True,
allow_download=True
)
# Store the processed image if available for comparison
if use_improved and img_to_process is not None:
st.session_state.processed_image = img_to_process
"""
# Display image analysis from validation
st.subheader("3. Image Analysis")
analysis_expander = st.expander("View Image Analysis Details", expanded=False)
with analysis_expander:
# Show image metadata
if "image_metadata" in validation_result:
metadata = validation_result["image_metadata"]
st.markdown("#### Image Details")
# Create columns for metadata display
meta_cols = st.columns(3)
with meta_cols[0]:
st.markdown("**Dimensions**")
width = metadata.get("width", 0)
height = metadata.get("height", 0)
st.write(f"{width} × {height}")
with meta_cols[1]:
st.markdown("**Format**")
img_format = metadata.get("format", "Unknown")
st.write(f"{img_format}")
with meta_cols[2]:
st.markdown("**Size**")
size_kb = metadata.get("size_kb", 0)
st.write(f"{size_kb:.1f} KB")
# Quality metrics if available
if "quality" in metadata:
st.markdown("#### Quality Metrics")
quality = metadata["quality"]
# Create columns for quality metrics
metric_cols = st.columns(3)
with metric_cols[0]:
st.markdown("**Sharpness**")
sharpness = int(quality.get("sharpness", 0) * 100)
st.write(f"{sharpness}%")
with metric_cols[1]:
st.markdown("**Brightness**")
brightness = int(quality.get("brightness", 0) * 100)
st.write(f"{brightness}%")
with metric_cols[2]:
st.markdown("**Contrast**")
contrast = int(quality.get("contrast", 0.26) * 100)
st.write(f"{contrast}%")
# Add space between sections
st.markdown("<div style='height: 20px;'></div>", unsafe_allow_html=True)
# NOW display the preprocessing UI AFTER the Image Analysis section
st.subheader("4. Image Preprocessing")
preprocessing_result = show_preprocessing_ui(image_service, img_rgb)
if not preprocessing_result.get("success", False):
st.error(f"Error in preprocessing: {preprocessing_result.get('message', 'Unknown error')}")
# Store path in session state for future use
if "current_image_path" not in st.session_state:
# Save the file for reference
save_path = image_service.save_uploaded_image(img_to_process)
st.session_state["current_image_path"] = save_path
# Add some space to improve layout
st.markdown("<div style='height: 20px;'></div>", unsafe_allow_html=True)
# Analysis section
st.subheader("5. Emotion Analysis")
st.info("Image successfully uploaded. Emotion analysis functionality will be available soon.")
# Add a disabled button as placeholder for future functionality
st.button("Analyze Emotions (Coming Soon)", disabled=True, key="analyze_button")
except Exception as e:
logger.error(f"Error processing image: {e}", exc_info=True)
st.error(f"Error processing image: {str(e)}")
else:
# Show validation issues
st.error("Image validation failed:")
for issue in validation_result["issues"]:
st.warning(issue)
except Exception as e:
logger.error(f"Error in Visual Analysis: {e}", exc_info=True)
st.error(f"Error processing image: {str(e)}")
def handle_history_page(db_service):
"""
Handle the History page logic.
Args:
db_service: The database service instance
"""
st.header("Analysis History")
st.markdown("View your previous analyses and export results.")
# Create tabs for different views - Using numbered sequence for clear navigation
history_tabs = ["1. Recent Analyses", "2. Statistics", "3. Export Data"]
tab1, tab2, tab3 = st.tabs(history_tabs)
with tab1:
# Implementation of recent analyses tab
pass # Implement the rest of the history page functionality
with tab2:
# Implementation of statistics tab
pass # Implement statistics functionality
with tab3:
# Implementation of export data tab
pass # Implement export functionality
def handle_about_page():
"""Handle the About page logic."""
st.header("About EmotionMirror")
st.markdown("""
EmotionMirror is an application that uses computer vision to analyze emotions in facial expressions.
**Version:** 0.1.3 (Phase 1.3)
**Features:**
- Facial emotion detection using computer vision
- Support for image uploads
- Analysis history and data export
- Image preprocessing for improved detection
**Technology:**
- Python
- OpenCV for image processing
- Deep learning models for emotion classification
- Streamlit for the user interface
""")