Spaces:
Running
on
Zero
Running
on
Zero
Commit
·
ef654f1
1
Parent(s):
34e2c3f
wip
Browse files- app.py +5 -4
- detection/object_detection.py +54 -13
app.py
CHANGED
@@ -138,8 +138,9 @@ with gr.Blocks() as demo:
|
|
138 |
# Process Button
|
139 |
obj_process_btn = gr.Button("Detect Objects")
|
140 |
|
141 |
-
# Output
|
142 |
-
obj_image_output = gr.Image(label="Detected Objects")
|
|
|
143 |
|
144 |
# Link radio button change to visibility update function
|
145 |
obj_input_type.change(
|
@@ -151,11 +152,11 @@ with gr.Blocks() as demo:
|
|
151 |
)
|
152 |
|
153 |
# Link process button to the object detection function
|
154 |
-
# The object_detection function
|
155 |
obj_process_btn.click(
|
156 |
fn=object_detection,
|
157 |
inputs=[obj_input_type, obj_img_upload, obj_url_input, obj_base64_input],
|
158 |
-
outputs=obj_image_output,
|
159 |
)
|
160 |
|
161 |
# Launch the Gradio demo
|
|
|
138 |
# Process Button
|
139 |
obj_process_btn = gr.Button("Detect Objects")
|
140 |
|
141 |
+
# Output Components
|
142 |
+
obj_image_output = gr.Image(label="Detected Objects Image") # Updated label for clarity
|
143 |
+
obj_raw_output = gr.JSON(label="Raw Object Detection Data") # Added JSON output
|
144 |
|
145 |
# Link radio button change to visibility update function
|
146 |
obj_input_type.change(
|
|
|
152 |
)
|
153 |
|
154 |
# Link process button to the object detection function
|
155 |
+
# The object_detection function now returns a tuple (image, raw_data)
|
156 |
obj_process_btn.click(
|
157 |
fn=object_detection,
|
158 |
inputs=[obj_input_type, obj_img_upload, obj_url_input, obj_base64_input],
|
159 |
+
outputs=[obj_image_output, obj_raw_output], # Updated outputs
|
160 |
)
|
161 |
|
162 |
# Launch the Gradio demo
|
detection/object_detection.py
CHANGED
@@ -1,17 +1,29 @@
|
|
1 |
# Standard library imports
|
2 |
# (Add any necessary imports for future object detection implementation)
|
|
|
3 |
|
4 |
# Third-party imports
|
5 |
from PIL import Image
|
6 |
import numpy as np
|
|
|
7 |
|
8 |
# Local imports
|
9 |
from utils.image_utils import load_image, preprocess_image
|
10 |
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
def object_detection(input_type, uploaded_image, image_url, base64_string):
|
13 |
"""
|
14 |
-
Performs object detection on the image from various input types.
|
15 |
|
16 |
Args:
|
17 |
input_type (str): The selected input method ("Upload File", "Enter URL", "Enter Base64").
|
@@ -20,8 +32,14 @@ def object_detection(input_type, uploaded_image, image_url, base64_string):
|
|
20 |
base64_string (str): The image base64 string (if input_type is "Enter Base64").
|
21 |
|
22 |
Returns:
|
23 |
-
|
|
|
|
|
24 |
"""
|
|
|
|
|
|
|
|
|
25 |
image = None
|
26 |
input_value = None
|
27 |
|
@@ -39,28 +57,51 @@ def object_detection(input_type, uploaded_image, image_url, base64_string):
|
|
39 |
|
40 |
else:
|
41 |
print("No valid input provided for object detection based on selected type.")
|
42 |
-
return None
|
43 |
|
44 |
# If input_value is set (URL or Base64), use load_image
|
45 |
if input_value:
|
46 |
image = load_image(input_value)
|
47 |
if image is None:
|
48 |
-
return None
|
49 |
|
50 |
# Now 'image' should be a PIL Image or None
|
51 |
if image is None:
|
52 |
print("Image is None after loading/selection for object detection.")
|
53 |
-
return None
|
54 |
|
55 |
try:
|
56 |
# Preprocess the image (convert PIL to numpy, ensure RGB)
|
57 |
-
|
58 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
|
60 |
-
# TODO: Implement object detection logic here
|
61 |
-
# Currently just returns the processed image
|
62 |
-
print("Object detection logic placeholder executed.")
|
63 |
-
return processed_image
|
64 |
except Exception as e:
|
65 |
-
print(f"Error
|
66 |
-
return None
|
|
|
1 |
# Standard library imports
|
2 |
# (Add any necessary imports for future object detection implementation)
|
3 |
+
import json
|
4 |
|
5 |
# Third-party imports
|
6 |
from PIL import Image
|
7 |
import numpy as np
|
8 |
+
from ultralytics import YOLO
|
9 |
|
10 |
# Local imports
|
11 |
from utils.image_utils import load_image, preprocess_image
|
12 |
|
13 |
|
14 |
+
# Load the YOLOv8 model globally to avoid reloading on each function call
|
15 |
+
# Using a common pre-trained YOLOv8 nano model ('yolov8n.pt')
|
16 |
+
try:
|
17 |
+
model = YOLO('yolov8n.pt')
|
18 |
+
print("YOLOv8 model loaded successfully.")
|
19 |
+
except Exception as e:
|
20 |
+
print(f"Error loading YOLOv8 model: {e}")
|
21 |
+
model = None # Set model to None if loading fails
|
22 |
+
|
23 |
+
|
24 |
def object_detection(input_type, uploaded_image, image_url, base64_string):
|
25 |
"""
|
26 |
+
Performs object detection on the image from various input types using YOLOv8.
|
27 |
|
28 |
Args:
|
29 |
input_type (str): The selected input method ("Upload File", "Enter URL", "Enter Base64").
|
|
|
32 |
base64_string (str): The image base64 string (if input_type is "Enter Base64").
|
33 |
|
34 |
Returns:
|
35 |
+
tuple: A tuple containing:
|
36 |
+
- numpy.ndarray: The image with detected objects drawn on it, or None if an error occurred or model not loaded.
|
37 |
+
- dict: A dictionary containing the raw detection data (bounding boxes, classes, scores), or None.
|
38 |
"""
|
39 |
+
if model is None:
|
40 |
+
print("YOLOv8 model is not loaded. Cannot perform object detection.")
|
41 |
+
return None, None # Return None for both outputs
|
42 |
+
|
43 |
image = None
|
44 |
input_value = None
|
45 |
|
|
|
57 |
|
58 |
else:
|
59 |
print("No valid input provided for object detection based on selected type.")
|
60 |
+
return None, None # Return None for both outputs
|
61 |
|
62 |
# If input_value is set (URL or Base64), use load_image
|
63 |
if input_value:
|
64 |
image = load_image(input_value)
|
65 |
if image is None:
|
66 |
+
return None, None # load_image failed
|
67 |
|
68 |
# Now 'image' should be a PIL Image or None
|
69 |
if image is None:
|
70 |
print("Image is None after loading/selection for object detection.")
|
71 |
+
return None, None # Return None for both outputs
|
72 |
|
73 |
try:
|
74 |
# Preprocess the image (convert PIL to numpy, ensure RGB)
|
75 |
+
processed_image_np = preprocess_image(image)
|
76 |
+
|
77 |
+
# Perform inference
|
78 |
+
results = model.predict(processed_image_np)
|
79 |
+
|
80 |
+
# Extract raw detection data
|
81 |
+
raw_data = []
|
82 |
+
if results and results[0].boxes:
|
83 |
+
for box in results[0].boxes:
|
84 |
+
# box.xywh contains [x_center, y_center, width, height]
|
85 |
+
# box.conf contains confidence score
|
86 |
+
# box.cls contains class index
|
87 |
+
x_center, y_center, width, height = [round(float(coord), 2) for coord in box.xywh[0].tolist()] # Changed to xywh
|
88 |
+
confidence = round(float(box.conf[0]), 4)
|
89 |
+
class_id = int(box.cls[0])
|
90 |
+
class_name = model.names[class_id] if model.names else str(class_id) # Get class name if available
|
91 |
+
|
92 |
+
raw_data.append({
|
93 |
+
"box": {"x": x_center, "y": y_center, "w": width, "h": height}, # Updated keys
|
94 |
+
"confidence": confidence,
|
95 |
+
"class_id": class_id,
|
96 |
+
"class_name": class_name
|
97 |
+
})
|
98 |
+
|
99 |
+
# Draw results on the image
|
100 |
+
result_image_np = results[0].plot() if results else processed_image_np # Plot if results exist
|
101 |
+
|
102 |
+
print("Object detection performed successfully.")
|
103 |
+
return result_image_np, raw_data # Return both the image and raw data
|
104 |
|
|
|
|
|
|
|
|
|
105 |
except Exception as e:
|
106 |
+
print(f"Error during YOLOv8 object detection: {e}")
|
107 |
+
return None, None # Return None for both outputs
|