alexandrephiev's picture
feat: YOLO image segmentation with Gradio UI
6242e13
import gradio as gr
import cv2
import numpy as np
from ultralytics import YOLO
def detect_and_crop_spines(image, model_path):
# Cache the YOLO model to avoid reloading it for every inference
if not hasattr(detect_and_crop_spines, 'model'):
detect_and_crop_spines.model = YOLO(model_path)
# Convert gradio image to CV2 format if needed
if isinstance(image, str):
image = cv2.imread(image)
elif isinstance(image, np.ndarray) and len(image.shape) == 3 and image.shape[2] == 3:
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
# Add error handling for image loading
if image is None:
raise ValueError("Failed to load image")
# Use confidence threshold and add error handling for predictions
try:
results = detect_and_crop_spines.model.predict(image, show=False, conf=0.25)
except Exception as e:
return None, f"Error during detection: {str(e)}"
annotated_image = image.copy()
for det in enumerate(results[0].boxes.xyxy.cpu().numpy()):
# Get corner points
points = np.array([[det[0], det[1]], [det[2], det[1]],
[det[2], det[3]], [det[0], det[3]]], dtype=np.float32)
# Get minimum area rectangle
rect = cv2.minAreaRect(points)
box = cv2.boxPoints(rect)
box = np.int0(box)
# Draw rotated rectangle
cv2.drawContours(annotated_image, [box], 0, (0, 255, 0), 2)
# Convert back to RGB for Gradio
annotated_image = cv2.cvtColor(annotated_image, cv2.COLOR_BGR2RGB)
return annotated_image, f"Detected {len(results[0].boxes)} book spines"
# Create Gradio interface
demo = gr.Interface(
fn=detect_and_crop_spines,
inputs=[
gr.Image(),
gr.Text(label="YOLO Model Path", value="yolo11x.pt")
],
outputs=[
gr.Image(label="Annotated Image"),
gr.Text(label="Detection Results")
],
title="Book Spine Detector",
description="Upload an image of a bookshelf to detect book spines using YOLO"
)
# Launch the app
demo.launch()