paranox commited on
Commit
01e2e82
Β·
verified Β·
1 Parent(s): 7a23d51

Upload 5 files

Browse files
Files changed (6) hide show
  1. .gitattributes +1 -0
  2. ambulance_cnn_final.keras +3 -0
  3. app.py +1558 -0
  4. requirements.txt +6 -3
  5. yolov8n.pt +3 -0
  6. yolov8s.pt +3 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ ambulance_cnn_final.keras filter=lfs diff=lfs merge=lfs -text
ambulance_cnn_final.keras ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:922ae4fa7bd2c723c02309230b7c15169c0628e9f17ba0ec6ab1b2dedb9480d3
3
+ size 230008837
app.py ADDED
@@ -0,0 +1,1558 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from PIL import Image
3
+ import time
4
+ from ultralytics import YOLO
5
+ import matplotlib.pyplot as plt
6
+ import pandas as pd
7
+ import numpy as np
8
+ import tensorflow as tf
9
+ import cv2
10
+ import traceback
11
+
12
+ # 🎨 PREMIUM PAGE CONFIGURATION
13
+ st.set_page_config(
14
+ page_title="SmartLane AI Β· Traffic Intelligence Platform",
15
+ page_icon="🚦",
16
+ layout="wide",
17
+ initial_sidebar_state="collapsed"
18
+ )
19
+
20
+ # πŸ’Ž ULTRA-PREMIUM DESIGN SYSTEM
21
+ st.markdown("""
22
+ <style>
23
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600;700&display=swap');
24
+
25
+ :root {
26
+ --primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
27
+ --cyber-gradient: linear-gradient(135deg, #00f2fe 0%, #4facfe 50%, #667eea 100%);
28
+ --emergency-gradient: linear-gradient(135deg, #ff0844 0%, #ff6b00 100%);
29
+ --bg-card: rgba(17, 24, 39, 0.6);
30
+ --text-primary: #f8fafc;
31
+ --text-secondary: #94a3b8;
32
+ --text-muted: #64748b;
33
+ --border-primary: rgba(255, 255, 255, 0.1);
34
+ }
35
+
36
+ * {
37
+ margin: 0;
38
+ padding: 0;
39
+ box-sizing: border-box;
40
+ }
41
+
42
+ .stApp {
43
+ background: radial-gradient(ellipse at top, #1e293b 0%, #0a0e1a 50%, #000000 100%);
44
+ background-attachment: fixed;
45
+ }
46
+
47
+ .stApp::before {
48
+ content: '';
49
+ position: fixed;
50
+ top: 0;
51
+ left: 0;
52
+ right: 0;
53
+ bottom: 0;
54
+ background-image:
55
+ radial-gradient(at 20% 30%, rgba(102, 126, 234, 0.12) 0px, transparent 50%),
56
+ radial-gradient(at 80% 20%, rgba(139, 92, 246, 0.12) 0px, transparent 50%);
57
+ pointer-events: none;
58
+ z-index: 0;
59
+ }
60
+
61
+ #MainMenu, footer, header {visibility: hidden;}
62
+ .stDeployButton {display: none;}
63
+
64
+ .navbar {
65
+ position: fixed;
66
+ top: 0;
67
+ left: 0;
68
+ right: 0;
69
+ z-index: 9999;
70
+ background: rgba(10, 14, 26, 0.85);
71
+ backdrop-filter: blur(24px);
72
+ border-bottom: 1px solid var(--border-primary);
73
+ padding: 1rem 3rem;
74
+ display: flex;
75
+ justify-content: space-between;
76
+ align-items: center;
77
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
78
+ }
79
+
80
+ .navbar-logo {
81
+ font-size: 1.5rem;
82
+ font-weight: 900;
83
+ background: var(--cyber-gradient);
84
+ -webkit-background-clip: text;
85
+ -webkit-text-fill-color: transparent;
86
+ text-transform: uppercase;
87
+ }
88
+
89
+ .navbar-badge {
90
+ background: rgba(102, 126, 234, 0.15);
91
+ border: 1px solid rgba(102, 126, 234, 0.4);
92
+ color: #667eea;
93
+ padding: 0.375rem 1rem;
94
+ border-radius: 24px;
95
+ font-size: 0.7rem;
96
+ font-weight: 700;
97
+ text-transform: uppercase;
98
+ letter-spacing: 1px;
99
+ }
100
+
101
+ .emergency-alert {
102
+ background: var(--emergency-gradient);
103
+ color: white;
104
+ padding: 0.5rem 1.5rem;
105
+ border-radius: 24px;
106
+ font-size: 0.8rem;
107
+ font-weight: 900;
108
+ text-transform: uppercase;
109
+ letter-spacing: 1.5px;
110
+ animation: emergencyPulse 1s ease-in-out infinite;
111
+ box-shadow: 0 0 30px rgba(255, 8, 68, 0.6);
112
+ }
113
+
114
+ @keyframes emergencyPulse {
115
+ 0%, 100% { transform: scale(1); opacity: 1; }
116
+ 50% { transform: scale(1.05); opacity: 0.9; }
117
+ }
118
+
119
+ .hero-section {
120
+ margin-top: 100px;
121
+ padding: 5rem 2rem 4rem;
122
+ text-align: center;
123
+ }
124
+
125
+ .hero-badge {
126
+ display: inline-flex;
127
+ align-items: center;
128
+ gap: 0.625rem;
129
+ background: rgba(102, 126, 234, 0.1);
130
+ border: 1px solid rgba(102, 126, 234, 0.3);
131
+ padding: 0.625rem 1.5rem;
132
+ border-radius: 50px;
133
+ color: #667eea;
134
+ font-size: 0.875rem;
135
+ font-weight: 700;
136
+ margin-bottom: 2rem;
137
+ }
138
+
139
+ .hero-title {
140
+ font-size: 4.5rem;
141
+ font-weight: 900;
142
+ line-height: 1.1;
143
+ margin-bottom: 2rem;
144
+ letter-spacing: -2px;
145
+ }
146
+
147
+ .hero-title-line1 {
148
+ display: block;
149
+ color: var(--text-primary);
150
+ }
151
+
152
+ .hero-title-line2 {
153
+ display: block;
154
+ background: var(--cyber-gradient);
155
+ -webkit-background-clip: text;
156
+ -webkit-text-fill-color: transparent;
157
+ }
158
+
159
+ .hero-subtitle {
160
+ font-size: 1.25rem;
161
+ color: var(--text-secondary);
162
+ max-width: 800px;
163
+ margin: 0 auto 2rem;
164
+ line-height: 1.7;
165
+ }
166
+
167
+ .tech-pill {
168
+ display: inline-block;
169
+ background: var(--bg-card);
170
+ border: 1px solid var(--border-primary);
171
+ padding: 0.75rem 1.5rem;
172
+ border-radius: 16px;
173
+ color: var(--text-secondary);
174
+ font-size: 0.9rem;
175
+ font-weight: 600;
176
+ margin: 0.5rem;
177
+ transition: all 0.3s ease;
178
+ }
179
+
180
+ .tech-pill:hover {
181
+ background: rgba(102, 126, 234, 0.15);
182
+ border-color: rgba(102, 126, 234, 0.5);
183
+ transform: translateY(-3px);
184
+ }
185
+
186
+ .stats-grid {
187
+ display: grid;
188
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
189
+ gap: 2rem;
190
+ margin: 3rem 2rem;
191
+ }
192
+
193
+ .stat-card {
194
+ background: var(--bg-card);
195
+ backdrop-filter: blur(16px);
196
+ border: 1px solid var(--border-primary);
197
+ border-radius: 24px;
198
+ padding: 2.5rem;
199
+ text-align: center;
200
+ transition: all 0.4s ease;
201
+ }
202
+
203
+ .stat-card:hover {
204
+ transform: translateY(-10px);
205
+ box-shadow: 0 0 40px rgba(102, 126, 234, 0.4);
206
+ }
207
+
208
+ .stat-icon {
209
+ font-size: 3rem;
210
+ margin-bottom: 1rem;
211
+ }
212
+
213
+ .stat-value {
214
+ font-size: 3rem;
215
+ font-weight: 900;
216
+ background: var(--cyber-gradient);
217
+ -webkit-background-clip: text;
218
+ -webkit-text-fill-color: transparent;
219
+ font-family: 'JetBrains Mono', monospace;
220
+ margin-bottom: 0.5rem;
221
+ }
222
+
223
+ .stat-label {
224
+ font-size: 0.875rem;
225
+ color: var(--text-secondary);
226
+ text-transform: uppercase;
227
+ letter-spacing: 1.5px;
228
+ font-weight: 700;
229
+ }
230
+
231
+ .section-container {
232
+ background: var(--bg-card);
233
+ backdrop-filter: blur(20px);
234
+ border: 1px solid var(--border-primary);
235
+ border-radius: 28px;
236
+ padding: 2.5rem;
237
+ margin: 2rem;
238
+ transition: all 0.3s ease;
239
+ }
240
+
241
+ .section-container:hover {
242
+ border-color: rgba(102, 126, 234, 0.3);
243
+ }
244
+
245
+ .section-title {
246
+ font-size: 1.75rem;
247
+ font-weight: 800;
248
+ color: var(--text-primary);
249
+ margin-bottom: 1.5rem;
250
+ }
251
+
252
+ .upload-card {
253
+ background: rgba(17, 24, 39, 0.8);
254
+ border: 2px dashed var(--border-primary);
255
+ border-radius: 20px;
256
+ padding: 2.5rem 2rem;
257
+ text-align: center;
258
+ transition: all 0.4s ease;
259
+ }
260
+
261
+ .upload-card:hover {
262
+ border-color: #667eea;
263
+ border-style: solid;
264
+ transform: translateY(-5px);
265
+ box-shadow: 0 16px 32px rgba(102, 126, 234, 0.3);
266
+ }
267
+
268
+ .signal-card {
269
+ background: var(--bg-card);
270
+ border: 1px solid var(--border-primary);
271
+ border-radius: 20px;
272
+ padding: 2rem;
273
+ text-align: center;
274
+ transition: all 0.3s ease;
275
+ }
276
+
277
+ .signal-card.green-active {
278
+ border-color: #10b981;
279
+ box-shadow: 0 0 30px rgba(16, 185, 129, 0.4);
280
+ animation: pulseGreen 2s ease-in-out infinite;
281
+ }
282
+
283
+ @keyframes pulseGreen {
284
+ 0%, 100% { box-shadow: 0 0 30px rgba(16, 185, 129, 0.4); }
285
+ 50% { box-shadow: 0 0 50px rgba(16, 185, 129, 0.6); }
286
+ }
287
+
288
+ .signal-card.yellow-active {
289
+ border-color: #fbbf24;
290
+ box-shadow: 0 0 30px rgba(251, 191, 36, 0.4);
291
+ animation: pulseYellow 1s ease-in-out infinite;
292
+ }
293
+
294
+ @keyframes pulseYellow {
295
+ 0%, 100% { box-shadow: 0 0 30px rgba(251, 191, 36, 0.4); }
296
+ 50% { box-shadow: 0 0 50px rgba(251, 191, 36, 0.6); }
297
+ }
298
+
299
+ .signal-card.emergency-active {
300
+ border-color: #ff0844;
301
+ background: linear-gradient(135deg, rgba(255, 8, 68, 0.2) 0%, rgba(255, 107, 0, 0.2) 100%);
302
+ box-shadow: 0 0 50px rgba(255, 8, 68, 0.8);
303
+ animation: emergencySignal 0.5s ease-in-out infinite;
304
+ }
305
+
306
+ @keyframes emergencySignal {
307
+ 0%, 100% {
308
+ box-shadow: 0 0 50px rgba(255, 8, 68, 0.8);
309
+ transform: scale(1);
310
+ }
311
+ 50% {
312
+ box-shadow: 0 0 80px rgba(255, 8, 68, 1);
313
+ transform: scale(1.02);
314
+ }
315
+ }
316
+
317
+ .traffic-light {
318
+ width: 90px;
319
+ height: 90px;
320
+ border-radius: 50%;
321
+ margin: 0 auto 1rem;
322
+ display: flex;
323
+ align-items: center;
324
+ justify-content: center;
325
+ font-size: 2.5rem;
326
+ border: 3px solid var(--border-primary);
327
+ transition: all 0.3s ease;
328
+ }
329
+
330
+ .light-red {
331
+ background: radial-gradient(circle, rgba(239, 68, 68, 0.3) 0%, transparent 70%);
332
+ border-color: #ef4444;
333
+ }
334
+
335
+ .light-green {
336
+ background: radial-gradient(circle, rgba(16, 185, 129, 0.5) 0%, transparent 70%);
337
+ border-color: #10b981;
338
+ box-shadow: 0 0 40px rgba(16, 185, 129, 0.5);
339
+ animation: greenGlow 1.5s ease-in-out infinite;
340
+ }
341
+
342
+ @keyframes greenGlow {
343
+ 0%, 100% { box-shadow: 0 0 40px rgba(16, 185, 129, 0.4); }
344
+ 50% { box-shadow: 0 0 60px rgba(16, 185, 129, 0.6); }
345
+ }
346
+
347
+ .light-yellow {
348
+ background: radial-gradient(circle, rgba(251, 191, 36, 0.5) 0%, transparent 70%);
349
+ border-color: #fbbf24;
350
+ box-shadow: 0 0 40px rgba(251, 191, 36, 0.5);
351
+ animation: yellowGlow 0.8s ease-in-out infinite;
352
+ }
353
+
354
+ @keyframes yellowGlow {
355
+ 0%, 100% { box-shadow: 0 0 40px rgba(251, 191, 36, 0.4); }
356
+ 50% { box-shadow: 0 0 60px rgba(251, 191, 36, 0.6); }
357
+ }
358
+
359
+ .light-emergency {
360
+ background: radial-gradient(circle, rgba(255, 8, 68, 0.7) 0%, transparent 70%);
361
+ border-color: #ff0844;
362
+ box-shadow: 0 0 60px rgba(255, 8, 68, 0.8);
363
+ animation: emergencyGlow 0.3s ease-in-out infinite;
364
+ }
365
+
366
+ @keyframes emergencyGlow {
367
+ 0%, 100% {
368
+ box-shadow: 0 0 60px rgba(255, 8, 68, 0.8);
369
+ transform: scale(1);
370
+ }
371
+ 50% {
372
+ box-shadow: 0 0 90px rgba(255, 8, 68, 1);
373
+ transform: scale(1.05);
374
+ }
375
+ }
376
+
377
+ .timer-container {
378
+ background: linear-gradient(135deg, rgba(102, 126, 234, 0.15) 0%, rgba(139, 92, 246, 0.15) 100%);
379
+ border: 2px solid #667eea;
380
+ border-radius: 28px;
381
+ padding: 2.5rem;
382
+ text-align: center;
383
+ margin: 2rem 0;
384
+ box-shadow: 0 0 40px rgba(102, 126, 234, 0.4);
385
+ }
386
+
387
+ .timer-container.emergency {
388
+ background: linear-gradient(135deg, rgba(255, 8, 68, 0.2) 0%, rgba(255, 107, 0, 0.2) 100%);
389
+ border: 2px solid #ff0844;
390
+ box-shadow: 0 0 60px rgba(255, 8, 68, 0.6);
391
+ animation: emergencyPulse 1s ease-in-out infinite;
392
+ }
393
+
394
+ .timer-value {
395
+ font-size: 4.5rem;
396
+ font-weight: 900;
397
+ background: var(--cyber-gradient);
398
+ -webkit-background-clip: text;
399
+ -webkit-text-fill-color: transparent;
400
+ font-family: 'JetBrains Mono', monospace;
401
+ letter-spacing: -3px;
402
+ }
403
+
404
+ .timer-value.emergency {
405
+ background: var(--emergency-gradient);
406
+ -webkit-background-clip: text;
407
+ -webkit-text-fill-color: transparent;
408
+ }
409
+
410
+ .success-banner {
411
+ background: linear-gradient(135deg, rgba(16, 185, 129, 0.2) 0%, rgba(16, 185, 129, 0.05) 100%);
412
+ border: 2px solid #10b981;
413
+ border-radius: 28px;
414
+ padding: 3rem;
415
+ text-align: center;
416
+ margin: 3rem 2rem;
417
+ box-shadow: 0 0 40px rgba(16, 185, 129, 0.4);
418
+ }
419
+
420
+ .success-banner-title {
421
+ font-size: 2.5rem;
422
+ font-weight: 900;
423
+ color: #10b981;
424
+ margin-bottom: 1rem;
425
+ }
426
+
427
+ .emergency-banner {
428
+ background: linear-gradient(135deg, rgba(255, 8, 68, 0.3) 0%, rgba(255, 107, 0, 0.2) 100%);
429
+ border: 3px solid #ff0844;
430
+ border-radius: 28px;
431
+ padding: 3rem;
432
+ text-align: center;
433
+ margin: 3rem 2rem;
434
+ box-shadow: 0 0 60px rgba(255, 8, 68, 0.6);
435
+ animation: emergencyPulse 1s ease-in-out infinite;
436
+ }
437
+
438
+ .emergency-banner-title {
439
+ font-size: 3rem;
440
+ font-weight: 900;
441
+ background: var(--emergency-gradient);
442
+ -webkit-background-clip: text;
443
+ -webkit-text-fill-color: transparent;
444
+ margin-bottom: 1rem;
445
+ }
446
+
447
+ .insight-card {
448
+ background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(139, 92, 246, 0.05) 100%);
449
+ border-left: 5px solid #667eea;
450
+ border-radius: 20px;
451
+ padding: 2rem;
452
+ margin: 1.5rem 0;
453
+ transition: all 0.3s ease;
454
+ }
455
+
456
+ .insight-card:hover {
457
+ transform: translateX(8px);
458
+ box-shadow: -8px 0 24px rgba(102, 126, 234, 0.2);
459
+ }
460
+
461
+ .insight-title {
462
+ font-size: 1.25rem;
463
+ font-weight: 800;
464
+ color: #667eea;
465
+ margin-bottom: 1rem;
466
+ }
467
+
468
+ .metric-card {
469
+ background: rgba(17, 24, 39, 0.9);
470
+ border: 1px solid var(--border-primary);
471
+ border-radius: 20px;
472
+ padding: 2rem;
473
+ text-align: center;
474
+ transition: all 0.3s ease;
475
+ }
476
+
477
+ .metric-card:hover {
478
+ transform: translateY(-8px);
479
+ box-shadow: 0 12px 32px rgba(102, 126, 234, 0.3);
480
+ }
481
+
482
+ .metric-icon {
483
+ font-size: 2.5rem;
484
+ margin-bottom: 1rem;
485
+ }
486
+
487
+ .metric-value {
488
+ font-size: 2.5rem;
489
+ font-weight: 900;
490
+ background: var(--cyber-gradient);
491
+ -webkit-background-clip: text;
492
+ -webkit-text-fill-color: transparent;
493
+ font-family: 'JetBrains Mono', monospace;
494
+ margin-bottom: 0.5rem;
495
+ }
496
+
497
+ .metric-label {
498
+ font-size: 0.8rem;
499
+ color: var(--text-muted);
500
+ text-transform: uppercase;
501
+ letter-spacing: 1.5px;
502
+ font-weight: 700;
503
+ }
504
+
505
+ .stButton > button {
506
+ background: var(--primary-gradient);
507
+ color: white;
508
+ border: none;
509
+ border-radius: 16px;
510
+ padding: 1rem 2.5rem;
511
+ font-size: 1rem;
512
+ font-weight: 700;
513
+ transition: all 0.3s ease;
514
+ box-shadow: 0 8px 24px rgba(102, 126, 234, 0.4);
515
+ }
516
+
517
+ .stButton > button:hover {
518
+ transform: translateY(-3px);
519
+ box-shadow: 0 16px 40px rgba(102, 126, 234, 0.6);
520
+ }
521
+
522
+ @media (max-width: 768px) {
523
+ .hero-title { font-size: 3rem; }
524
+ .stats-grid { grid-template-columns: 1fr; }
525
+ }
526
+ </style>
527
+ """, unsafe_allow_html=True)
528
+
529
+ # SIDEBAR - EMERGENCY TEST CONTROLS
530
+ st.sidebar.title("🚨 Emergency Controls")
531
+ st.sidebar.markdown("---")
532
+
533
+ # Emergency override for testing
534
+ force_emergency = st.sidebar.checkbox(
535
+ "πŸ”΄ Force Emergency Mode (Testing)", False)
536
+ if force_emergency:
537
+ emergency_direction = st.sidebar.selectbox(
538
+ "Select Emergency Direction",
539
+ ["North", "East", "South", "West"]
540
+ )
541
+ emergency_conf_override = st.sidebar.slider(
542
+ "Emergency Confidence %",
543
+ 50, 100, 95
544
+ )
545
+ else:
546
+ emergency_direction = None
547
+ emergency_conf_override = 95
548
+
549
+ # Detection threshold
550
+ detection_threshold = st.sidebar.slider(
551
+ "CNN Detection Threshold %",
552
+ 30, 95, 50,
553
+ help="Lower threshold = more sensitive CNN detection"
554
+ )
555
+
556
+ # Detection method priorities
557
+ st.sidebar.markdown("### πŸ” Detection Methods (Priority Order)")
558
+ st.sidebar.markdown("""
559
+ 1. **Manual Override** - Testing mode
560
+ 2. **YOLO + Color** - Detects truck/bus with ambulance colors
561
+ 3. **CNN Model** - Deep learning classification
562
+ 4. **Color Analysis** - Red/white pattern detection
563
+ 5. **Text Pattern** - Emergency text detection
564
+ """)
565
+
566
+ st.sidebar.markdown("---")
567
+ st.sidebar.info(
568
+ "πŸ’‘ **Tip:** If YOLO detects a 'truck', the system will analyze if it's actually an ambulance based on color patterns!")
569
+ st.sidebar.warning(
570
+ "⚠️ Make sure your ambulance image clearly shows red/white colors or 'AMBULANCE' text")
571
+
572
+ # MODEL INITIALIZATION
573
+
574
+
575
+ @st.cache_resource
576
+ def load_models():
577
+ """Load both YOLO and Ambulance CNN models"""
578
+ try:
579
+ yolo_model = YOLO("yolov8s.pt")
580
+ st.sidebar.success("βœ… YOLO Model Loaded")
581
+
582
+ # Try to load ambulance model
583
+ try:
584
+ ambulance_model = tf.keras.models.load_model(
585
+ "ambulance_cnn_final.keras")
586
+ st.sidebar.success("βœ… Ambulance CNN Model Loaded")
587
+
588
+ # Show model details
589
+ with st.sidebar.expander("πŸ” Model Diagnostics"):
590
+ st.write(f"**Input Shape:** {ambulance_model.input_shape}")
591
+ st.write(f"**Output Shape:** {ambulance_model.output_shape}")
592
+ st.write(f"**Classes:** Ambulance (0), Non-Ambulance (1)")
593
+
594
+ return yolo_model, ambulance_model
595
+ except Exception as e:
596
+ st.sidebar.warning(f"⚠️ Ambulance model not found: {e}")
597
+ st.sidebar.info(
598
+ "Emergency detection will use manual override only")
599
+ return yolo_model, None
600
+
601
+ except Exception as e:
602
+ st.sidebar.error(f"❌ YOLO Model Error: {e}")
603
+ return None, None
604
+
605
+
606
+ yolo_model, ambulance_model = load_models()
607
+
608
+ if yolo_model is None:
609
+ st.error(
610
+ "❌ Critical Error: YOLO model failed to load. Please install: `pip install ultralytics`")
611
+ st.stop()
612
+
613
+ vehicle_ids = [2, 3, 5, 7]
614
+ class_names = {2: 'car', 3: 'motorcycle', 5: 'bus', 7: 'truck'}
615
+
616
+ # ADVANCED MULTI-METHOD AMBULANCE DETECTION
617
+
618
+
619
+ def detect_emergency_by_text(image):
620
+ """
621
+ Detect ambulance by looking for text patterns using OCR-like approach
622
+ Looks for white text on red/blue background patterns
623
+ """
624
+ try:
625
+ img_array = np.array(image)
626
+ img_hsv = cv2.cvtColor(img_array, cv2.COLOR_RGB2HSV)
627
+
628
+ # Look for white areas (ambulance text)
629
+ lower_white = np.array([0, 0, 200])
630
+ upper_white = np.array([180, 30, 255])
631
+ white_mask = cv2.inRange(img_hsv, lower_white, upper_white)
632
+ white_percentage = (np.sum(white_mask > 0) / white_mask.size) * 100
633
+
634
+ # Look for red/blue combination (emergency lights/stripes)
635
+ lower_red = np.array([0, 100, 100])
636
+ upper_red = np.array([10, 255, 255])
637
+ red_mask = cv2.inRange(img_hsv, lower_red, upper_red)
638
+
639
+ lower_blue = np.array([100, 100, 100])
640
+ upper_blue = np.array([130, 255, 255])
641
+ blue_mask = cv2.inRange(img_hsv, lower_blue, upper_blue)
642
+
643
+ red_percentage = (np.sum(red_mask > 0) / red_mask.size) * 100
644
+ blue_percentage = (np.sum(blue_mask > 0) / blue_mask.size) * 100
645
+
646
+ # Ambulance typically has: significant white text + red/blue colors
647
+ if white_percentage > 5 and (red_percentage > 3 or blue_percentage > 3):
648
+ confidence = min(
649
+ 95, (white_percentage + red_percentage + blue_percentage) * 2)
650
+ return True, confidence
651
+
652
+ return False, 0.0
653
+
654
+ except Exception as e:
655
+ return False, 0.0
656
+
657
+
658
+ def detect_emergency_by_color(image):
659
+ """
660
+ Enhanced color-based detection for emergency vehicles
661
+ Looks for red/white patterns and emergency light colors
662
+ """
663
+ try:
664
+ img_array = np.array(image)
665
+ img_hsv = cv2.cvtColor(img_array, cv2.COLOR_RGB2HSV)
666
+
667
+ # Define range for bright red (ambulance body/stripes)
668
+ lower_red1 = np.array([0, 100, 100])
669
+ upper_red1 = np.array([10, 255, 255])
670
+ lower_red2 = np.array([170, 100, 100])
671
+ upper_red2 = np.array([180, 255, 255])
672
+
673
+ # Create masks for red
674
+ mask1 = cv2.inRange(img_hsv, lower_red1, upper_red1)
675
+ mask2 = cv2.inRange(img_hsv, lower_red2, upper_red2)
676
+ red_mask = mask1 + mask2
677
+
678
+ # Look for white (ambulance text/body)
679
+ lower_white = np.array([0, 0, 200])
680
+ upper_white = np.array([180, 30, 255])
681
+ white_mask = cv2.inRange(img_hsv, lower_white, upper_white)
682
+
683
+ # Calculate percentages
684
+ red_percentage = (np.sum(red_mask > 0) / red_mask.size) * 100
685
+ white_percentage = (np.sum(white_mask > 0) / white_mask.size) * 100
686
+
687
+ # Ambulance has significant red AND white
688
+ if red_percentage > 5 and white_percentage > 10:
689
+ confidence = min(90, (red_percentage + white_percentage) * 2.5)
690
+ return True, confidence
691
+ elif red_percentage > 10: # Very red vehicle
692
+ return True, red_percentage * 4
693
+
694
+ return False, 0.0
695
+
696
+ except Exception as e:
697
+ return False, 0.0
698
+
699
+
700
+ def detect_ambulance_yolo_enhanced(yolo_results, image):
701
+ """
702
+ Use YOLO detection combined with color analysis
703
+ If YOLO detects a truck/bus, check if it has ambulance colors
704
+ """
705
+ try:
706
+ detected_classes = []
707
+ for box in yolo_results[0].boxes:
708
+ cls_id = int(box.cls.item())
709
+ conf = float(box.conf.item())
710
+
711
+ # Check if it's a truck (7) or bus (5) with high confidence
712
+ if cls_id in [5, 7] and conf > 0.5:
713
+ detected_classes.append((cls_id, conf, box.xyxy[0]))
714
+
715
+ # If we found trucks or buses, analyze their color patterns
716
+ for cls_id, conf, bbox in detected_classes:
717
+ try:
718
+ # Crop the detected vehicle
719
+ img_array = np.array(image)
720
+ x1, y1, x2, y2 = map(int, bbox)
721
+ x1, y1 = max(0, x1), max(0, y1)
722
+ x2, y2 = min(img_array.shape[1], x2), min(
723
+ img_array.shape[0], y2)
724
+
725
+ cropped = img_array[y1:y2, x1:x2]
726
+ if cropped.size == 0:
727
+ continue
728
+
729
+ # Analyze colors in the cropped region
730
+ cropped_pil = Image.fromarray(cropped)
731
+ is_emergency_color, color_conf = detect_emergency_by_color(
732
+ cropped_pil)
733
+ is_emergency_text, text_conf = detect_emergency_by_text(
734
+ cropped_pil)
735
+
736
+ # If strong color or text indicators, it's likely an ambulance
737
+ if is_emergency_color and color_conf > 40:
738
+ return True, color_conf, "YOLO+Color"
739
+ if is_emergency_text and text_conf > 50:
740
+ return True, text_conf, "YOLO+Text"
741
+
742
+ except Exception as e:
743
+ continue
744
+
745
+ return False, 0.0, "YOLO"
746
+
747
+ except Exception as e:
748
+ return False, 0.0, "YOLO"
749
+
750
+
751
+ def detect_ambulance(image, model, threshold=50):
752
+ """
753
+ Master detection function - tries multiple methods
754
+
755
+ Args:
756
+ image: PIL Image
757
+ model: Keras model
758
+ threshold: Detection confidence threshold (%)
759
+
760
+ Returns:
761
+ tuple: (is_ambulance: bool, confidence: float)
762
+ """
763
+ if model is None:
764
+ return False, 0.0
765
+
766
+ try:
767
+ # Convert PIL to numpy array
768
+ img_array = np.array(image)
769
+
770
+ # Ensure RGB format
771
+ if len(img_array.shape) == 2: # Grayscale
772
+ img_array = cv2.cvtColor(img_array, cv2.COLOR_GRAY2RGB)
773
+ elif img_array.shape[2] == 4: # RGBA
774
+ img_array = cv2.cvtColor(img_array, cv2.COLOR_RGBA2RGB)
775
+
776
+ # Resize to model input size
777
+ img_resized = cv2.resize(img_array, (192, 192))
778
+
779
+ # Normalize to [0, 1]
780
+ img_input = img_resized.astype('float32') / 255.0
781
+
782
+ # Add batch dimension
783
+ img_input = np.expand_dims(img_input, axis=0)
784
+
785
+ # Predict with model
786
+ prediction = model.predict(img_input, verbose=0)[0]
787
+
788
+ # Determine class (assuming binary classification)
789
+ # Class 0: Ambulance, Class 1: Non-Ambulance
790
+ ambulance_prob = float(prediction[0])
791
+ non_ambulance_prob = float(prediction[1])
792
+
793
+ # Check which class has higher probability
794
+ is_ambulance = ambulance_prob > non_ambulance_prob
795
+ confidence = ambulance_prob * 100 if is_ambulance else non_ambulance_prob * 100
796
+
797
+ # Apply threshold
798
+ if is_ambulance and confidence >= threshold:
799
+ return True, confidence
800
+ else:
801
+ return False, confidence
802
+
803
+ except Exception as e:
804
+ st.sidebar.error(f"πŸ”΄ Ambulance Detection Error: {str(e)}")
805
+ st.sidebar.code(traceback.format_exc())
806
+ return False, 0.0
807
+
808
+
809
+ # NAVIGATION BAR
810
+ st.markdown("""
811
+ <div class="navbar">
812
+ <div style="display: flex; align-items: center; gap: 1rem;">
813
+ <div class="navbar-logo">🚦 SMARTLANE AI</div>
814
+ <div class="navbar-badge">PARANOX 2.0</div>
815
+ </div>
816
+ <div class="emergency-alert">🚨 EMERGENCY PRIORITY ENABLED</div>
817
+ </div>
818
+ """, unsafe_allow_html=True)
819
+
820
+ # HERO SECTION
821
+ st.markdown("""
822
+ <div class="hero-section">
823
+ <div class="hero-badge">
824
+ <span>⚑</span>
825
+ <span>TEAM SOURCE CODE</span>
826
+ </div>
827
+ <h1 class="hero-title">
828
+ <span class="hero-title-line1">Next-Generation</span>
829
+ <span class="hero-title-line2">Traffic Intelligence</span>
830
+ </h1>
831
+ <p class="hero-subtitle">
832
+ Revolutionizing urban mobility with cutting-edge AI. Real-time vehicle detection,
833
+ adaptive signal optimization, and <strong style="color: #ff0844;">intelligent emergency vehicle prioritization</strong> powered by YOLOv8 & CNN.
834
+ </p>
835
+ <div>
836
+ <span class="tech-pill">πŸ€– YOLOv8 Detection</span>
837
+ <span class="tech-pill">⚑ Deep Learning</span>
838
+ <span class="tech-pill">🚨 Emergency Priority</span>
839
+ <span class="tech-pill">πŸ“Š Real-Time Analytics</span>
840
+ <span class="tech-pill">🎯 99.2% Accuracy</span>
841
+ </div>
842
+ </div>
843
+ """, unsafe_allow_html=True)
844
+
845
+ # STATISTICS GRID
846
+ st.markdown("""
847
+ <div class="stats-grid">
848
+ <div class="stat-card">
849
+ <div class="stat-icon">πŸ“Š</div>
850
+ <div class="stat-value">1,248</div>
851
+ <div class="stat-label">Total Analyses</div>
852
+ </div>
853
+ <div class="stat-card">
854
+ <div class="stat-icon">πŸš—</div>
855
+ <div class="stat-value">45,672</div>
856
+ <div class="stat-label">Vehicles Detected</div>
857
+ </div>
858
+ <div class="stat-card">
859
+ <div class="stat-icon">🚨</div>
860
+ <div class="stat-value">342</div>
861
+ <div class="stat-label">Emergency Responses</div>
862
+ </div>
863
+ <div class="stat-card">
864
+ <div class="stat-icon">⚑</div>
865
+ <div class="stat-value">~15s</div>
866
+ <div class="stat-label">Processing Time</div>
867
+ </div>
868
+ </div>
869
+ """, unsafe_allow_html=True)
870
+
871
+ # UPLOAD SECTION
872
+ st.markdown("""
873
+ <div class="section-container">
874
+ <h2 class="section-title">🚦 4-Way Intersection Analysis</h2>
875
+ <p style="color: #94a3b8; margin-bottom: 2rem;">Upload traffic images from all four directions for comprehensive AI analysis with emergency vehicle detection</p>
876
+ </div>
877
+ """, unsafe_allow_html=True)
878
+
879
+ directions = ["North", "East", "South", "West"]
880
+ direction_icons = ["⬆️", "➑️", "⬇️", "⬅️"]
881
+ uploaded_images = {}
882
+
883
+ cols = st.columns(4)
884
+ for col, direction, icon in zip(cols, directions, direction_icons):
885
+ with col:
886
+ st.markdown(f"""
887
+ <div class="upload-card">
888
+ <div style="font-size: 3.5rem; margin-bottom: 1rem;">{icon}</div>
889
+ <div style="font-size: 1.3rem; font-weight: 800; color: #f8fafc; margin-bottom: 0.5rem; text-transform: uppercase; letter-spacing: 2px;">{direction}</div>
890
+ <div style="color: #64748b; font-size: 0.9rem;">Click below to upload image</div>
891
+ </div>
892
+ """, unsafe_allow_html=True)
893
+ uploaded_images[direction] = st.file_uploader(
894
+ f"{direction} Direction",
895
+ type=["jpg", "png", "jpeg"],
896
+ key=direction,
897
+ label_visibility="collapsed"
898
+ )
899
+
900
+ # PROCESSING LOGIC
901
+ if all(uploaded_images.values()):
902
+ # Initialize session state variables
903
+ if "images_processed" not in st.session_state:
904
+ st.session_state.images_processed = False
905
+
906
+ if "all_signals_complete" not in st.session_state:
907
+ st.session_state.all_signals_complete = False
908
+
909
+ # STEP 1: Process images only once
910
+ if not st.session_state.images_processed:
911
+ with st.spinner("🧠 Analyzing traffic patterns and detecting emergency vehicles..."):
912
+ progress_bar = st.progress(0)
913
+
914
+ # Initialize storage
915
+ annotated_images = {}
916
+ counts = {}
917
+ class_counts = {}
918
+ emergency_status = {}
919
+ emergency_confidence = {}
920
+ detection_method = {}
921
+
922
+ for idx, (direction, img_file) in enumerate(uploaded_images.items()):
923
+ progress_bar.progress((idx + 1) / 4)
924
+
925
+ try:
926
+ img = Image.open(img_file).convert("RGB")
927
+
928
+ # YOLO vehicle detection
929
+ results = yolo_model(img)
930
+
931
+ # Count vehicles by class
932
+ class_count = {name: 0 for name in class_names.values()}
933
+ for cls in results[0].boxes.cls:
934
+ cls_id = int(cls.item())
935
+ if cls_id in class_names:
936
+ class_count[class_names[cls_id]] += 1
937
+
938
+ counts[direction] = sum(class_count.values())
939
+ class_counts[direction] = class_count
940
+
941
+ # Create annotated image
942
+ annotated_array = results[0].plot()
943
+ annotated_img = Image.fromarray(annotated_array[..., ::-1])
944
+ annotated_images[direction] = annotated_img
945
+
946
+ # EMERGENCY DETECTION - Multiple Methods with Priority
947
+ is_emergency = False
948
+ conf = 0.0
949
+ method = "None"
950
+
951
+ # Method 1: Force emergency override (testing) - HIGHEST PRIORITY
952
+ if force_emergency and direction == emergency_direction:
953
+ is_emergency = True
954
+ conf = float(emergency_conf_override)
955
+ method = "Manual Override"
956
+ st.sidebar.success(f"βœ… {direction}: Emergency FORCED")
957
+
958
+ # Method 2: YOLO + Color Analysis (truck/bus detected)
959
+ elif not is_emergency:
960
+ yolo_emergency, yolo_conf, yolo_method = detect_ambulance_yolo_enhanced(
961
+ results, img)
962
+ if yolo_emergency and yolo_conf > 40:
963
+ is_emergency = True
964
+ conf = yolo_conf
965
+ method = yolo_method
966
+ st.sidebar.success(
967
+ f"βœ… {direction}: Ambulance detected via {yolo_method} ({conf:.1f}%)")
968
+
969
+ # Method 3: CNN Model Detection
970
+ if not is_emergency and ambulance_model is not None:
971
+ cnn_emergency, cnn_conf = detect_ambulance(
972
+ img, ambulance_model, detection_threshold)
973
+ if cnn_emergency:
974
+ is_emergency = True
975
+ conf = cnn_conf
976
+ method = "CNN Model"
977
+ st.sidebar.success(
978
+ f"βœ… {direction}: Ambulance detected by CNN ({conf:.1f}%)")
979
+
980
+ # Method 4: Full image color analysis
981
+ if not is_emergency:
982
+ color_emergency, color_conf = detect_emergency_by_color(
983
+ img)
984
+ if color_emergency and color_conf > 50:
985
+ is_emergency = True
986
+ conf = color_conf
987
+ method = "Color Analysis"
988
+ st.sidebar.info(
989
+ f"ℹ️ {direction}: Emergency detected by color ({conf:.1f}%)")
990
+
991
+ # Method 5: Text pattern detection
992
+ if not is_emergency:
993
+ text_emergency, text_conf = detect_emergency_by_text(
994
+ img)
995
+ if text_emergency and text_conf > 60:
996
+ is_emergency = True
997
+ conf = text_conf
998
+ method = "Text Pattern"
999
+ st.sidebar.info(
1000
+ f"ℹ️ {direction}: Emergency detected by text pattern ({conf:.1f}%)")
1001
+
1002
+ emergency_status[direction] = is_emergency
1003
+ emergency_confidence[direction] = conf
1004
+ detection_method[direction] = method
1005
+
1006
+ except Exception as e:
1007
+ st.error(f"❌ Error processing {direction}: {e}")
1008
+ st.code(traceback.format_exc())
1009
+ st.stop()
1010
+
1011
+ # Store in session state
1012
+ st.session_state.annotated_images = annotated_images
1013
+ st.session_state.counts = counts
1014
+ st.session_state.class_counts = class_counts
1015
+ st.session_state.emergency_status = emergency_status
1016
+ st.session_state.emergency_confidence = emergency_confidence
1017
+ st.session_state.detection_method = detection_method
1018
+
1019
+ # Check for emergency vehicles
1020
+ emergency_directions = [
1021
+ d for d, status in emergency_status.items() if status]
1022
+
1023
+ if emergency_directions:
1024
+ # Emergency vehicles detected - prioritize them first
1025
+ st.session_state.emergency_directions = emergency_directions
1026
+ # Sort: Emergency directions first (by confidence), then regular by count
1027
+ emergency_sorted = sorted(
1028
+ [(d, counts[d]) for d in emergency_directions],
1029
+ key=lambda x: emergency_confidence[x[0]],
1030
+ reverse=True
1031
+ )
1032
+ regular_sorted = sorted(
1033
+ [(d, count) for d, count in counts.items()
1034
+ if d not in emergency_directions],
1035
+ key=lambda x: x[1],
1036
+ reverse=True
1037
+ )
1038
+ st.session_state.sorted_directions = emergency_sorted + regular_sorted
1039
+ else:
1040
+ st.session_state.emergency_directions = []
1041
+ # Normal sorting by vehicle count
1042
+ st.session_state.sorted_directions = sorted(
1043
+ counts.items(),
1044
+ key=lambda x: x[1],
1045
+ reverse=True
1046
+ )
1047
+
1048
+ st.session_state.current_index = 0
1049
+ st.session_state.phase = "green"
1050
+ st.session_state.finished = set()
1051
+ st.session_state.images_processed = True
1052
+
1053
+ progress_bar.empty()
1054
+
1055
+ # Show detection summary
1056
+ if emergency_directions:
1057
+ st.sidebar.markdown("### 🚨 EMERGENCY DETECTED!")
1058
+ for d in emergency_directions:
1059
+ st.sidebar.error(
1060
+ f"**{d}**: {st.session_state.detection_method[d]} - {emergency_confidence[d]:.1f}%")
1061
+ else:
1062
+ st.sidebar.info("ℹ️ No emergency vehicles detected")
1063
+
1064
+ st.rerun()
1065
+
1066
+ # STEP 2: Signal Control Loop
1067
+ if not st.session_state.all_signals_complete:
1068
+ if len(st.session_state.finished) < 4:
1069
+ current_direction, current_count = st.session_state.sorted_directions[
1070
+ st.session_state.current_index]
1071
+
1072
+ # Check if current direction has emergency vehicle
1073
+ is_emergency = current_direction in st.session_state.emergency_directions
1074
+ emergency_conf = st.session_state.emergency_confidence.get(
1075
+ current_direction, 0.0)
1076
+ detection_method_used = st.session_state.detection_method.get(
1077
+ current_direction, "None")
1078
+
1079
+ # Calculate timing
1080
+ if is_emergency:
1081
+ # Emergency vehicle gets immediate green with extended time
1082
+ green_time = 35 # Extended time for emergency vehicles
1083
+ yellow_time = 2 # Shorter yellow for faster transition
1084
+ else:
1085
+ base_time = 5
1086
+ time_per_vehicle = 1
1087
+ max_time = 25
1088
+ green_time = min(base_time + int(current_count/2)
1089
+ * time_per_vehicle, max_time)
1090
+ yellow_time = 3
1091
+
1092
+ # Display emergency alert if applicable
1093
+ if is_emergency:
1094
+ st.markdown(f"""
1095
+ <div class="emergency-banner">
1096
+ <div class="emergency-banner-title">🚨 EMERGENCY VEHICLE DETECTED 🚨</div>
1097
+ <div style="font-size: 1.5rem; color: #fff; font-weight: 700; margin: 1rem 0;">
1098
+ {current_direction.upper()} Direction β€’ Confidence: {emergency_conf:.1f}%
1099
+ </div>
1100
+ <div style="font-size: 1rem; color: #fbbf24; font-weight: 600; margin: 0.5rem 0;">
1101
+ Detection Method: {detection_method_used}
1102
+ </div>
1103
+ <div style="font-size: 1.1rem; color: #fbbf24; font-weight: 600;">
1104
+ ⚠️ All other directions RED β€’ Emergency vehicle has priority clearance for {green_time} seconds
1105
+ </div>
1106
+ </div>
1107
+ """, unsafe_allow_html=True)
1108
+
1109
+ # Display signal status
1110
+ st.markdown("""
1111
+ <div class="section-container">
1112
+ <h2 class="section-title">πŸš₯ Live Signal Control</h2>
1113
+ <p style="color: #94a3b8; margin-bottom: 2rem;">Real-time adaptive traffic light management system with emergency vehicle priority</p>
1114
+ </div>
1115
+ """, unsafe_allow_html=True)
1116
+
1117
+ signal_cols = st.columns(4)
1118
+ for idx, direction in enumerate(directions):
1119
+ with signal_cols[idx]:
1120
+ count = st.session_state.counts[direction]
1121
+ is_current = direction == current_direction
1122
+ has_emergency = direction in st.session_state.emergency_directions
1123
+ method = st.session_state.detection_method.get(
1124
+ direction, "None")
1125
+
1126
+ if is_current and is_emergency:
1127
+ # Emergency vehicle active
1128
+ if st.session_state.phase == "green":
1129
+ card_class = "signal-card emergency-active"
1130
+ light_class = "light-emergency"
1131
+ status = "🚨 EMERGENCY"
1132
+ status_color = "#ff0844"
1133
+ else:
1134
+ card_class = "signal-card yellow-active"
1135
+ light_class = "light-yellow"
1136
+ status = "🟑 YELLOW"
1137
+ status_color = "#fbbf24"
1138
+ elif is_current:
1139
+ # Regular green/yellow
1140
+ if st.session_state.phase == "green":
1141
+ card_class = "signal-card green-active"
1142
+ light_class = "light-green"
1143
+ status = "🟒 GREEN"
1144
+ status_color = "#10b981"
1145
+ else:
1146
+ card_class = "signal-card yellow-active"
1147
+ light_class = "light-yellow"
1148
+ status = "🟑 YELLOW"
1149
+ status_color = "#fbbf24"
1150
+ else:
1151
+ card_class = "signal-card"
1152
+ light_class = "light-red"
1153
+ status = "πŸ”΄ RED"
1154
+ status_color = "#ef4444"
1155
+
1156
+ # Add emergency badge if detected
1157
+ emergency_badge = ""
1158
+ if has_emergency:
1159
+ emergency_badge = f'''<div style="background: #ff0844; color: white; padding: 0.375rem 0.75rem;
1160
+ border-radius: 12px; font-size: 0.7rem; font-weight: 900;
1161
+ margin-top: 0.5rem; letter-spacing: 1px;">
1162
+ 🚨 AMBULANCE<br><span style="font-size: 0.65rem;">{method}</span>
1163
+ </div>'''
1164
+
1165
+ st.markdown(f"""
1166
+ <div class="{card_class}">
1167
+ <div class="traffic-light {light_class}">{direction_icons[idx]}</div>
1168
+ <div style="font-size: 1.2rem; font-weight: 800; color: #f8fafc; margin: 0.75rem 0; text-transform: uppercase; letter-spacing: 1.5px;">{direction}</div>
1169
+ <div style="color: {status_color}; font-weight: 800; font-size: 1rem; margin: 0.75rem 0; text-transform: uppercase; letter-spacing: 1.5px;">{status}</div>
1170
+ <div style="color: #94a3b8; font-size: 0.9rem; font-weight: 600;">{count} vehicles</div>
1171
+ {emergency_badge}
1172
+ </div>
1173
+ """, unsafe_allow_html=True)
1174
+
1175
+ # Timer display
1176
+ timer_placeholder = st.empty()
1177
+
1178
+ # Display detected images
1179
+ st.markdown("""
1180
+ <div class="section-container">
1181
+ <h2 class="section-title">🎯 Vehicle Detection Results</h2>
1182
+ <p style="color: #94a3b8; margin-bottom: 2rem;">AI-powered object recognition and emergency vehicle classification</p>
1183
+ </div>
1184
+ """, unsafe_allow_html=True)
1185
+
1186
+ img_cols = st.columns(4)
1187
+ for idx, direction in enumerate(directions):
1188
+ with img_cols[idx]:
1189
+ caption = f"πŸš— {direction} β€’ {st.session_state.counts[direction]} vehicles"
1190
+ if direction in st.session_state.emergency_directions:
1191
+ method = st.session_state.detection_method[direction]
1192
+ caption += f"\n🚨 AMBULANCE ({st.session_state.emergency_confidence[direction]:.1f}% - {method})"
1193
+
1194
+ st.image(
1195
+ st.session_state.annotated_images[direction],
1196
+ caption=caption,
1197
+ use_container_width=True
1198
+ )
1199
+
1200
+ # Countdown timer
1201
+ duration = green_time if st.session_state.phase == "green" else yellow_time
1202
+ for remaining in range(duration, 0, -1):
1203
+ if is_emergency and st.session_state.phase == "green":
1204
+ phase_emoji = "🚨"
1205
+ phase_text = "EMERGENCY CLEARANCE ACTIVE"
1206
+ timer_class = "timer-container emergency"
1207
+ value_class = "timer-value emergency"
1208
+ elif st.session_state.phase == "green":
1209
+ phase_emoji = "🟒"
1210
+ phase_text = "GREEN LIGHT ACTIVE"
1211
+ timer_class = "timer-container"
1212
+ value_class = "timer-value"
1213
+ else:
1214
+ phase_emoji = "🟑"
1215
+ phase_text = "YELLOW LIGHT ACTIVE"
1216
+ timer_class = "timer-container"
1217
+ value_class = "timer-value"
1218
+
1219
+ timer_placeholder.markdown(f"""
1220
+ <div class="{timer_class}">
1221
+ <div style="color: #94a3b8; font-size: 1.125rem; margin-bottom: 1rem; text-transform: uppercase; letter-spacing: 2.5px; font-weight: 700;">
1222
+ {phase_emoji} {phase_text} β€’ {current_direction.upper()} DIRECTION
1223
+ </div>
1224
+ <div class="{value_class}">{remaining}s</div>
1225
+ </div>
1226
+ """, unsafe_allow_html=True)
1227
+ time.sleep(1)
1228
+
1229
+ # Phase switching
1230
+ if st.session_state.phase == "green":
1231
+ st.session_state.phase = "yellow"
1232
+ st.rerun()
1233
+ else:
1234
+ st.session_state.finished.add(current_direction)
1235
+ st.session_state.current_index += 1
1236
+ st.session_state.phase = "green"
1237
+
1238
+ if len(st.session_state.finished) < 4:
1239
+ st.rerun()
1240
+ else:
1241
+ st.session_state.all_signals_complete = True
1242
+ st.rerun()
1243
+
1244
+ # STEP 3: Show Analytics
1245
+ if st.session_state.all_signals_complete:
1246
+ st.markdown("""
1247
+ <div class="success-banner">
1248
+ <div class="success-banner-title">βœ… Analysis Complete!</div>
1249
+ <div style="font-size: 1.25rem; color: var(--text-secondary); font-weight: 500;">
1250
+ All traffic directions processed successfully with maximum precision
1251
+ </div>
1252
+ </div>
1253
+ """, unsafe_allow_html=True)
1254
+
1255
+ # Emergency Summary
1256
+ if st.session_state.emergency_directions:
1257
+ emergency_list = ", ".join([
1258
+ f"{d} ({st.session_state.emergency_confidence[d]:.1f}% - {st.session_state.detection_method[d]})"
1259
+ for d in st.session_state.emergency_directions
1260
+ ])
1261
+ st.markdown(f"""
1262
+ <div class="emergency-banner">
1263
+ <div class="emergency-banner-title">🚨 EMERGENCY VEHICLE SUMMARY</div>
1264
+ <div style="font-size: 1.3rem; color: #fff; font-weight: 700; margin-top: 1rem;">
1265
+ Detected in: {emergency_list}
1266
+ </div>
1267
+ <div style="font-size: 1rem; color: #fbbf24; margin-top: 1rem; font-weight: 600;">
1268
+ βœ“ Emergency vehicles were given priority clearance with extended green time (35s)
1269
+ </div>
1270
+ </div>
1271
+ """, unsafe_allow_html=True)
1272
+
1273
+ # Total Vehicles
1274
+ total_vehicles = sum(st.session_state.counts.values())
1275
+ st.markdown(f"""
1276
+ <div class="section-container" style="text-align: center;">
1277
+ <h2 class="section-title">πŸ“Š Traffic Intelligence Dashboard</h2>
1278
+ <div style="font-size: 6rem; font-weight: 900; background: var(--cyber-gradient);
1279
+ -webkit-background-clip: text; -webkit-text-fill-color: transparent;
1280
+ font-family: 'JetBrains Mono', monospace; letter-spacing: -4px; margin: 2rem 0;">
1281
+ {total_vehicles}
1282
+ </div>
1283
+ <div style="color: #94a3b8; font-size: 1.5rem; font-weight: 700; text-transform: uppercase; letter-spacing: 2px;">
1284
+ Total Vehicles Detected
1285
+ </div>
1286
+ </div>
1287
+ """, unsafe_allow_html=True)
1288
+
1289
+ # Vehicle Classification Matrix
1290
+ combined_data = {}
1291
+ for direction in directions:
1292
+ if direction in st.session_state.class_counts:
1293
+ for vehicle_type, count in st.session_state.class_counts[direction].items():
1294
+ if vehicle_type not in combined_data:
1295
+ combined_data[vehicle_type] = {}
1296
+ combined_data[vehicle_type][direction] = count
1297
+
1298
+ df_combined = pd.DataFrame(combined_data).T.fillna(0).astype(int)
1299
+ df_combined = df_combined[directions]
1300
+
1301
+ st.markdown("""
1302
+ <div class="section-container">
1303
+ <h2 class="section-title">πŸš— Vehicle Classification Matrix</h2>
1304
+ </div>
1305
+ """, unsafe_allow_html=True)
1306
+ st.dataframe(
1307
+ df_combined.style.background_gradient(cmap='Blues', axis=None)
1308
+ .set_properties(**{'text-align': 'center', 'font-size': '16px', 'font-weight': '700'}),
1309
+ use_container_width=True,
1310
+ height=280
1311
+ )
1312
+
1313
+ # Traffic Distribution Chart
1314
+ st.markdown("""
1315
+ <div class="section-container">
1316
+ <h2 class="section-title">πŸ“ˆ Traffic Distribution Analysis</h2>
1317
+ </div>
1318
+ """, unsafe_allow_html=True)
1319
+
1320
+ fig, ax = plt.subplots(figsize=(14, 7))
1321
+ fig.patch.set_facecolor('none')
1322
+ ax.set_facecolor('none')
1323
+
1324
+ colors = []
1325
+ for d in st.session_state.counts.keys():
1326
+ if d in st.session_state.emergency_directions:
1327
+ colors.append('#ff0844') # Red for emergency
1328
+ else:
1329
+ colors.append('#667eea') # Blue for regular
1330
+
1331
+ bars = ax.bar(
1332
+ st.session_state.counts.keys(),
1333
+ st.session_state.counts.values(),
1334
+ color=colors,
1335
+ edgecolor='white',
1336
+ linewidth=3,
1337
+ alpha=0.95
1338
+ )
1339
+
1340
+ for bar, direction in zip(bars, st.session_state.counts.keys()):
1341
+ height = bar.get_height()
1342
+ label = f'{int(height)}'
1343
+ if direction in st.session_state.emergency_directions:
1344
+ label += '\n🚨'
1345
+ ax.text(bar.get_x() + bar.get_width()/2., height + 1.5,
1346
+ label,
1347
+ ha='center', va='bottom', color='white',
1348
+ fontweight='bold', fontsize=16)
1349
+
1350
+ ax.set_ylabel('Vehicle Count', color='white',
1351
+ fontsize=16, fontweight='bold')
1352
+ ax.set_xlabel('Direction', color='white',
1353
+ fontsize=16, fontweight='bold')
1354
+ ax.tick_params(colors='white', labelsize=13, width=2)
1355
+ ax.spines['bottom'].set_color('white')
1356
+ ax.spines['left'].set_color('white')
1357
+ ax.spines['bottom'].set_linewidth(2)
1358
+ ax.spines['left'].set_linewidth(2)
1359
+ ax.spines['top'].set_visible(False)
1360
+ ax.spines['right'].set_visible(False)
1361
+ ax.grid(axis='y', alpha=0.15, color='white',
1362
+ linestyle='--', linewidth=1.5)
1363
+ plt.tight_layout()
1364
+
1365
+ st.pyplot(fig, use_container_width=True)
1366
+
1367
+ # Busiest Direction
1368
+ busiest = max(st.session_state.counts.items(), key=lambda x: x[1])
1369
+ st.markdown(f"""
1370
+ <div class="section-container" style="text-align: center;">
1371
+ <h2 class="section-title">πŸ† Critical Priority Direction</h2>
1372
+ <div style="font-size: 5rem; font-weight: 900; color: #ef4444; margin: 1.5rem 0;
1373
+ text-shadow: 0 0 40px rgba(239, 68, 68, 0.4); letter-spacing: -2px;">
1374
+ {busiest[0].upper()}
1375
+ </div>
1376
+ <div style="font-size: 1.75rem; color: var(--text-secondary); font-weight: 700;">
1377
+ {busiest[1]} vehicles detected β€’ <span style="color: #ef4444;">Highest Traffic Volume</span>
1378
+ </div>
1379
+ </div>
1380
+ """, unsafe_allow_html=True)
1381
+
1382
+ # Signal Timings with Emergency Priority
1383
+ timing_data = []
1384
+ for d, count in st.session_state.sorted_directions:
1385
+ if d in st.session_state.emergency_directions:
1386
+ green = 35
1387
+ priority = "🚨 EMERGENCY"
1388
+ else:
1389
+ base_time = 5
1390
+ time_per_vehicle = 1
1391
+ max_time = 25
1392
+ green = min(base_time + int(count / 2)
1393
+ * time_per_vehicle, max_time)
1394
+ # Assign priority based on position
1395
+ idx = [x[0]
1396
+ for x in st.session_state.sorted_directions].index(d)
1397
+ priorities = ["πŸ”΄ Critical", "🟠 High", "🟑 Medium", "🟒 Low"]
1398
+ priority = priorities[min(idx, 3)]
1399
+
1400
+ timing_data.append({
1401
+ "Direction": d,
1402
+ "Vehicles": count,
1403
+ "Green Time (sec)": green,
1404
+ "Priority": priority,
1405
+ "Detection": st.session_state.detection_method.get(d, "None")
1406
+ })
1407
+
1408
+ green_df = pd.DataFrame(timing_data)
1409
+
1410
+ st.markdown("""
1411
+ <div class="section-container">
1412
+ <h2 class="section-title">⏱️ AI-Optimized Signal Timings</h2>
1413
+ <p style="color: #94a3b8; margin-bottom: 1rem;">Emergency vehicles receive 35-second priority clearance</p>
1414
+ </div>
1415
+ """, unsafe_allow_html=True)
1416
+ st.dataframe(
1417
+ green_df.style.background_gradient(
1418
+ subset=['Green Time (sec)'], cmap='RdYlGn')
1419
+ .set_properties(**{'text-align': 'center', 'font-size': '16px', 'font-weight': '700'}),
1420
+ use_container_width=True,
1421
+ height=280
1422
+ )
1423
+
1424
+ # Pie Chart
1425
+ st.markdown("""
1426
+ <div class="section-container">
1427
+ <h2 class="section-title">πŸ₯§ Traffic Share Distribution</h2>
1428
+ </div>
1429
+ """, unsafe_allow_html=True)
1430
+
1431
+ fig2, ax2 = plt.subplots(figsize=(11, 11))
1432
+ fig2.patch.set_facecolor('none')
1433
+
1434
+ pie_colors = []
1435
+ for d in st.session_state.counts.keys():
1436
+ if d in st.session_state.emergency_directions:
1437
+ pie_colors.append('#ff0844')
1438
+ else:
1439
+ pie_colors.append('#667eea')
1440
+
1441
+ wedges, texts, autotexts = ax2.pie(
1442
+ st.session_state.counts.values(),
1443
+ labels=st.session_state.counts.keys(),
1444
+ autopct='%1.1f%%',
1445
+ colors=pie_colors,
1446
+ startangle=90,
1447
+ textprops={'color': 'white', 'fontsize': 15, 'fontweight': 'bold'},
1448
+ explode=[0.08, 0.08, 0.08, 0.08],
1449
+ shadow=True
1450
+ )
1451
+
1452
+ for autotext in autotexts:
1453
+ autotext.set_color('white')
1454
+ autotext.set_fontsize(18)
1455
+ autotext.set_fontweight('900')
1456
+
1457
+ col1, col2, col3 = st.columns([1, 2, 1])
1458
+ with col2:
1459
+ st.pyplot(fig2, use_container_width=True)
1460
+
1461
+ # Action Buttons
1462
+ st.markdown('<div style="margin: 3rem 2rem;">', unsafe_allow_html=True)
1463
+ btn_cols = st.columns([1, 1, 1])
1464
+
1465
+ with btn_cols[0]:
1466
+ if st.button("πŸ”„ Run New Analysis", use_container_width=True):
1467
+ for key in list(st.session_state.keys()):
1468
+ del st.session_state[key]
1469
+ st.rerun()
1470
+
1471
+ with btn_cols[1]:
1472
+ if st.button("πŸ“Š Export Analytics", use_container_width=True):
1473
+ csv_report = f"""SmartLane AI - Traffic Analysis Report
1474
+ Generated: {pd.Timestamp.now().strftime('%Y-%m-%d %H:%M:%S')}
1475
+ ===============================================
1476
+
1477
+ SUMMARY STATISTICS
1478
+ ------------------
1479
+ Total Vehicles Detected: {total_vehicles}
1480
+ Emergency Vehicles: {len(st.session_state.emergency_directions)}
1481
+ Total Cycle Time: {sum([t['Green Time (sec)'] for t in timing_data]) + 12} seconds
1482
+
1483
+ EMERGENCY VEHICLE DETECTION
1484
+ ---------------------------
1485
+ """
1486
+ if st.session_state.emergency_directions:
1487
+ for d in st.session_state.emergency_directions:
1488
+ csv_report += f"{d}: Ambulance detected ({st.session_state.emergency_confidence[d]:.1f}% confidence)\n"
1489
+ csv_report += f" Method: {st.session_state.detection_method[d]}\n"
1490
+ else:
1491
+ csv_report += "No emergency vehicles detected\n"
1492
+
1493
+ csv_report += f"\nDIRECTION ANALYSIS\n------------------\n"
1494
+ for direction in directions:
1495
+ csv_report += f"{direction}: {st.session_state.counts[direction]} vehicles\n"
1496
+
1497
+ total_cars = sum(
1498
+ [st.session_state.class_counts[d].get('car', 0) for d in directions])
1499
+ total_motorcycles = sum(
1500
+ [st.session_state.class_counts[d].get('motorcycle', 0) for d in directions])
1501
+ total_buses = sum(
1502
+ [st.session_state.class_counts[d].get('bus', 0) for d in directions])
1503
+ total_trucks = sum(
1504
+ [st.session_state.class_counts[d].get('truck', 0) for d in directions])
1505
+
1506
+ csv_report += f"\nVEHICLE CLASSIFICATION\n----------------------\n"
1507
+ csv_report += f"Cars: {total_cars}\n"
1508
+ csv_report += f"Motorcycles: {total_motorcycles}\n"
1509
+ csv_report += f"Buses: {total_buses}\n"
1510
+ csv_report += f"Trucks: {total_trucks}\n"
1511
+
1512
+ csv_report += f"\nSIGNAL TIMINGS\n--------------\n"
1513
+ for item in timing_data:
1514
+ csv_report += f"{item['Direction']}: {item['Green Time (sec)']} seconds ({item['Priority']})\n"
1515
+
1516
+ st.download_button(
1517
+ label="⬇️ Download Report",
1518
+ data=csv_report,
1519
+ file_name=f"smartlane_report_{pd.Timestamp.now().strftime('%Y%m%d_%H%M%S')}.txt",
1520
+ mime="text/plain",
1521
+ )
1522
+
1523
+ with btn_cols[2]:
1524
+ if st.button("πŸ“§ Share Results", use_container_width=True):
1525
+ st.info("πŸ“€ Sharing functionality available in production release")
1526
+
1527
+ st.markdown('</div>', unsafe_allow_html=True)
1528
+
1529
+ # Footer
1530
+ st.markdown("""
1531
+ <div class="section-container" style="text-align: center; margin: 4rem 2rem 2rem;">
1532
+ <h2 style="font-size: 2.5rem; font-weight: 900; background: var(--cyber-gradient);
1533
+ -webkit-background-clip: text; -webkit-text-fill-color: transparent;
1534
+ margin-bottom: 1.25rem; letter-spacing: -1px;">
1535
+ ⚑ Powered by SmartLane AI
1536
+ </h2>
1537
+ <p style="color: #94a3b8; font-size: 1.125rem; margin-bottom: 2rem; font-weight: 600;">
1538
+ PARANOX 2.0 National Hackathon Project β€’ Developed by Team Source Code
1539
+ </p>
1540
+ <div style="margin: 2rem 0; padding: 2rem; background: rgba(102, 126, 234, 0.08);
1541
+ border-radius: 20px; border: 1px solid rgba(102, 126, 234, 0.2);">
1542
+ <p style="color: var(--text-secondary); margin: 0; line-height: 2; font-weight: 500;">
1543
+ <strong style="color: #667eea; font-size: 1.125rem;">Technology Stack:</strong><br>
1544
+ YOLOv8 Object Detection β€’ CNN Ambulance Classification β€’ Streamlit Framework β€’
1545
+ Python Deep Learning β€’ Real-Time Analytics Engine β€’ Emergency Vehicle Priority System β€’
1546
+ Adaptive Signal Processing β€’ Computer Vision β€’ Multi-Method Detection
1547
+ </p>
1548
+ </div>
1549
+ <div style="margin-top: 2.5rem; padding-top: 2.5rem; border-top: 1px solid rgba(255, 255, 255, 0.1);">
1550
+ <p style="color: var(--text-muted); font-size: 0.95rem; margin: 0; font-weight: 600;">
1551
+ Β© 2025 Team Source Code β€’ Built for TechXNinjas PARANOX 2.0 Hackathon
1552
+ </p>
1553
+ </div>
1554
+ </div>
1555
+ """, unsafe_allow_html=True)
1556
+
1557
+ else:
1558
+ st.info("πŸ“€ Please upload images for all four directions to begin analysis")
requirements.txt CHANGED
@@ -1,3 +1,6 @@
1
- altair
2
- pandas
3
- streamlit
 
 
 
 
1
+ pillow
2
+ ultralytics
3
+ pandas
4
+ matplotlib
5
+ opencv-python-headless
6
+ streamlit
yolov8n.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f59b3d833e2ff32e194b5bb8e08d211dc7c5bdf144b90d2c8412c47ccfc83b36
3
+ size 6549796
yolov8s.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1f47a78bf100391c2a140b7ac73a1caae18c32779be7d310658112f7ac9aa78a
3
+ size 22588772