driver-paddy / gradio_interface.py
Testys's picture
Update gradio_interface.py
83e4b57 verified
import os
import gradio as gr
import queue
import threading
from concurrent.futures import ThreadPoolExecutor
from ai_alert_generator import AIAlertGenerator, DrowsinessDetectionSystem
class GradioWebRTCInterface:
"""Enhanced Gradio interface with WebRTC support"""
def __init__(self):
self.detection_system = None
self.ai_alert_generator = None
self.processing = False
def initialize_system(self, gemini_key):
"""Initialize the detection system"""
try:
self.detection_system = DrowsinessDetectionSystem()
self.ai_alert_generator = AIAlertGenerator(gemini_key if gemini_key.strip() else None)
return "βœ… System initialized successfully!", "πŸš€ Ready for detection"
except Exception as e:
return f"❌ Error: {str(e)}", "❌ Initialization failed"
def process_video_stream(self, frame, gemini_key):
"""Process video stream"""
if self.detection_system is None:
self.detection_system = DrowsinessDetectionSystem()
self.ai_alert_generator = AIAlertGenerator(gemini_key if gemini_key.strip() else None)
try:
# Process frame
processed_frame, status_list, should_alert, metrics = self.detection_system.process_frame(frame)
# Generate alert if needed
alert_text = ""
alert_audio = None
if should_alert and metrics.get('indicators'):
alert_text = self.ai_alert_generator.generate_alert_text(
metrics['indicators'],
metrics.get('severity', 'medium')
)
# Create audio alert
try:
audio_file, _ = self.ai_alert_generator.create_audio_alert(alert_text)
alert_audio = audio_file
except Exception as e:
print(f"Audio generation error: {e}")
# Format status
status_text = "\n".join(status_list)
# Get logs
logs = self.detection_system.get_logs()
return processed_frame, status_text, alert_text, alert_audio, logs
except Exception as e:
error_msg = f"Processing error: {str(e)}"
return frame, error_msg, "", None, error_msg
def create_interface(self):
"""Create the Gradio interface with WebRTC support"""
with gr.Blocks(
title="πŸš— AI Driver Drowsiness Detection System",
theme=gr.themes.Soft(),
css="""
.alert-box {
background-color: #ffebee;
border: 2px solid #f44336;
border-radius: 8px;
padding: 10px;
}
.status-box {
background-color: #e8f5e8;
border: 2px solid #4caf50;
border-radius: 8px;
padding: 10px;
}
.metric-display {
font-family: 'Courier New', monospace;
font-size: 14px;
}
.header-text {
text-align: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 20px;
border-radius: 10px;
margin-bottom: 20px;
}
"""
) as interface:
gr.HTML("""
<div class="header-text">
<h1>πŸš— Drive Paddy/h1>
<p><strong>Real-time monitoring with OpenCV, Computer Vision & AI Alerts</strong></p>
</div>
""")
with gr.Tab("πŸŽ₯ Live Detection"):
with gr.Row():
with gr.Column(scale=2):
# WebRTC video input
webcam_options = gr.WebcamOptions(mirror=False)
video_input = gr.Video(
label="πŸ“Ή Camera Feed (WebRTC Streaming)",
sources=["webcam"],
streaming=True,
webcam_options=webcam_options,
height=480
)
# System controls
with gr.Row():
gemini_key = os.getenv("GEMINI_API_KEY")
init_btn = gr.Button("πŸš€ Initialize", variant="primary", scale=1)
with gr.Column(scale=1):
# System status
init_status = gr.Textbox(
label="πŸ”§ System Status",
interactive=False,
lines=2,
elem_classes=["status-box"]
)
# Detection metrics
current_status = gr.Textbox(
label="πŸ“Š Detection Metrics",
interactive=False,
lines=8,
elem_classes=["metric-display"]
)
# Alert display
alert_text_display = gr.Textbox(
label="🚨 Active Alert",
interactive=False,
lines=3,
elem_classes=["alert-box"]
)
# Audio alert output
alert_audio = gr.Audio(
label="πŸ”Š Alert Sound",
autoplay=True,
visible=True
)
# System logs panel
with gr.Row():
system_logs = gr.Textbox(
label="πŸ“ System Activity Log",
lines=6,
interactive=False,
elem_classes=["metric-display"]
)
with gr.Tab("βš™οΈ System Configuration"):
with gr.Row():
with gr.Column():
gr.Markdown("""
### πŸ”§ Detection Parameters
**Current OpenCV-based thresholds:**
- **Eye Aspect Ratio (EAR)**: < 0.20 for 15+ frames
- **Mouth Aspect Ratio (MAR)**: > 0.8 for 10+ frames
- **Head Nod Angle**: > 20Β° deviation for 8+ frames
- **Alert Cooldown**: 8 seconds between alerts
### 🎯 Detection Methods
- **Primary**: MediaPipe Face Mesh (if available)
- **Fallback**: OpenCV Haar Cascades
- **No external downloads**: Uses built-in OpenCV models
""")
with gr.Column():
gr.Markdown("""
### πŸ“‹ Easy Setup
**Install dependencies:**
```bash
pip install opencv-python gradio numpy scipy google-generativeai
# Optional for better detection:
pip install mediapipe
```
**No model downloads required!**
- Uses OpenCV's built-in face detection
- MediaPipe auto-detects if available
- Gemini API key is optional for AI alerts
""")
gr.Markdown("""
### πŸš€ Advanced Features
- **Real-time WebRTC Processing**: Low latency video streaming
- **Multi-modal Detection**: Eyes, mouth, and head pose analysis
- **AI-Powered Alerts**: Contextual voice messages via Gemini
- **Adaptive Fallback**: Graceful degradation without external models
- **Visual Feedback**: Live metrics overlay on video
- **Comprehensive Logging**: Detailed activity tracking
""")
with gr.Tab("πŸ“Š Detection Info"):
gr.Markdown("""
### πŸ‘οΈ Eye Aspect Ratio (EAR)
**How it works:**
- Calculates ratio of eye height to width
- Lower values indicate closed/closing eyes
- Triggers alert when consistently low
**Detection method:**
- **MediaPipe**: Uses precise eye landmarks
- **OpenCV**: Estimates from eye rectangles
### πŸ‘„ Mouth Aspect Ratio (MAR)
**Yawn detection:**
- Measures mouth opening relative to width
- Higher values indicate yawning
- Accounts for talking vs. yawning patterns
### πŸ“ Head Pose Estimation
**Nodding detection:**
- Tracks head tilt and position
- Detects forward head movement
- Uses nose-chin alignment for pose estimation
### 🧠 AI Alert Generation
**Smart alerts:**
- Context-aware messages via Gemini
- Severity-based escalation
- Fallback to audio beeps
- Cooldown prevents alert spam
""")
# Event handlers
init_btn.click(
fn=self.initialize_system,
inputs=[gemini_key],
outputs=[init_status, alert_text_display]
)
# WebRTC stream processing
video_input.stream(
fn=self.process_video_stream,
inputs=[video_input, gemini_key],
outputs=[video_input, current_status, alert_text_display, alert_audio, system_logs],
stream_every=0.1, # 10 FPS processing
show_progress=False
)
# Safety notice
gr.HTML("""
<div style="margin-top: 20px; padding: 15px; background: linear-gradient(135deg, #ffeaa7 0%, #fab1a0 100%); border-radius: 8px; border-left: 5px solid #e17055;">
<h3>⚠️ Important Safety Notice</h3>
<p><strong>This system is for demonstration and research purposes only.</strong></p>
<ul style="margin: 10px 0;">
<li><strong>Not a substitute</strong> for responsible driving practices</li>
<li><strong>Pull over safely</strong> if you feel drowsy while driving</li>
<li><strong>Ensure proper setup</strong>: good lighting, stable camera position</li>
<li><strong>Use as supplementary tool</strong> alongside other safety measures</li>
</ul>
<p style="margin-top: 15px;"><em>Always prioritize real-world driving safety over technology assistance.</em></p>
</div>
""")
return interface