Spaces:
Runtime error
Runtime error
File size: 5,395 Bytes
a4af8e6 72cf232 a4af8e6 72cf232 a4af8e6 72cf232 a4af8e6 b36b7cd |
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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# app_gradio.py
import gradio as gr
import numpy as np
import os
import yaml
from dotenv import load_dotenv
import io
from scipy.io.wavfile import read as read_wav
# Correctly import from the drive_paddy package structure
from src.detection.factory import get_detector
from src.alerting.alert_system import get_alerter
# --- Load Configuration and Environment Variables ---
# This part is the same as our Streamlit app
load_dotenv()
config_path = 'config.yaml'
with open(config_path, 'r') as f:
config = yaml.safe_load(f)
secrets = {
"gemini_api_key": os.getenv("GEMINI_API_KEY"),
}
# --- Initialize Backend Components ---
# We create these once and reuse them.
detector = get_detector(config)
alerter = get_alerter(config, secrets["gemini_api_key"])
# --- Audio Processing for Gradio ---
# Gradio's gr.Audio component needs a specific format: (sample_rate, numpy_array)
def process_audio_for_gradio(audio_bytes):
"""Converts in-memory audio bytes to a format Gradio can play."""
# gTTS creates MP3, so we read it as such
byte_io = io.BytesIO(audio_bytes)
# The 'read' function from scipy.io.wavfile expects a WAV file.
# We need to first convert the MP3 bytes from gTTS to WAV bytes.
# This requires pydub.
try:
from pydub import AudioSegment
audio = AudioSegment.from_mp3(byte_io)
wav_byte_io = io.BytesIO()
audio.export(wav_byte_io, format="wav")
wav_byte_io.seek(0)
sample_rate, data = read_wav(wav_byte_io)
return (sample_rate, data)
except Exception as e:
print(f"Could not process audio for Gradio: {e}")
return None
# --- Main Processing Function for Gradio ---
# This function is the core of the app. It takes a webcam frame and returns
# updates for all the output components.
def process_live_frame(frame):
"""
Takes a single frame from the Gradio webcam input, processes it,
and returns the processed frame, status text, and any audio alerts.
"""
if frame is None:
# Return default values if frame is None
blank_image = np.zeros((480, 640, 3), dtype=np.uint8)
return blank_image, "Status: Inactive", None
# Process the frame using our existing detector
processed_frame, indicators, _ = detector.process_frame(frame)
drowsiness_level = indicators.get("drowsiness_level", "Awake")
lighting = indicators.get("lighting", "Good")
score = indicators.get("details", {}).get("Score", 0)
# Build the status text
status_text = f"Lighting: {lighting}\n"
if lighting == "Low":
status_text += "Detection paused due to low light."
else:
status_text += f"Status: {drowsiness_level}\nScore: {score:.2f}"
# Handle alerts
audio_output = None
if drowsiness_level != "Awake":
audio_data = alerter.trigger_alert(level=drowsiness_level)
if audio_data:
audio_output = process_audio_for_gradio(audio_data)
else:
alerter.reset_alert()
return processed_frame, status_text, audio_output
# --- UI Definition for the Live Detection Page ---
def create_live_detection_page():
"""Builds the Gradio UI components for the live detection tab."""
with gr.Blocks(theme=gr.themes.Default(primary_hue="blue", secondary_hue="blue")) as live_detection_page:
gr.Markdown("A live test using Gradio's webcam component.")
with gr.Row():
with gr.Column():
webcam_input = gr.Image(sources=["webcam"], streaming=True, label="Live Camera Feed")
with gr.Column():
processed_output = gr.Image(label="Processed Feed")
status_output = gr.Textbox(label="Live Status", lines=3, interactive=False)
# Audio player is now visible for debugging and user feedback.
audio_alert_output = gr.Audio(autoplay=True, visible=True, label="Alert Sound")
webcam_input.stream(
fn=process_live_frame,
inputs=[webcam_input],
outputs=[processed_output, status_output, audio_alert_output]
)
return live_detection_page
# --- UI Definition for the Home Page ---
def create_home_page():
"""Builds the Gradio UI components for the home/welcome tab."""
with gr.Blocks(theme=gr.themes.Default(primary_hue="blue", secondary_hue="blue")) as home_page:
gr.Markdown(
"""
<div align="center">
<img src="https://em-content.zobj.net/source/samsung/380/automobile_1f697.png" alt="Car Emoji" width="100"/>
<h1>Welcome to Drive Paddy!</h1>
<p><strong>Your Drowsiness Detection Assistant</strong></p>
</div>
---
### How It Works
This application uses your webcam to monitor for signs of drowsiness in real-time. Navigate to the **Live Detection** tab to begin.
- **Multi-Signal Analysis**: Detects eye closure, yawning, and head position.
- **AI-Powered Alerts**: Uses Gemini to generate dynamic audio warnings.
- **Live Feedback**: Provides instant visual feedback on the video stream and status panel.
"""
)
return home_page
# --- Combine Pages into a Tabbed Interface ---
app = gr.TabbedInterface(
[create_home_page(), create_live_detection_page()],
["Home", "Live Detection"]
)
# --- Launch the App ---
app.launch(debug=True)
|