danielritchie commited on
Commit
2d7bad3
·
verified ·
1 Parent(s): dfdc486

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -0
app.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import cv2
3
+ import numpy as np
4
+ from ultralytics import YOLO
5
+ import torch
6
+
7
+ # Initialize models
8
+ duck_model = YOLO('https://huggingface.co/brainwavecollective/yolo8n-rubber-duck-detector/resolve/main/yolov8n_rubberducks4.pt')
9
+ standard_model = YOLO('yolov8n.pt')
10
+
11
+ def calculate_iou(box1, box2):
12
+ x1 = max(box1[0], box2[0])
13
+ y1 = max(box1[1], box2[1])
14
+ x2 = min(box1[2], box2[2])
15
+ y2 = min(box1[3], box2[3])
16
+ intersection = max(0, x2 - x1) * max(0, y2 - y1)
17
+
18
+ box1_area = (box1[2] - box1[0]) * (box1[3] - box1[1])
19
+ box2_area = (box2[2] - box2[0]) * (box2[3] - box2[1])
20
+ union = box1_area + box2_area - intersection
21
+
22
+ return intersection / union if union > 0 else 0
23
+
24
+ def process_image(image, model, is_duck_model=True):
25
+ results = model(image, conf=0.4)
26
+
27
+ valid_boxes = []
28
+ for r in results:
29
+ for box in r.boxes:
30
+ class_name = model.names[int(box.cls[0])]
31
+ # For both models, only show teddy bear class
32
+ if class_name == "teddy bear":
33
+ valid_boxes.append({
34
+ 'coords': box.xyxy[0].cpu().numpy().tolist(),
35
+ 'confidence': float(box.conf[0])
36
+ })
37
+
38
+ # Filter overlapping boxes
39
+ filtered_boxes = []
40
+ for i, box in enumerate(valid_boxes):
41
+ should_add = True
42
+ for existing_box in filtered_boxes:
43
+ if calculate_iou(box['coords'], existing_box['coords']) > 0.5:
44
+ if box['confidence'] <= existing_box['confidence']:
45
+ should_add = False
46
+ break
47
+ if should_add:
48
+ filtered_boxes.append(box)
49
+
50
+ # Draw boxes and labels
51
+ processed_image = image.copy()
52
+ for box in filtered_boxes:
53
+ x1, y1, x2, y2 = map(int, box['coords'])
54
+ cv2.rectangle(processed_image, (x1, y1), (x2, y2), (0, 255, 0), 2)
55
+ label = f"{'Duck' if is_duck_model else 'Standard'} ({box['confidence']:.2f})"
56
+ cv2.putText(processed_image, label, (x1, y1-10),
57
+ cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
58
+
59
+ return processed_image, len(filtered_boxes)
60
+
61
+ def compare_models(input_image):
62
+ # Convert from Gradio's PIL image to OpenCV format
63
+ image = np.array(input_image)
64
+
65
+ # Process with both models
66
+ duck_image, duck_detections = process_image(image, duck_model, True)
67
+ standard_image, std_detections = process_image(image, standard_model, False)
68
+
69
+ # Create side-by-side comparison
70
+ height, width = image.shape[:2]
71
+ canvas = np.zeros((height, width * 2, 3), dtype=np.uint8)
72
+
73
+ # Place images side by side
74
+ canvas[:, :width] = duck_image
75
+ canvas[:, width:] = standard_image
76
+
77
+ # Add labels for each model
78
+ cv2.putText(canvas, "Rubber Duck YOLO", (10, 30),
79
+ cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
80
+ cv2.putText(canvas, f"Detections: {duck_detections}", (10, 60),
81
+ cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
82
+
83
+ cv2.putText(canvas, "Standard YOLOv8", (width + 10, 30),
84
+ cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
85
+ cv2.putText(canvas, f"Detections: {std_detections}", (width + 10, 60),
86
+ cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
87
+
88
+ return canvas
89
+
90
+ # Create Gradio interface
91
+ iface = gr.Interface(
92
+ fn=compare_models,
93
+ inputs=gr.Image(type="pil"),
94
+ outputs=gr.Image(type="numpy"),
95
+ title="YOLO Model Comparison",
96
+ description="Compare Rubber Duck YOLO detector with standard YOLOv8 model",
97
+ examples=[["example1.jpg"], ["example2.jpg"]], # Add your example images here
98
+ cache_examples=True
99
+ )
100
+
101
+ # Launch the interface
102
+ if __name__ == "__main__":
103
+ iface.launch(share=True)