VietCat commited on
Commit
74ac36a
·
1 Parent(s): 81a35ad

Add auto-detection, interactive zoom, and class names to top 5 detections

Browse files

- Auto-detect on image upload and threshold slider change
- Add Clear button to reset all fields
- Show class names alongside top 5 raw confidence scores
- Mark output images as non-interactive for better UX
- Update UI description for auto-detection feature

Files changed (2) hide show
  1. app.py +31 -5
  2. model.py +7 -1
app.py CHANGED
@@ -38,14 +38,14 @@ def detect_traffic_signs(image, confidence_threshold):
38
  # Create Gradio interface
39
  with gr.Blocks(title="Traffic Sign Detector") as demo:
40
  gr.Markdown("# Traffic Sign Detector")
41
- gr.Markdown("Upload an image to detect traffic signs using YOLOv8.")
42
 
43
  with gr.Row():
44
  input_image = gr.Image(label="Upload Image", type="pil")
45
- output_image = gr.Image(label="Detected Signs")
46
 
47
  with gr.Row():
48
- preprocessed_image = gr.Image(label="Preprocessed Image (640x640, Letterboxed)")
49
 
50
  with gr.Row():
51
  confidence_threshold = gr.Slider(
@@ -57,12 +57,38 @@ with gr.Blocks(title="Traffic Sign Detector") as demo:
57
  info="Lower values show more detections (less confident). Adjust to find optimal balance."
58
  )
59
 
60
- detect_btn = gr.Button("Detect Traffic Signs")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  detect_btn.click(
62
  fn=detect_traffic_signs,
63
  inputs=[input_image, confidence_threshold],
64
  outputs=[output_image, preprocessed_image],
65
- queue=True # Enable queue to ensure logs are shown
 
 
 
 
 
 
66
  )
67
 
68
  if __name__ == "__main__":
 
38
  # Create Gradio interface
39
  with gr.Blocks(title="Traffic Sign Detector") as demo:
40
  gr.Markdown("# Traffic Sign Detector")
41
+ gr.Markdown("Upload an image to detect traffic signs using YOLOv8. Detection runs automatically when you upload or adjust the threshold.")
42
 
43
  with gr.Row():
44
  input_image = gr.Image(label="Upload Image", type="pil")
45
+ output_image = gr.Image(label="Detected Signs", interactive=False)
46
 
47
  with gr.Row():
48
+ preprocessed_image = gr.Image(label="Preprocessed Image (640x640, Letterboxed)", interactive=False)
49
 
50
  with gr.Row():
51
  confidence_threshold = gr.Slider(
 
57
  info="Lower values show more detections (less confident). Adjust to find optimal balance."
58
  )
59
 
60
+ with gr.Row():
61
+ detect_btn = gr.Button("Detect Traffic Signs", variant="primary")
62
+ reset_btn = gr.Button("Clear")
63
+
64
+ # Auto-detect when image is uploaded
65
+ input_image.change(
66
+ fn=detect_traffic_signs,
67
+ inputs=[input_image, confidence_threshold],
68
+ outputs=[output_image, preprocessed_image],
69
+ queue=True
70
+ )
71
+
72
+ # Auto-detect when threshold is changed
73
+ confidence_threshold.change(
74
+ fn=detect_traffic_signs,
75
+ inputs=[input_image, confidence_threshold],
76
+ outputs=[output_image, preprocessed_image],
77
+ queue=True
78
+ )
79
+
80
+ # Manual detection button
81
  detect_btn.click(
82
  fn=detect_traffic_signs,
83
  inputs=[input_image, confidence_threshold],
84
  outputs=[output_image, preprocessed_image],
85
+ queue=True
86
+ )
87
+
88
+ # Clear button
89
+ reset_btn.click(
90
+ fn=lambda: (None, None, None),
91
+ outputs=[input_image, output_image, preprocessed_image]
92
  )
93
 
94
  if __name__ == "__main__":
model.py CHANGED
@@ -207,7 +207,13 @@ class TrafficSignDetector:
207
 
208
  if results_raw and len(results_raw[0].boxes) > 0:
209
  all_raw_confs = [float(box.conf[0]) for box in results_raw[0].boxes]
210
- print(f" - Top 5 raw confidences: {[f'{c:.6f}' for c in sorted(all_raw_confs, reverse=True)[:5]]}")
 
 
 
 
 
 
211
  print(f" - Confidence stats: min={min(all_raw_confs):.6f}, max={max(all_raw_confs):.6f}, mean={np.mean(all_raw_confs):.6f}")
212
  print(f" - Confidences > 0.01: {sum(1 for c in all_raw_confs if c > 0.01)}")
213
  print(f" - Confidences > 0.001: {sum(1 for c in all_raw_confs if c > 0.001)}")
 
207
 
208
  if results_raw and len(results_raw[0].boxes) > 0:
209
  all_raw_confs = [float(box.conf[0]) for box in results_raw[0].boxes]
210
+
211
+ # Get top 5 with class names
212
+ boxes_with_conf = [(float(box.conf[0]), int(box.cls[0].cpu().numpy())) for box in results_raw[0].boxes]
213
+ top_5 = sorted(boxes_with_conf, key=lambda x: x[0], reverse=True)[:5]
214
+ top_5_str = [f"{c:.6f} ({self.classes[cls]})" for c, cls in top_5]
215
+
216
+ print(f" - Top 5 raw confidences: {top_5_str}")
217
  print(f" - Confidence stats: min={min(all_raw_confs):.6f}, max={max(all_raw_confs):.6f}, mean={np.mean(all_raw_confs):.6f}")
218
  print(f" - Confidences > 0.01: {sum(1 for c in all_raw_confs if c > 0.01)}")
219
  print(f" - Confidences > 0.001: {sum(1 for c in all_raw_confs if c > 0.001)}")