File size: 11,785 Bytes
e65b3b4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128696e
e65b3b4
 
 
 
 
 
 
 
128696e
e65b3b4
 
 
 
83e4b57
e65b3b4
 
 
 
 
 
deb8709
e65b3b4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
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