from ultralytics import YOLO import gradio as gr from PIL import Image import torch # (kept, since you already imported it) # Load model model = YOLO("best.pt") # make sure best.pt is in the same folder # Prediction function (same idea: YOLO predict -> plot -> return image + label) def predict(inp): if inp is None: return None, {} results = model.predict(source=inp, conf=0.5, iou=0.5, imgsz=640) r = results[0] output_img = r.plot()[:, :, ::-1] # convert BGR to RGB for Gradio # Convert annotated output to PIL annotated = Image.fromarray(output_img) # Build label dictionary for gr.Label (class -> confidence) label_dict = {} # If detections exist, aggregate by class using highest confidence if hasattr(r, "boxes") and r.boxes is not None and len(r.boxes) > 0: names = model.names if hasattr(model, "names") else {} cls = r.boxes.cls.tolist() conf = r.boxes.conf.tolist() best = {} for c, p in zip(cls, conf): c = int(c) best[c] = max(best.get(c, 0.0), float(p)) # Sort top predictions by confidence for c, p in sorted(best.items(), key=lambda x: x[1], reverse=True): label_dict[names.get(c, str(c))] = p return annotated, label_dict # ----------------------------- # UI ONLY (layout + styling) # ----------------------------- CSS = """ :root { --radius: 16px; } #page { max-width: 1200px; margin: 0 auto; } .hero { padding: 18px 18px 8px 18px; border-radius: var(--radius); border: 1px solid rgba(255,255,255,0.08); background: linear-gradient(180deg, rgba(255,126,0,0.10), rgba(0,0,0,0.0)); } .hero h1 { font-size: 28px; line-height: 1.1; margin: 0 0 6px 0; } .hero p { margin: 0; opacity: 0.9; } .card { border-radius: var(--radius) !important; border: 1px solid rgba(255,255,255,0.10) !important; background: rgba(255,255,255,0.03) !important; } .btn-primary button { background: linear-gradient(90deg, #ff7a00, #ff4d00) !important; border: 0 !important; border-radius: 14px !important; font-weight: 700 !important; } .btn-ghost button { border-radius: 14px !important; font-weight: 600 !important; } .small-muted { font-size: 12px; opacity: 0.75; } .gradio-container .prose h3 { margin-top: 6px !important; } """ with gr.Blocks( css=CSS, theme=gr.themes.Soft( radius_size="lg", text_size="md" ), ) as demo: with gr.Column(elem_id="page"): gr.HTML( """
Upload an image of a pill. The YOLOv12 model detects and classifies pill types commonly found in the Philippines. This study aims to automate pill recognition for pharmaceutical verification and healthcare support.
Tip: Use clear lighting, avoid blur, and keep pills centered for best results.