MuhammmadRizwanRizwan commited on
Commit
13065cb
·
verified ·
1 Parent(s): 8f1038f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +641 -639
app.py CHANGED
@@ -1,414 +1,416 @@
1
 
2
- import streamlit as st
3
- from PIL import Image
4
- import torch
5
- import cv2
6
- import numpy as np
7
- from datetime import datetime
8
- import plotly.express as px
9
- import plotly.graph_objects as go
10
- import pandas as pd
11
- from ultralytics import YOLO
12
- import os
13
- import io
14
- from fpdf import FPDF
15
- import base64
16
 
17
- # Page config
18
- st.set_page_config(
19
- page_title="Traffic Sign Detection System",
20
- page_icon="🚦",
21
- layout="wide",
22
- initial_sidebar_state="expanded"
23
- )
24
 
25
- # Custom CSS
26
- st.markdown("""
27
- <style>
28
- .stApp {
29
- background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
30
- color: #e5e5e5;
31
- }
32
- .upload-box {
33
- border: 2px dashed #4a4a8a;
34
- border-radius: 15px;
35
- padding: 30px;
36
- text-align: center;
37
- background: rgba(255,255,255,0.05);
38
- backdrop-filter: blur(10px);
39
- transition: all 0.3s ease;
40
- }
41
- .upload-box:hover {
42
- border-color: #6a6aaa;
43
- background: rgba(255,255,255,0.08);
44
- }
45
- .detection-box {
46
- background: rgba(255,255,255,0.07);
47
- padding: 25px;
48
- border-radius: 15px;
49
- margin: 15px 0;
50
- box-shadow: 0 4px 15px rgba(0,0,0,0.2);
51
- }
52
- .metrics-card {
53
- background: rgba(255,255,255,0.1);
54
- padding: 20px;
55
- border-radius: 10px;
56
- margin: 10px 0;
57
- transition: transform 0.3s ease;
58
- }
59
- .metrics-card:hover {
60
- transform: translateY(-5px);
61
- }
62
- .confidence-meter {
63
- height: 20px;
64
- background: rgba(255,255,255,0.1);
65
- border-radius: 10px;
66
- overflow: hidden;
67
- box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
68
- }
69
- .header-container {
70
- padding: 20px;
71
- background: rgba(255,255,255,0.05);
72
- border-radius: 15px;
73
- margin-bottom: 20px;
74
- text-align: center;
75
- }
76
- .stButton>button {
77
- background: linear-gradient(45deg, #3498db, #2980b9);
78
- color: white;
79
- border: none;
80
- padding: 10px 20px;
81
- border-radius: 8px;
82
- transition: all 0.3s ease;
83
- }
84
- .stButton>button:hover {
85
- transform: translateY(-2px);
86
- box-shadow: 0 5px 15px rgba(0,0,0,0.2);
87
- }
88
- </style>
89
- """, unsafe_allow_html=True)
90
 
91
- # Initialize session state
92
- if 'model' not in st.session_state:
93
- st.session_state.model = None
94
- st.session_state.total_analyses = 0
95
 
96
- @st.cache_resource
97
- def load_model():
98
- """Load and cache the YOLO model"""
99
- try:
100
- model = YOLO('best.pt')
101
- return model
102
- except Exception as e:
103
- st.error(f"Error loading model: {str(e)}")
104
- return None
105
 
106
- def create_confidence_bar(confidence):
107
- """Create a visual confidence meter"""
108
- colors = {
109
- "high": "#00ff00",
110
- "medium": "#ffaa00",
111
- "low": "#ff0000"
112
- }
113
- color = colors["high"] if confidence > 0.7 else colors["medium"] if confidence > 0.5 else colors["low"]
114
- return f"""
115
- <div class="confidence-meter">
116
- <div style="width:{confidence*100}%; height:100%; background:{color};
117
- transition:width 0.5s; text-align:center; color:white; line-height:20px;">
118
- {confidence:.1%}
119
- </div>
120
- </div>
121
- """
122
 
123
- def create_visualization(results, model):
124
- """Create visualization plots for detection results"""
125
- if len(results.boxes) > 0:
126
- # Prepare data for visualization
127
- confidences = results.boxes.conf.cpu().numpy()
128
- classes = [model.names[int(cls)] for cls in results.boxes.cls.cpu().numpy()]
129
 
130
- # Create confidence distribution plot
131
- fig_conf = go.Figure(data=[go.Histogram(x=confidences, nbinsx=20)])
132
- fig_conf.update_layout(
133
- title="Confidence Score Distribution",
134
- xaxis_title="Confidence Score",
135
- yaxis_title="Count",
136
- template="plotly_dark"
137
- )
138
 
139
- # Create class distribution plot
140
- class_counts = pd.Series(classes).value_counts()
141
- fig_class = px.pie(values=class_counts.values, names=class_counts.index,
142
- title="Distribution of Detected Signs")
143
- fig_class.update_layout(template="plotly_dark")
144
 
145
- return fig_conf, fig_class
146
- return None, None
147
 
148
- class PDF(FPDF):
149
- def header(self):
150
- self.set_font('Arial', 'B', 20)
151
- self.cell(0, 10, 'Traffic Sign Detection Report', 0, 1, 'C')
152
- self.ln(10)
153
 
154
- def footer(self):
155
- self.set_y(-15)
156
- self.set_font('Arial', 'I', 8)
157
- self.cell(0, 10, f'Report generated on {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}', 0, 0, 'C')
158
-
159
- def generate_pdf_report(original_image, detected_image, results, model, analytics_enabled=True):
160
- """Generate a PDF report with detection results and analytics"""
161
- pdf = PDF()
162
- pdf.add_page()
163
-
164
- # Add timestamp
165
- pdf.set_font('Arial', '', 12)
166
- pdf.cell(0, 10, f'Analysis Date: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}', 0, 1)
167
- pdf.ln(5)
168
-
169
- # Save and add images
170
- # Original Image
171
- pdf.set_font('Arial', 'B', 14)
172
- pdf.cell(0, 10, 'Original Image', 0, 1)
173
-
174
- # Convert original image to RGB if needed
175
- if len(original_image.shape) == 3 and original_image.shape[2] == 3:
176
- original_image_rgb = cv2.cvtColor(original_image, cv2.COLOR_BGR2RGB)
177
- else:
178
- original_image_rgb = original_image
179
 
180
- # Save original image
181
- orig_img_path = 'temp_original.jpg'
182
- cv2.imwrite(orig_img_path, cv2.cvtColor(original_image_rgb, cv2.COLOR_RGB2BGR))
183
- pdf.image(orig_img_path, x=10, w=190)
184
- pdf.ln(10)
185
-
186
- # Detection Results
187
- pdf.set_font('Arial', 'B', 14)
188
- pdf.cell(0, 10, 'Detection Results', 0, 1)
189
-
190
- # Save detected image
191
- detected_img_path = 'temp_detected.jpg'
192
- cv2.imwrite(detected_img_path, cv2.cvtColor(detected_image, cv2.COLOR_RGB2BGR))
193
- pdf.image(detected_img_path, x=10, w=190)
194
- pdf.ln(10)
195
-
196
- # Detection Details
197
- pdf.set_font('Arial', 'B', 14)
198
- pdf.cell(0, 10, 'Detection Details', 0, 1)
199
- pdf.set_font('Arial', '', 12)
200
 
201
- if len(results.boxes) > 0:
202
- # Summary statistics
203
- avg_conf = float(torch.mean(results.boxes.conf).item())
204
- unique_classes = len(set(results.boxes.cls.cpu().numpy()))
205
 
206
- pdf.cell(0, 10, f'Total Detections: {len(results.boxes)}', 0, 1)
207
- pdf.cell(0, 10, f'Average Confidence: {avg_conf:.2%}', 0, 1)
208
- pdf.cell(0, 10, f'Unique Sign Types: {unique_classes}', 0, 1)
209
- pdf.ln(5)
210
 
211
- # Detailed detections
212
- pdf.set_font('Arial', 'B', 12)
213
- pdf.cell(0, 10, 'Detailed Detections:', 0, 1)
214
- pdf.set_font('Arial', '', 12)
215
 
216
- for idx, box in enumerate(results.boxes):
217
- class_id = int(box.cls[0])
218
- conf = float(box.conf[0])
219
- class_name = model.names[class_id]
220
- box_coords = box.xyxy[0].cpu().numpy()
221
 
222
- pdf.cell(0, 10, f'Detection {idx+1}:', 0, 1)
223
- pdf.cell(0, 10, f' • Sign Type: {class_name}', 0, 1)
224
- pdf.cell(0, 10, f' • Confidence: {conf:.2%}', 0, 1)
225
- pdf.cell(0, 10, f' • Location: x1={box_coords[0]:.1f}, y1={box_coords[1]:.1f}, x2={box_coords[2]:.1f}, y2={box_coords[3]:.1f}', 0, 1)
226
- pdf.ln(5)
227
- else:
228
- pdf.cell(0, 10, 'No traffic signs detected in this image.', 0, 1)
229
-
230
- # Clean up temporary files
231
- try:
232
- os.remove(orig_img_path)
233
- os.remove(detected_img_path)
234
- except:
235
- pass
236
 
237
- # Save to bytes
238
- pdf_bytes = io.BytesIO()
239
- pdf.output(pdf_bytes)
240
- pdf_bytes.seek(0)
241
 
242
- return pdf_bytes
243
 
244
- def main():
245
- # Header
246
- st.markdown("""
247
- <div class="header-container">
248
- <h1>🚦 Traffic Sign Detection System</h1>
249
- <p>Upload an image to detect and analyze traffic signs</p>
250
- </div>
251
- """, unsafe_allow_html=True)
252
 
253
- # Sidebar
254
- with st.sidebar:
255
- st.header("📊 Analysis Settings")
256
- # confidence_threshold = st.slider("Detection Confidence Threshold", 0.0, 1.0, 0.25, 0.05)
257
- enable_analytics = st.checkbox("Enable Advanced Analytics", True)
 
 
258
 
259
- # Main content
260
- col1, col2 = st.columns([2, 1])
261
 
262
- with col1:
263
- st.markdown("<div class='upload-box'>", unsafe_allow_html=True)
264
- uploaded_file = st.file_uploader(
265
- "Drop your traffic sign image here or click to upload",
266
- type=['jpg', 'jpeg', 'png']
267
- )
268
- st.markdown("</div>", unsafe_allow_html=True)
269
 
270
- with col2:
271
- st.markdown("<div class='metrics-card'>", unsafe_allow_html=True)
272
- st.markdown("### 📈 System Statistics")
273
- st.metric("Total Analyses", st.session_state.total_analyses)
274
- st.markdown("</div>", unsafe_allow_html=True)
275
 
276
- if uploaded_file:
277
- # Load and process image
278
- image_bytes = uploaded_file.read()
279
- image = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)
280
 
281
- col1, col2 = st.columns(2)
282
 
283
- with col1:
284
- st.markdown("### Original Image")
285
- image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
286
- st.image(image_rgb)
287
 
288
- if st.button("🔍 Analyze Image", key="analyze_button"):
289
- st.session_state.total_analyses += 1
290
 
291
- with st.spinner("Processing image..."):
292
- # Load model if not already loaded
293
- if st.session_state.model is None:
294
- st.session_state.model = load_model()
295
 
296
- if st.session_state.model is not None:
297
- # Progress bar
298
- progress_text = "Running analysis..."
299
- progress_bar = st.progress(0)
300
- # for i in range(100):
301
- # progress_bar.progress(i + 1)
302
- # if i == 30:
303
- # progress_text = "Detecting signs..."
304
- # elif i == 60:
305
- # progress_text = "Analyzing patterns..."
306
- # elif i == 90:
307
- # progress_text = "Preparing results..."
308
- # st.write(progress_text)
309
 
310
- # Run inference
311
- results = st.session_state.model.predict(source=image, conf=confidence_threshold)[0]
312
 
313
- with col2:
314
- st.markdown("### Detection Results")
315
- plotted_image = results.plot()
316
- plotted_image_rgb = cv2.cvtColor(plotted_image, cv2.COLOR_BGR2RGB)
317
- st.image(plotted_image_rgb)
318
 
319
- # Display detections and analytics
320
- if len(results.boxes) > 0:
321
- st.markdown("<div class='detection-box'>", unsafe_allow_html=True)
322
- st.markdown("### 🎯 Detection Details")
323
 
324
- for idx, box in enumerate(results.boxes):
325
- class_id = int(box.cls[0])
326
- conf = float(box.conf[0])
327
- class_name = st.session_state.model.names[class_id]
328
 
329
- with st.expander(f"Detection {idx+1}: {class_name} ({conf:.2%})"):
330
- st.markdown(create_confidence_bar(conf), unsafe_allow_html=True)
331
- box_coords = box.xyxy[0].cpu().numpy()
332
- st.markdown(f"**Location:** x1={box_coords[0]:.1f}, y1={box_coords[1]:.1f}, x2={box_coords[2]:.1f}, y2={box_coords[3]:.1f}")
333
 
334
- if enable_analytics:
335
- st.markdown("### 📊 Analytics")
336
- fig_conf, fig_class = create_visualization(results, st.session_state.model)
337
- if fig_conf and fig_class:
338
- col1, col2 = st.columns(2)
339
- with col1:
340
- st.plotly_chart(fig_conf, use_container_width=True)
341
- with col2:
342
- st.plotly_chart(fig_class, use_container_width=True)
343
 
344
- # Summary metrics
345
- col1, col2, col3 = st.columns(3)
346
- with col1:
347
- st.markdown("<div class='metrics-card'>", unsafe_allow_html=True)
348
- st.metric("Total Detections", len(results.boxes))
349
- st.markdown("</div>", unsafe_allow_html=True)
350
- with col2:
351
- st.markdown("<div class='metrics-card'>", unsafe_allow_html=True)
352
- # avg_conf = float(torch.mean(results.boxes
353
- avg_conf = float(torch.mean(results.boxes.conf).item())
354
- st.metric("Average Confidence", f"{avg_conf:.1%}")
355
- st.markdown("</div>", unsafe_allow_html=True)
356
- with col3:
357
- st.markdown("<div class='metrics-card'>", unsafe_allow_html=True)
358
- unique_classes = len(set(results.boxes.cls.cpu().numpy()))
359
- st.metric("Unique Sign Types", unique_classes)
360
- st.markdown("</div>", unsafe_allow_html=True)
361
 
362
- # Generate and offer PDF report download
363
- st.markdown("### 📄 Download Report")
364
- pdf_bytes = generate_pdf_report(
365
- image,
366
- plotted_image,
367
- results,
368
- st.session_state.model,
369
- analytics_enabled=enable_analytics
370
- )
371
 
372
- # Create download button with custom styling
373
- st.markdown("""
374
- <style>
375
- .download-button {
376
- background: linear-gradient(45deg, #2ecc71, #27ae60);
377
- color: white;
378
- padding: 12px 24px;
379
- border-radius: 8px;
380
- border: none;
381
- cursor: pointer;
382
- transition: all 0.3s ease;
383
- text-decoration: none;
384
- display: inline-block;
385
- margin: 10px 0;
386
- }
387
- .download-button:hover {
388
- transform: translateY(-2px);
389
- box-shadow: 0 5px 15px rgba(0,0,0,0.2);
390
- }
391
- </style>
392
- """, unsafe_allow_html=True)
393
 
394
- # Convert PDF bytes to base64 for download
395
- b64_pdf = base64.b64encode(pdf_bytes.getvalue()).decode()
396
- href = f'<a href="data:application/pdf;base64,{b64_pdf}" download="traffic_sign_report.pdf" class="download-button">📥 Download Detection Report</a>'
397
- st.markdown(href, unsafe_allow_html=True)
398
 
399
- st.markdown("</div>", unsafe_allow_html=True)
400
- else:
401
- st.warning("No traffic signs detected in the image.")
402
- else:
403
- st.error("Failed to load the model. Please check if the model file exists and try again.")
404
 
405
 
406
- if __name__ == "__main__":
407
- try:
408
- main()
409
- except Exception as e:
410
- st.error(f"An error occurred: {str(e)}")
411
- st.error("Please refresh the page and try again.")
412
 
413
 
414
 
@@ -421,310 +423,310 @@ if __name__ == "__main__":
421
 
422
 
423
 
424
- # import streamlit as st
425
- # from PIL import Image
426
- # import torch
427
- # import cv2
428
- # import numpy as np
429
- # from datetime import datetime
430
- # import plotly.express as px
431
- # import plotly.graph_objects as go
432
- # import pandas as pd
433
- # from ultralytics import YOLO
434
- # import os
435
 
436
- # # Page config
437
- # st.set_page_config(
438
- # page_title="Traffic Sign Detection System",
439
- # page_icon="🚦",
440
- # layout="wide",
441
- # initial_sidebar_state="expanded"
442
- # )
443
 
444
- # # Custom CSS with improved styling
445
- # st.markdown("""
446
- # <style>
447
- # .stApp {
448
- # background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
449
- # color: #e5e5e5;
450
- # }
451
- # .upload-box {
452
- # border: 2px dashed #4a4a8a;
453
- # border-radius: 15px;
454
- # padding: 30px;
455
- # text-align: center;
456
- # background: rgba(255,255,255,0.05);
457
- # backdrop-filter: blur(10px);
458
- # transition: all 0.3s ease;
459
- # }
460
- # .upload-box:hover {
461
- # border-color: #6a6aaa;
462
- # background: rgba(255,255,255,0.08);
463
- # }
464
- # .detection-box {
465
- # background: rgba(255,255,255,0.07);
466
- # padding: 25px;
467
- # border-radius: 15px;
468
- # margin: 15px 0;
469
- # box-shadow: 0 4px 15px rgba(0,0,0,0.2);
470
- # }
471
- # .metrics-card {
472
- # background: rgba(255,255,255,0.1);
473
- # padding: 20px;
474
- # border-radius: 10px;
475
- # margin: 10px 0;
476
- # transition: transform 0.3s ease;
477
- # }
478
- # .metrics-card:hover {
479
- # transform: translateY(-5px);
480
- # }
481
- # .confidence-meter {
482
- # height: 20px;
483
- # background: rgba(255,255,255,0.1);
484
- # border-radius: 10px;
485
- # overflow: hidden;
486
- # box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
487
- # }
488
- # .header-container {
489
- # padding: 20px;
490
- # background: rgba(255,255,255,0.05);
491
- # border-radius: 15px;
492
- # margin-bottom: 20px;
493
- # text-align: center;
494
- # }
495
- # .stButton>button {
496
- # background: linear-gradient(45deg, #3498db, #2980b9);
497
- # color: white;
498
- # border: none;
499
- # padding: 10px 20px;
500
- # border-radius: 8px;
501
- # transition: all 0.3s ease;
502
- # }
503
- # .stButton>button:hover {
504
- # transform: translateY(-2px);
505
- # box-shadow: 0 5px 15px rgba(0,0,0,0.2);
506
- # }
507
- # </style>
508
- # """, unsafe_allow_html=True)
509
 
510
- # # Initialize session state
511
- # if 'model' not in st.session_state:
512
- # st.session_state.model = None
513
- # st.session_state.total_analyses = 0
514
 
515
- # @st.cache_resource
516
- # def load_model():
517
- # """Load and cache the YOLO model"""
518
- # try:
519
- # model = YOLO('best.pt')
520
- # return model
521
- # except Exception as e:
522
- # st.error(f"Error loading model: {str(e)}")
523
- # return None
524
 
525
- # def create_confidence_bar(confidence):
526
- # """Create a visual confidence meter"""
527
- # colors = {
528
- # "high": "#00ff00",
529
- # "medium": "#ffaa00",
530
- # "low": "#ff0000"
531
- # }
532
- # color = colors["high"] if confidence > 0.7 else colors["medium"] if confidence > 0.5 else colors["low"]
533
- # return f"""
534
- # <div class="confidence-meter">
535
- # <div style="width:{confidence*100}%; height:100%; background:{color};
536
- # transition:width 0.5s; text-align:center; color:white; line-height:20px;">
537
- # {confidence:.1%}
538
- # </div>
539
- # </div>
540
- # """
541
 
542
- # def create_visualization(results, model):
543
- # """Create visualization plots for detection results"""
544
- # if len(results.boxes) > 0:
545
- # # Prepare data for visualization
546
- # confidences = results.boxes.conf.cpu().numpy()
547
- # classes = [model.names[int(cls)] for cls in results.boxes.cls.cpu().numpy()]
548
 
549
- # # Create confidence distribution plot
550
- # fig_conf = go.Figure(data=[go.Histogram(x=confidences, nbinsx=20)])
551
- # fig_conf.update_layout(
552
- # title="Confidence Score Distribution",
553
- # xaxis_title="Confidence Score",
554
- # yaxis_title="Count",
555
- # template="plotly_dark"
556
- # )
557
 
558
- # # Create class distribution plot
559
- # class_counts = pd.Series(classes).value_counts()
560
- # fig_class = px.pie(values=class_counts.values, names=class_counts.index,
561
- # title="Distribution of Detected Signs")
562
- # fig_class.update_layout(template="plotly_dark")
563
 
564
- # return fig_conf, fig_class
565
- # return None, None
566
 
567
- # def main():
568
- # # Header
569
- # st.markdown("""
570
- # <div class="header-container">
571
- # <h1>🚦 Traffic Sign Detection System</h1>
572
- # <p>Upload an image to detect and analyze traffic signs</p>
573
- # </div>
574
- # """, unsafe_allow_html=True)
575
 
576
- # # Sidebar
577
- # with st.sidebar:
578
- # st.header("📊 Analysis Settings")
579
- # confidence_threshold = st.slider("Detection Confidence Threshold", 0.0, 1.0, 0.25, 0.05)
580
- # enable_analytics = st.checkbox("Enable Advanced Analytics", True)
581
 
582
- # # Main content
583
- # col1, col2 = st.columns([2, 1])
584
 
585
- # with col1:
586
- # st.markdown("<div class='upload-box'>", unsafe_allow_html=True)
587
- # uploaded_file = st.file_uploader(
588
- # "Drop your traffic sign image here or click to upload",
589
- # type=['jpg', 'jpeg', 'png']
590
- # )
591
- # st.markdown("</div>", unsafe_allow_html=True)
592
 
593
- # with col2:
594
- # st.markdown("<div class='metrics-card'>", unsafe_allow_html=True)
595
- # st.markdown("### 📈 System Statistics")
596
- # st.metric("Total Analyses", st.session_state.total_analyses)
597
- # st.markdown("</div>", unsafe_allow_html=True)
598
 
599
- # if uploaded_file:
600
- # # Load and process image
601
- # image_bytes = uploaded_file.read()
602
- # image = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)
603
 
604
- # col1, col2 = st.columns(2)
605
 
606
- # with col1:
607
- # st.markdown("### Original Image")
608
- # image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
609
- # st.image(image_rgb)
610
 
611
- # if st.button("🔍 Analyze Image", key="analyze_button"):
612
- # st.session_state.total_analyses += 1
613
 
614
- # with st.spinner("Processing image..."):
615
- # # Load model if not already loaded
616
- # if st.session_state.model is None:
617
- # st.session_state.model = load_model()
618
 
619
- # if st.session_state.model is not None:
620
- # # Progress bar
621
- # progress_text = "Running analysis..."
622
- # progress_bar = st.progress(0)
623
- # # for i in range(100):
624
- # # progress_bar.progress(i + 1)
625
- # # if i == 30:
626
- # # progress_text = "Detecting signs..."
627
- # # elif i == 60:
628
- # # progress_text = "Analyzing patterns..."
629
- # # elif i == 90:
630
- # # progress_text = "Preparing results..."
631
- # # st.write(progress_text)
632
 
633
- # # Run inference
634
- # results = st.session_state.model.predict(source=image, conf=confidence_threshold)[0]
635
 
636
- # with col2:
637
- # st.markdown("### Detection Results")
638
- # plotted_image = results.plot()
639
- # plotted_image_rgb = cv2.cvtColor(plotted_image, cv2.COLOR_BGR2RGB)
640
- # st.image(plotted_image_rgb)
641
 
642
- # # Display detections and analytics
643
- # if len(results.boxes) > 0:
644
- # st.markdown("<div class='detection-box'>", unsafe_allow_html=True)
645
- # st.markdown("### 🎯 Detection Details")
646
 
647
- # for idx, box in enumerate(results.boxes):
648
- # class_id = int(box.cls[0])
649
- # conf = float(box.conf[0])
650
- # class_name = st.session_state.model.names[class_id]
651
 
652
- # with st.expander(f"Detection {idx+1}: {class_name} ({conf:.2%})"):
653
- # st.markdown(create_confidence_bar(conf), unsafe_allow_html=True)
654
- # box_coords = box.xyxy[0].cpu().numpy()
655
- # st.markdown(f"**Location:** x1={box_coords[0]:.1f}, y1={box_coords[1]:.1f}, x2={box_coords[2]:.1f}, y2={box_coords[3]:.1f}")
656
 
657
- # if enable_analytics:
658
- # st.markdown("### 📊 Analytics")
659
- # fig_conf, fig_class = create_visualization(results, st.session_state.model)
660
- # if fig_conf and fig_class:
661
- # col1, col2 = st.columns(2)
662
- # with col1:
663
- # st.plotly_chart(fig_conf, use_container_width=True)
664
- # with col2:
665
- # st.plotly_chart(fig_class, use_container_width=True)
666
 
667
- # # Summary metrics
668
- # col1, col2, col3 = st.columns(3)
669
- # with col1:
670
- # st.markdown("<div class='metrics-card'>", unsafe_allow_html=True)
671
- # st.metric("Total Detections", len(results.boxes))
672
- # st.markdown("</div>", unsafe_allow_html=True)
673
- # with col2:
674
- # st.markdown("<div class='metrics-card'>", unsafe_allow_html=True)
675
- # avg_conf = float(torch.mean(results.boxes.conf).item())
676
- # st.metric("Average Confidence", f"{avg_conf:.2%}")
677
- # st.markdown("</div>", unsafe_allow_html=True)
678
- # with col3:
679
- # st.markdown("<div class='metrics-card'>", unsafe_allow_html=True)
680
- # unique_classes = len(set(results.boxes.cls.cpu().numpy()))
681
- # st.metric("Unique Sign Types", unique_classes)
682
- # st.markdown("</div>", unsafe_allow_html=True)
683
 
684
- # else:
685
- # st.warning("No traffic signs detected in this image.")
686
-
687
- # # Footer
688
- # st.markdown("---")
689
- # st.markdown(
690
- # """
691
- # <div style='text-align: center'>
692
- # <p>Traffic Sign Detection System | Built with Streamlit and YOLOv8</p>
693
- # <p>Deployed on Hugging Face Spaces | 2024</p>
694
- # </div>
695
- # """,
696
- # unsafe_allow_html=True
697
- # )
698
 
699
- # # Help section in sidebar
700
- # with st.sidebar:
701
- # st.markdown("---")
702
- # with st.expander("ℹ️ Help & Instructions"):
703
- # st.markdown("""
704
- # ### How to Use:
705
- # 1. Upload an image containing traffic signs
706
- # 2. Adjust the confidence threshold if needed
707
- # 3. Click 'Analyze Image' to start detection
708
- # 4. View results and analytics
709
 
710
- # ### Features:
711
- # - Real-time traffic sign detection
712
- # - Advanced analytics visualization
713
- # - Confidence score analysis
714
- # - Multiple sign detection support
715
 
716
- # ### Tips:
717
- # - Use clear, well-lit images
718
- # - Adjust confidence threshold for better results
719
- # - Enable analytics for detailed insights
720
- # """)
721
 
722
- # if __name__ == "__main__":
723
- # try:
724
- # main()
725
- # except Exception as e:
726
- # st.error(f"An error occurred: {str(e)}")
727
- # st.error("Please refresh the page and try again.")
728
 
729
 
730
 
 
1
 
2
+ # import streamlit as st
3
+ # from PIL import Image
4
+ # import torch
5
+ # import cv2
6
+ # import numpy as np
7
+ # from datetime import datetime
8
+ # import plotly.express as px
9
+ # import plotly.graph_objects as go
10
+ # import pandas as pd
11
+ # from ultralytics import YOLO
12
+ # import os
13
+ # import io
14
+ # from fpdf import FPDF
15
+ # import base64
16
 
17
+ # # Page config
18
+ # st.set_page_config(
19
+ # page_title="Traffic Sign Detection System",
20
+ # page_icon="🚦",
21
+ # layout="wide",
22
+ # initial_sidebar_state="expanded"
23
+ # )
24
 
25
+ # # Custom CSS
26
+ # st.markdown("""
27
+ # <style>
28
+ # .stApp {
29
+ # background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
30
+ # color: #e5e5e5;
31
+ # }
32
+ # .upload-box {
33
+ # border: 2px dashed #4a4a8a;
34
+ # border-radius: 15px;
35
+ # padding: 30px;
36
+ # text-align: center;
37
+ # background: rgba(255,255,255,0.05);
38
+ # backdrop-filter: blur(10px);
39
+ # transition: all 0.3s ease;
40
+ # }
41
+ # .upload-box:hover {
42
+ # border-color: #6a6aaa;
43
+ # background: rgba(255,255,255,0.08);
44
+ # }
45
+ # .detection-box {
46
+ # background: rgba(255,255,255,0.07);
47
+ # padding: 25px;
48
+ # border-radius: 15px;
49
+ # margin: 15px 0;
50
+ # box-shadow: 0 4px 15px rgba(0,0,0,0.2);
51
+ # }
52
+ # .metrics-card {
53
+ # background: rgba(255,255,255,0.1);
54
+ # padding: 20px;
55
+ # border-radius: 10px;
56
+ # margin: 10px 0;
57
+ # transition: transform 0.3s ease;
58
+ # }
59
+ # .metrics-card:hover {
60
+ # transform: translateY(-5px);
61
+ # }
62
+ # .confidence-meter {
63
+ # height: 20px;
64
+ # background: rgba(255,255,255,0.1);
65
+ # border-radius: 10px;
66
+ # overflow: hidden;
67
+ # box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
68
+ # }
69
+ # .header-container {
70
+ # padding: 20px;
71
+ # background: rgba(255,255,255,0.05);
72
+ # border-radius: 15px;
73
+ # margin-bottom: 20px;
74
+ # text-align: center;
75
+ # }
76
+ # .stButton>button {
77
+ # background: linear-gradient(45deg, #3498db, #2980b9);
78
+ # color: white;
79
+ # border: none;
80
+ # padding: 10px 20px;
81
+ # border-radius: 8px;
82
+ # transition: all 0.3s ease;
83
+ # }
84
+ # .stButton>button:hover {
85
+ # transform: translateY(-2px);
86
+ # box-shadow: 0 5px 15px rgba(0,0,0,0.2);
87
+ # }
88
+ # </style>
89
+ # """, unsafe_allow_html=True)
90
 
91
+ # # Initialize session state
92
+ # if 'model' not in st.session_state:
93
+ # st.session_state.model = None
94
+ # st.session_state.total_analyses = 0
95
 
96
+ # @st.cache_resource
97
+ # def load_model():
98
+ # """Load and cache the YOLO model"""
99
+ # try:
100
+ # model = YOLO('best.pt')
101
+ # return model
102
+ # except Exception as e:
103
+ # st.error(f"Error loading model: {str(e)}")
104
+ # return None
105
 
106
+ # def create_confidence_bar(confidence):
107
+ # """Create a visual confidence meter"""
108
+ # colors = {
109
+ # "high": "#00ff00",
110
+ # "medium": "#ffaa00",
111
+ # "low": "#ff0000"
112
+ # }
113
+ # color = colors["high"] if confidence > 0.7 else colors["medium"] if confidence > 0.5 else colors["low"]
114
+ # return f"""
115
+ # <div class="confidence-meter">
116
+ # <div style="width:{confidence*100}%; height:100%; background:{color};
117
+ # transition:width 0.5s; text-align:center; color:white; line-height:20px;">
118
+ # {confidence:.1%}
119
+ # </div>
120
+ # </div>
121
+ # """
122
 
123
+ # def create_visualization(results, model):
124
+ # """Create visualization plots for detection results"""
125
+ # if len(results.boxes) > 0:
126
+ # # Prepare data for visualization
127
+ # confidences = results.boxes.conf.cpu().numpy()
128
+ # classes = [model.names[int(cls)] for cls in results.boxes.cls.cpu().numpy()]
129
 
130
+ # # Create confidence distribution plot
131
+ # fig_conf = go.Figure(data=[go.Histogram(x=confidences, nbinsx=20)])
132
+ # fig_conf.update_layout(
133
+ # title="Confidence Score Distribution",
134
+ # xaxis_title="Confidence Score",
135
+ # yaxis_title="Count",
136
+ # template="plotly_dark"
137
+ # )
138
 
139
+ # # Create class distribution plot
140
+ # class_counts = pd.Series(classes).value_counts()
141
+ # fig_class = px.pie(values=class_counts.values, names=class_counts.index,
142
+ # title="Distribution of Detected Signs")
143
+ # fig_class.update_layout(template="plotly_dark")
144
 
145
+ # return fig_conf, fig_class
146
+ # return None, None
147
 
148
+ # class PDF(FPDF):
149
+ # def header(self):
150
+ # self.set_font('Arial', 'B', 20)
151
+ # self.cell(0, 10, 'Traffic Sign Detection Report', 0, 1, 'C')
152
+ # self.ln(10)
153
 
154
+ # def footer(self):
155
+ # self.set_y(-15)
156
+ # self.set_font('Arial', 'I', 8)
157
+ # self.cell(0, 10, f'Report generated on {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}', 0, 0, 'C')
158
+
159
+ # def generate_pdf_report(original_image, detected_image, results, model, analytics_enabled=True):
160
+ # """Generate a PDF report with detection results and analytics"""
161
+ # pdf = PDF()
162
+ # pdf.add_page()
163
+
164
+ # # Add timestamp
165
+ # pdf.set_font('Arial', '', 12)
166
+ # pdf.cell(0, 10, f'Analysis Date: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}', 0, 1)
167
+ # pdf.ln(5)
168
+
169
+ # # Save and add images
170
+ # # Original Image
171
+ # pdf.set_font('Arial', 'B', 14)
172
+ # pdf.cell(0, 10, 'Original Image', 0, 1)
173
+
174
+ # # Convert original image to RGB if needed
175
+ # if len(original_image.shape) == 3 and original_image.shape[2] == 3:
176
+ # original_image_rgb = cv2.cvtColor(original_image, cv2.COLOR_BGR2RGB)
177
+ # else:
178
+ # original_image_rgb = original_image
179
 
180
+ # # Save original image
181
+ # orig_img_path = 'temp_original.jpg'
182
+ # cv2.imwrite(orig_img_path, cv2.cvtColor(original_image_rgb, cv2.COLOR_RGB2BGR))
183
+ # pdf.image(orig_img_path, x=10, w=190)
184
+ # pdf.ln(10)
185
+
186
+ # # Detection Results
187
+ # pdf.set_font('Arial', 'B', 14)
188
+ # pdf.cell(0, 10, 'Detection Results', 0, 1)
189
+
190
+ # # Save detected image
191
+ # detected_img_path = 'temp_detected.jpg'
192
+ # cv2.imwrite(detected_img_path, cv2.cvtColor(detected_image, cv2.COLOR_RGB2BGR))
193
+ # pdf.image(detected_img_path, x=10, w=190)
194
+ # pdf.ln(10)
195
+
196
+ # # Detection Details
197
+ # pdf.set_font('Arial', 'B', 14)
198
+ # pdf.cell(0, 10, 'Detection Details', 0, 1)
199
+ # pdf.set_font('Arial', '', 12)
200
 
201
+ # if len(results.boxes) > 0:
202
+ # # Summary statistics
203
+ # avg_conf = float(torch.mean(results.boxes.conf).item())
204
+ # unique_classes = len(set(results.boxes.cls.cpu().numpy()))
205
 
206
+ # pdf.cell(0, 10, f'Total Detections: {len(results.boxes)}', 0, 1)
207
+ # pdf.cell(0, 10, f'Average Confidence: {avg_conf:.2%}', 0, 1)
208
+ # pdf.cell(0, 10, f'Unique Sign Types: {unique_classes}', 0, 1)
209
+ # pdf.ln(5)
210
 
211
+ # # Detailed detections
212
+ # pdf.set_font('Arial', 'B', 12)
213
+ # pdf.cell(0, 10, 'Detailed Detections:', 0, 1)
214
+ # pdf.set_font('Arial', '', 12)
215
 
216
+ # for idx, box in enumerate(results.boxes):
217
+ # class_id = int(box.cls[0])
218
+ # conf = float(box.conf[0])
219
+ # class_name = model.names[class_id]
220
+ # box_coords = box.xyxy[0].cpu().numpy()
221
 
222
+ # pdf.cell(0, 10, f'Detection {idx+1}:', 0, 1)
223
+ # pdf.cell(0, 10, f' • Sign Type: {class_name}', 0, 1)
224
+ # pdf.cell(0, 10, f' • Confidence: {conf:.2%}', 0, 1)
225
+ # pdf.cell(0, 10, f' • Location: x1={box_coords[0]:.1f}, y1={box_coords[1]:.1f}, x2={box_coords[2]:.1f}, y2={box_coords[3]:.1f}', 0, 1)
226
+ # pdf.ln(5)
227
+ # else:
228
+ # pdf.cell(0, 10, 'No traffic signs detected in this image.', 0, 1)
229
+
230
+ # # Clean up temporary files
231
+ # try:
232
+ # os.remove(orig_img_path)
233
+ # os.remove(detected_img_path)
234
+ # except:
235
+ # pass
236
 
237
+ # # Save to bytes
238
+ # pdf_bytes = io.BytesIO()
239
+ # pdf.output(pdf_bytes)
240
+ # pdf_bytes.seek(0)
241
 
242
+ # return pdf_bytes
243
 
244
+ # def main():
245
+ # # Header
246
+ # st.markdown("""
247
+ # <div class="header-container">
248
+ # <h1>🚦 Traffic Sign Detection System</h1>
249
+ # <p>Upload an image to detect and analyze traffic signs</p>
250
+ # </div>
251
+ # """, unsafe_allow_html=True)
252
 
253
+ # # Sidebar
254
+ # with st.sidebar:
255
+ # st.header("📊 Analysis Settings")
256
+ # # confidence_threshold = st.slider("Detection Confidence Threshold", 0.0, 1.0, 0.25, 0.05) = st.slider("Detection Confidence Threshold", 0.0, 1.0, 0.25, 0.05)
257
+
258
+ # confidence_threshold = st.slider("Detection Confidence Threshold", 0.0, 1.0, 0.25, 0.05)
259
+ # enable_analytics = st.checkbox("Enable Advanced Analytics", True)
260
 
261
+ # # Main content
262
+ # col1, col2 = st.columns([2, 1])
263
 
264
+ # with col1:
265
+ # st.markdown("<div class='upload-box'>", unsafe_allow_html=True)
266
+ # uploaded_file = st.file_uploader(
267
+ # "Drop your traffic sign image here or click to upload",
268
+ # type=['jpg', 'jpeg', 'png']
269
+ # )
270
+ # st.markdown("</div>", unsafe_allow_html=True)
271
 
272
+ # with col2:
273
+ # st.markdown("<div class='metrics-card'>", unsafe_allow_html=True)
274
+ # st.markdown("### 📈 System Statistics")
275
+ # st.metric("Total Analyses", st.session_state.total_analyses)
276
+ # st.markdown("</div>", unsafe_allow_html=True)
277
 
278
+ # if uploaded_file:
279
+ # # Load and process image
280
+ # image_bytes = uploaded_file.read()
281
+ # image = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)
282
 
283
+ # col1, col2 = st.columns(2)
284
 
285
+ # with col1:
286
+ # st.markdown("### Original Image")
287
+ # image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
288
+ # st.image(image_rgb)
289
 
290
+ # if st.button("🔍 Analyze Image", key="analyze_button"):
291
+ # st.session_state.total_analyses += 1
292
 
293
+ # with st.spinner("Processing image..."):
294
+ # # Load model if not already loaded
295
+ # if st.session_state.model is None:
296
+ # st.session_state.model = load_model()
297
 
298
+ # if st.session_state.model is not None:
299
+ # # Progress bar
300
+ # progress_text = "Running analysis..."
301
+ # progress_bar = st.progress(0)
302
+ # # for i in range(100):
303
+ # # progress_bar.progress(i + 1)
304
+ # # if i == 30:
305
+ # # progress_text = "Detecting signs..."
306
+ # # elif i == 60:
307
+ # # progress_text = "Analyzing patterns..."
308
+ # # elif i == 90:
309
+ # # progress_text = "Preparing results..."
310
+ # # st.write(progress_text)
311
 
312
+ # # Run inference
313
+ # results = st.session_state.model.predict(source=image, conf=confidence_threshold)[0]
314
 
315
+ # with col2:
316
+ # st.markdown("### Detection Results")
317
+ # plotted_image = results.plot()
318
+ # plotted_image_rgb = cv2.cvtColor(plotted_image, cv2.COLOR_BGR2RGB)
319
+ # st.image(plotted_image_rgb)
320
 
321
+ # # Display detections and analytics
322
+ # if len(results.boxes) > 0:
323
+ # st.markdown("<div class='detection-box'>", unsafe_allow_html=True)
324
+ # st.markdown("### 🎯 Detection Details")
325
 
326
+ # for idx, box in enumerate(results.boxes):
327
+ # class_id = int(box.cls[0])
328
+ # conf = float(box.conf[0])
329
+ # class_name = st.session_state.model.names[class_id]
330
 
331
+ # with st.expander(f"Detection {idx+1}: {class_name} ({conf:.2%})"):
332
+ # st.markdown(create_confidence_bar(conf), unsafe_allow_html=True)
333
+ # box_coords = box.xyxy[0].cpu().numpy()
334
+ # st.markdown(f"**Location:** x1={box_coords[0]:.1f}, y1={box_coords[1]:.1f}, x2={box_coords[2]:.1f}, y2={box_coords[3]:.1f}")
335
 
336
+ # if enable_analytics:
337
+ # st.markdown("### 📊 Analytics")
338
+ # fig_conf, fig_class = create_visualization(results, st.session_state.model)
339
+ # if fig_conf and fig_class:
340
+ # col1, col2 = st.columns(2)
341
+ # with col1:
342
+ # st.plotly_chart(fig_conf, use_container_width=True)
343
+ # with col2:
344
+ # st.plotly_chart(fig_class, use_container_width=True)
345
 
346
+ # # Summary metrics
347
+ # col1, col2, col3 = st.columns(3)
348
+ # with col1:
349
+ # st.markdown("<div class='metrics-card'>", unsafe_allow_html=True)
350
+ # st.metric("Total Detections", len(results.boxes))
351
+ # st.markdown("</div>", unsafe_allow_html=True)
352
+ # with col2:
353
+ # st.markdown("<div class='metrics-card'>", unsafe_allow_html=True)
354
+ # # avg_conf = float(torch.mean(results.boxes
355
+ # avg_conf = float(torch.mean(results.boxes.conf).item())
356
+ # st.metric("Average Confidence", f"{avg_conf:.1%}")
357
+ # st.markdown("</div>", unsafe_allow_html=True)
358
+ # with col3:
359
+ # st.markdown("<div class='metrics-card'>", unsafe_allow_html=True)
360
+ # unique_classes = len(set(results.boxes.cls.cpu().numpy()))
361
+ # st.metric("Unique Sign Types", unique_classes)
362
+ # st.markdown("</div>", unsafe_allow_html=True)
363
 
364
+ # # Generate and offer PDF report download
365
+ # st.markdown("### 📄 Download Report")
366
+ # pdf_bytes = generate_pdf_report(
367
+ # image,
368
+ # plotted_image,
369
+ # results,
370
+ # st.session_state.model,
371
+ # analytics_enabled=enable_analytics
372
+ # )
373
 
374
+ # # Create download button with custom styling
375
+ # st.markdown("""
376
+ # <style>
377
+ # .download-button {
378
+ # background: linear-gradient(45deg, #2ecc71, #27ae60);
379
+ # color: white;
380
+ # padding: 12px 24px;
381
+ # border-radius: 8px;
382
+ # border: none;
383
+ # cursor: pointer;
384
+ # transition: all 0.3s ease;
385
+ # text-decoration: none;
386
+ # display: inline-block;
387
+ # margin: 10px 0;
388
+ # }
389
+ # .download-button:hover {
390
+ # transform: translateY(-2px);
391
+ # box-shadow: 0 5px 15px rgba(0,0,0,0.2);
392
+ # }
393
+ # </style>
394
+ # """, unsafe_allow_html=True)
395
 
396
+ # # Convert PDF bytes to base64 for download
397
+ # b64_pdf = base64.b64encode(pdf_bytes.getvalue()).decode()
398
+ # href = f'<a href="data:application/pdf;base64,{b64_pdf}" download="traffic_sign_report.pdf" class="download-button">📥 Download Detection Report</a>'
399
+ # st.markdown(href, unsafe_allow_html=True)
400
 
401
+ # st.markdown("</div>", unsafe_allow_html=True)
402
+ # else:
403
+ # st.warning("No traffic signs detected in the image.")
404
+ # else:
405
+ # st.error("Failed to load the model. Please check if the model file exists and try again.")
406
 
407
 
408
+ # if __name__ == "__main__":
409
+ # try:
410
+ # main()
411
+ # except Exception as e:
412
+ # st.error(f"An error occurred: {str(e)}")
413
+ # st.error("Please refresh the page and try again.")
414
 
415
 
416
 
 
423
 
424
 
425
 
426
+ import streamlit as st
427
+ from PIL import Image
428
+ import torch
429
+ import cv2
430
+ import numpy as np
431
+ from datetime import datetime
432
+ import plotly.express as px
433
+ import plotly.graph_objects as go
434
+ import pandas as pd
435
+ from ultralytics import YOLO
436
+ import os
437
 
438
+ # Page config
439
+ st.set_page_config(
440
+ page_title="Traffic Sign Detection System",
441
+ page_icon="🚦",
442
+ layout="wide",
443
+ initial_sidebar_state="expanded"
444
+ )
445
 
446
+ # Custom CSS with improved styling
447
+ st.markdown("""
448
+ <style>
449
+ .stApp {
450
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
451
+ color: #e5e5e5;
452
+ }
453
+ .upload-box {
454
+ border: 2px dashed #4a4a8a;
455
+ border-radius: 15px;
456
+ padding: 30px;
457
+ text-align: center;
458
+ background: rgba(255,255,255,0.05);
459
+ backdrop-filter: blur(10px);
460
+ transition: all 0.3s ease;
461
+ }
462
+ .upload-box:hover {
463
+ border-color: #6a6aaa;
464
+ background: rgba(255,255,255,0.08);
465
+ }
466
+ .detection-box {
467
+ background: rgba(255,255,255,0.07);
468
+ padding: 25px;
469
+ border-radius: 15px;
470
+ margin: 15px 0;
471
+ box-shadow: 0 4px 15px rgba(0,0,0,0.2);
472
+ }
473
+ .metrics-card {
474
+ background: rgba(255,255,255,0.1);
475
+ padding: 20px;
476
+ border-radius: 10px;
477
+ margin: 10px 0;
478
+ transition: transform 0.3s ease;
479
+ }
480
+ .metrics-card:hover {
481
+ transform: translateY(-5px);
482
+ }
483
+ .confidence-meter {
484
+ height: 20px;
485
+ background: rgba(255,255,255,0.1);
486
+ border-radius: 10px;
487
+ overflow: hidden;
488
+ box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
489
+ }
490
+ .header-container {
491
+ padding: 20px;
492
+ background: rgba(255,255,255,0.05);
493
+ border-radius: 15px;
494
+ margin-bottom: 20px;
495
+ text-align: center;
496
+ }
497
+ .stButton>button {
498
+ background: linear-gradient(45deg, #3498db, #2980b9);
499
+ color: white;
500
+ border: none;
501
+ padding: 10px 20px;
502
+ border-radius: 8px;
503
+ transition: all 0.3s ease;
504
+ }
505
+ .stButton>button:hover {
506
+ transform: translateY(-2px);
507
+ box-shadow: 0 5px 15px rgba(0,0,0,0.2);
508
+ }
509
+ </style>
510
+ """, unsafe_allow_html=True)
511
 
512
+ # Initialize session state
513
+ if 'model' not in st.session_state:
514
+ st.session_state.model = None
515
+ st.session_state.total_analyses = 0
516
 
517
+ @st.cache_resource
518
+ def load_model():
519
+ """Load and cache the YOLO model"""
520
+ try:
521
+ model = YOLO('best.pt')
522
+ return model
523
+ except Exception as e:
524
+ st.error(f"Error loading model: {str(e)}")
525
+ return None
526
 
527
+ def create_confidence_bar(confidence):
528
+ """Create a visual confidence meter"""
529
+ colors = {
530
+ "high": "#00ff00",
531
+ "medium": "#ffaa00",
532
+ "low": "#ff0000"
533
+ }
534
+ color = colors["high"] if confidence > 0.7 else colors["medium"] if confidence > 0.5 else colors["low"]
535
+ return f"""
536
+ <div class="confidence-meter">
537
+ <div style="width:{confidence*100}%; height:100%; background:{color};
538
+ transition:width 0.5s; text-align:center; color:white; line-height:20px;">
539
+ {confidence:.1%}
540
+ </div>
541
+ </div>
542
+ """
543
 
544
+ def create_visualization(results, model):
545
+ """Create visualization plots for detection results"""
546
+ if len(results.boxes) > 0:
547
+ # Prepare data for visualization
548
+ confidences = results.boxes.conf.cpu().numpy()
549
+ classes = [model.names[int(cls)] for cls in results.boxes.cls.cpu().numpy()]
550
 
551
+ # Create confidence distribution plot
552
+ fig_conf = go.Figure(data=[go.Histogram(x=confidences, nbinsx=20)])
553
+ fig_conf.update_layout(
554
+ title="Confidence Score Distribution",
555
+ xaxis_title="Confidence Score",
556
+ yaxis_title="Count",
557
+ template="plotly_dark"
558
+ )
559
 
560
+ # Create class distribution plot
561
+ class_counts = pd.Series(classes).value_counts()
562
+ fig_class = px.pie(values=class_counts.values, names=class_counts.index,
563
+ title="Distribution of Detected Signs")
564
+ fig_class.update_layout(template="plotly_dark")
565
 
566
+ return fig_conf, fig_class
567
+ return None, None
568
 
569
+ def main():
570
+ # Header
571
+ st.markdown("""
572
+ <div class="header-container">
573
+ <h1>🚦 Traffic Sign Detection System</h1>
574
+ <p>Upload an image to detect and analyze traffic signs</p>
575
+ </div>
576
+ """, unsafe_allow_html=True)
577
 
578
+ # Sidebar
579
+ with st.sidebar:
580
+ st.header("📊 Analysis Settings")
581
+ confidence_threshold = st.slider("Detection Confidence Threshold", 0.0, 1.0, 0.25, 0.05)
582
+ enable_analytics = st.checkbox("Enable Advanced Analytics", True)
583
 
584
+ # Main content
585
+ col1, col2 = st.columns([2, 1])
586
 
587
+ with col1:
588
+ st.markdown("<div class='upload-box'>", unsafe_allow_html=True)
589
+ uploaded_file = st.file_uploader(
590
+ "Drop your traffic sign image here or click to upload",
591
+ type=['jpg', 'jpeg', 'png']
592
+ )
593
+ st.markdown("</div>", unsafe_allow_html=True)
594
 
595
+ with col2:
596
+ st.markdown("<div class='metrics-card'>", unsafe_allow_html=True)
597
+ st.markdown("### 📈 System Statistics")
598
+ st.metric("Total Analyses", st.session_state.total_analyses)
599
+ st.markdown("</div>", unsafe_allow_html=True)
600
 
601
+ if uploaded_file:
602
+ # Load and process image
603
+ image_bytes = uploaded_file.read()
604
+ image = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)
605
 
606
+ col1, col2 = st.columns(2)
607
 
608
+ with col1:
609
+ st.markdown("### Original Image")
610
+ image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
611
+ st.image(image_rgb)
612
 
613
+ if st.button("🔍 Analyze Image", key="analyze_button"):
614
+ st.session_state.total_analyses += 1
615
 
616
+ with st.spinner("Processing image..."):
617
+ # Load model if not already loaded
618
+ if st.session_state.model is None:
619
+ st.session_state.model = load_model()
620
 
621
+ if st.session_state.model is not None:
622
+ # Progress bar
623
+ progress_text = "Running analysis..."
624
+ progress_bar = st.progress(0)
625
+ # for i in range(100):
626
+ # progress_bar.progress(i + 1)
627
+ # if i == 30:
628
+ # progress_text = "Detecting signs..."
629
+ # elif i == 60:
630
+ # progress_text = "Analyzing patterns..."
631
+ # elif i == 90:
632
+ # progress_text = "Preparing results..."
633
+ # st.write(progress_text)
634
 
635
+ # Run inference
636
+ results = st.session_state.model.predict(source=image, conf=confidence_threshold)[0]
637
 
638
+ with col2:
639
+ st.markdown("### Detection Results")
640
+ plotted_image = results.plot()
641
+ plotted_image_rgb = cv2.cvtColor(plotted_image, cv2.COLOR_BGR2RGB)
642
+ st.image(plotted_image_rgb)
643
 
644
+ # Display detections and analytics
645
+ if len(results.boxes) > 0:
646
+ st.markdown("<div class='detection-box'>", unsafe_allow_html=True)
647
+ st.markdown("### 🎯 Detection Details")
648
 
649
+ for idx, box in enumerate(results.boxes):
650
+ class_id = int(box.cls[0])
651
+ conf = float(box.conf[0])
652
+ class_name = st.session_state.model.names[class_id]
653
 
654
+ with st.expander(f"Detection {idx+1}: {class_name} ({conf:.2%})"):
655
+ st.markdown(create_confidence_bar(conf), unsafe_allow_html=True)
656
+ box_coords = box.xyxy[0].cpu().numpy()
657
+ st.markdown(f"**Location:** x1={box_coords[0]:.1f}, y1={box_coords[1]:.1f}, x2={box_coords[2]:.1f}, y2={box_coords[3]:.1f}")
658
 
659
+ if enable_analytics:
660
+ st.markdown("### 📊 Analytics")
661
+ fig_conf, fig_class = create_visualization(results, st.session_state.model)
662
+ if fig_conf and fig_class:
663
+ col1, col2 = st.columns(2)
664
+ with col1:
665
+ st.plotly_chart(fig_conf, use_container_width=True)
666
+ with col2:
667
+ st.plotly_chart(fig_class, use_container_width=True)
668
 
669
+ # Summary metrics
670
+ col1, col2, col3 = st.columns(3)
671
+ with col1:
672
+ st.markdown("<div class='metrics-card'>", unsafe_allow_html=True)
673
+ st.metric("Total Detections", len(results.boxes))
674
+ st.markdown("</div>", unsafe_allow_html=True)
675
+ with col2:
676
+ st.markdown("<div class='metrics-card'>", unsafe_allow_html=True)
677
+ avg_conf = float(torch.mean(results.boxes.conf).item())
678
+ st.metric("Average Confidence", f"{avg_conf:.2%}")
679
+ st.markdown("</div>", unsafe_allow_html=True)
680
+ with col3:
681
+ st.markdown("<div class='metrics-card'>", unsafe_allow_html=True)
682
+ unique_classes = len(set(results.boxes.cls.cpu().numpy()))
683
+ st.metric("Unique Sign Types", unique_classes)
684
+ st.markdown("</div>", unsafe_allow_html=True)
685
 
686
+ else:
687
+ st.warning("No traffic signs detected in this image.")
688
+
689
+ # Footer
690
+ st.markdown("---")
691
+ st.markdown(
692
+ """
693
+ <div style='text-align: center'>
694
+ <p>Traffic Sign Detection System | Built with Streamlit and YOLOv8</p>
695
+ <p>Deployed on Hugging Face Spaces | 2024</p>
696
+ </div>
697
+ """,
698
+ unsafe_allow_html=True
699
+ )
700
 
701
+ # Help section in sidebar
702
+ with st.sidebar:
703
+ st.markdown("---")
704
+ with st.expander("ℹ️ Help & Instructions"):
705
+ st.markdown("""
706
+ ### How to Use:
707
+ 1. Upload an image containing traffic signs
708
+ 2. Adjust the confidence threshold if needed
709
+ 3. Click 'Analyze Image' to start detection
710
+ 4. View results and analytics
711
 
712
+ ### Features:
713
+ - Real-time traffic sign detection
714
+ - Advanced analytics visualization
715
+ - Confidence score analysis
716
+ - Multiple sign detection support
717
 
718
+ ### Tips:
719
+ - Use clear, well-lit images
720
+ - Adjust confidence threshold for better results
721
+ - Enable analytics for detailed insights
722
+ """)
723
 
724
+ if __name__ == "__main__":
725
+ try:
726
+ main()
727
+ except Exception as e:
728
+ st.error(f"An error occurred: {str(e)}")
729
+ st.error("Please refresh the page and try again.")
730
 
731
 
732