YOLO26-ONNX

This repository contains ONNX exports of every Ultralytics YOLO26 model variant. YOLO26 is a unified, real-time vision model family covering object detection, instance segmentation, oriented bounding box detection, pose estimation, and image classification, with native end-to-end NMS-free inference and no Distribution Focal Loss head.

Each variant here was converted from the original PyTorch weights using model.export(format="onnx") and placed in its own folder. The exports are meant to be used directly with ONNX Runtime, with no ultralytics package required at inference time.

Model Variants

Five scales (n, s, m, l, x) across five tasks, 25 variants in total.

Size Detect Segment OBB Pose Classify
n yolo26n yolo26n-seg yolo26n-obb yolo26n-pose yolo26n-cls
s yolo26s yolo26s-seg yolo26s-obb yolo26s-pose yolo26s-cls
m yolo26m yolo26m-seg yolo26m-obb yolo26m-pose yolo26m-cls
l yolo26l yolo26l-seg yolo26l-obb yolo26l-pose yolo26l-cls
x yolo26x yolo26x-seg yolo26x-obb yolo26x-pose yolo26x-cls

Repository Structure

YOLO26-ONNX/
├── README.md
├── yolo26n/yolo26n.onnx
├── yolo26s/yolo26s.onnx
├── yolo26m/yolo26m.onnx
├── yolo26l/yolo26l.onnx
├── yolo26x/yolo26x.onnx
├── yolo26n-seg/yolo26n-seg.onnx
├── yolo26s-seg/yolo26s-seg.onnx
├── yolo26m-seg/yolo26m-seg.onnx
├── yolo26l-seg/yolo26l-seg.onnx
├── yolo26x-seg/yolo26x-seg.onnx
├── yolo26n-obb/yolo26n-obb.onnx
├── yolo26s-obb/yolo26s-obb.onnx
├── yolo26m-obb/yolo26m-obb.onnx
├── yolo26l-obb/yolo26l-obb.onnx
├── yolo26x-obb/yolo26x-obb.onnx
├── yolo26n-pose/yolo26n-pose.onnx
├── yolo26s-pose/yolo26s-pose.onnx
├── yolo26m-pose/yolo26m-pose.onnx
├── yolo26l-pose/yolo26l-pose.onnx
├── yolo26x-pose/yolo26x-pose.onnx
├── yolo26n-cls/yolo26n-cls.onnx
├── yolo26s-cls/yolo26s-cls.onnx
├── yolo26m-cls/yolo26m-cls.onnx
├── yolo26l-cls/yolo26l-cls.onnx
├── yolo26x-cls/yolo26x-cls.onnx
└── yolo26_onnx_utils.py

Run with ONNX

!pip install \
gradio \
ultralytics \
huggingface_hub \
onnx>=1.16.0 \
onnxslim>=0.1.31 \
onnxruntime>=1.18.0 \
opencv-python-headless>=4.9.0 \
numpy
import json
import tempfile
import time
from pathlib import Path

import cv2
import gradio as gr
import numpy as np
import onnxruntime as ort
import PIL.Image as Image
from huggingface_hub import hf_hub_download

# ============================================================================
# Config
# ============================================================================

MODEL_REPO = "prithivMLmods/YOLO26-ONNX"

SIZES = ["n", "s", "m", "l", "x"]
TASK_SUFFIX = {"detect": "", "seg": "-seg", "obb": "-obb", "pose": "-pose", "cls": "-cls"}
TASK_ORDER = ["detect", "seg", "obb", "pose", "cls"]
TASK_IMGSZ = {"detect": 640, "seg": 640, "obb": 640, "pose": 640, "cls": 224}
IMAGE_SIZE_CHOICES = [320, 640, 1024]


def variant_name(size, task):
    return f"yolo26{size}{TASK_SUFFIX[task]}"


MODEL_CHOICES = [variant_name(s, t) for t in TASK_ORDER for s in SIZES]

COCO80 = [
    "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat",
    "traffic light", "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat",
    "dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "backpack",
    "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball",
    "kite", "baseball bat", "baseball glove", "skateboard", "surfboard", "tennis racket",
    "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",
    "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair",
    "couch", "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse",
    "remote", "keyboard", "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator",
    "book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush",
]

# COCO 17-keypoint skeleton (0-indexed) + keypoint colors
POSE_SKELETON = [
    (15, 13), (13, 11), (16, 14), (14, 12), (11, 12), (5, 11), (6, 12), (5, 6), (5, 7),
    (6, 8), (7, 9), (8, 10), (1, 2), (0, 1), (0, 2), (1, 3), (2, 4), (3, 5), (4, 6),
]


def class_color(idx):
    """Deterministic BGR color per class index."""
    hue = (idx * 47) % 180
    hsv = np.uint8([[[hue, 200, 255]]])
    bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)[0][0]
    return tuple(int(c) for c in bgr)


# ============================================================================
# Model cache + preload
# ============================================================================

MODEL_CACHE = {}  # name -> dict(session, task, imgsz, input_name, output_names)
_IMAGENET_LABELS = None


def task_for_name(name):
    for task in ("cls", "seg", "obb", "pose"):  # check longest/most-specific suffixes first
        if name.endswith(TASK_SUFFIX[task]) and TASK_SUFFIX[task]:
            return task
    return "detect"


def load_imagenet_labels():
    """Lazily fetch ImageNet-1k id->label names (used by yolo26*-cls variants)."""
    global _IMAGENET_LABELS
    if _IMAGENET_LABELS is not None:
        return _IMAGENET_LABELS
    try:
        path = hf_hub_download(repo_id="huggingface/label-files", filename="imagenet-1k-id2label.json", repo_type="dataset")
        with open(path) as f:
            id2label = json.load(f)
        _IMAGENET_LABELS = [id2label[str(i)] for i in range(len(id2label))]
    except Exception as e:
        print(f"[YOLO26-ONNX] could not load ImageNet labels ({e}); classification will show raw indices.")
        _IMAGENET_LABELS = []
    return _IMAGENET_LABELS


def preload_all_models():
    providers = ["CUDAExecutionProvider", "CPUExecutionProvider"]
    print(f"[YOLO26-ONNX] preloading {len(MODEL_CHOICES)} variants from {MODEL_REPO} ...")
    for i, name in enumerate(MODEL_CHOICES):
        task = task_for_name(name)
        t0 = time.time()
        try:
            onnx_path = hf_hub_download(repo_id=MODEL_REPO, filename=f"{name}/{name}.onnx")
            session = ort.InferenceSession(onnx_path, providers=providers)
            in_shape = session.get_inputs()[0].shape
            h = in_shape[2] if isinstance(in_shape[2], int) else TASK_IMGSZ[task]
            w = in_shape[3] if isinstance(in_shape[3], int) else TASK_IMGSZ[task]
            MODEL_CACHE[name] = {
                "session": session,
                "task": task,
                "imgsz": (h, w),
                "input_name": session.get_inputs()[0].name,
                "output_names": [o.name for o in session.get_outputs()],
            }
            print(f"[YOLO26-ONNX] [{i + 1}/{len(MODEL_CHOICES)}] loaded {name} ({task}) in {time.time() - t0:.1f}s")
        except Exception as e:
            print(f"[YOLO26-ONNX] [{i + 1}/{len(MODEL_CHOICES)}] FAILED to load {name}: {e}")

    if any(task_for_name(n) == "cls" for n in MODEL_CACHE):
        load_imagenet_labels()

    print(f"[YOLO26-ONNX] preload complete: {len(MODEL_CACHE)}/{len(MODEL_CHOICES)} models ready.")


preload_all_models()

# ============================================================================
# Preprocessing
# ============================================================================


def letterbox(image, new_shape=640, color=(114, 114, 114)):
    if isinstance(new_shape, int):
        new_shape = (new_shape, new_shape)
    h0, w0 = image.shape[:2]
    r = min(new_shape[0] / h0, new_shape[1] / w0)
    new_unpad = (int(round(w0 * r)), int(round(h0 * r)))
    dw = (new_shape[1] - new_unpad[0]) / 2
    dh = (new_shape[0] - new_unpad[1]) / 2
    if (w0, h0) != new_unpad:
        image = cv2.resize(image, new_unpad, interpolation=cv2.INTER_LINEAR)
    top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
    left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
    image = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
    return image, r, (left, top)


def preprocess_spatial(image_bgr, imgsz):
    padded, ratio, pad = letterbox(image_bgr, imgsz)
    img = padded[:, :, ::-1].transpose(2, 0, 1)
    img = np.ascontiguousarray(img, dtype=np.float32) / 255.0
    return img[None], ratio, pad, image_bgr.shape[:2]


def preprocess_cls(image_bgr, imgsz):
    """Classification preprocessing: plain resize (no letterbox padding)."""
    h, w = imgsz
    resized = cv2.resize(image_bgr, (w, h), interpolation=cv2.INTER_LINEAR)
    img = resized[:, :, ::-1].transpose(2, 0, 1)
    img = np.ascontiguousarray(img, dtype=np.float32) / 255.0
    return img[None]


def scale_xy_back(xy, ratio, pad, orig_shape):
    out = xy.copy()
    out[..., 0] -= pad[0]
    out[..., 1] -= pad[1]
    out /= ratio
    h0, w0 = orig_shape
    out[..., 0] = out[..., 0].clip(0, w0)
    out[..., 1] = out[..., 1].clip(0, h0)
    return out


def scale_boxes_back(boxes_xyxy, ratio, pad, orig_shape):
    boxes = boxes_xyxy.copy()
    boxes[:, [0, 2]] -= pad[0]
    boxes[:, [1, 3]] -= pad[1]
    boxes /= ratio
    h0, w0 = orig_shape
    boxes[:, [0, 2]] = boxes[:, [0, 2]].clip(0, w0)
    boxes[:, [1, 3]] = boxes[:, [1, 3]].clip(0, h0)
    return boxes


def extra_nms(boxes, scores, classes, iou_thres):
    """Optional belt-and-suspenders NMS per class on top of YOLO26's native
    end-to-end (NMS-free) output. Usually a no-op since the model already
    returns filtered detections, but keeps the IoU slider meaningful."""
    if len(boxes) == 0:
        return np.arange(0)
    keep_all = []
    for c in np.unique(classes):
        idx = np.where(classes == c)[0]
        b = boxes[idx]
        s = scores[idx]
        xywh = np.stack([b[:, 0], b[:, 1], b[:, 2] - b[:, 0], b[:, 3] - b[:, 1]], axis=1)
        keep = cv2.dnn.NMSBoxes(xywh.tolist(), s.tolist(), score_threshold=0.0, nms_threshold=iou_thres)
        if len(keep) > 0:
            keep = np.array(keep).reshape(-1)
            keep_all.extend(idx[keep].tolist())
    return np.array(sorted(keep_all), dtype=int)


# ============================================================================
# Inference + decode
# ============================================================================


def run_inference(model_name, image_bgr, conf_thres, iou_thres, imgsz_override=None):
    entry = MODEL_CACHE[model_name]
    session, task = entry["session"], entry["task"]
    imgsz = (int(imgsz_override), int(imgsz_override)) if imgsz_override else entry["imgsz"]

    if task == "cls":
        blob = preprocess_cls(image_bgr, imgsz)
        outputs = session.run(entry["output_names"], {entry["input_name"]: blob})
        logits = outputs[0][0]
        exp = np.exp(logits - logits.max())
        probs = exp / exp.sum()
        top5_idx = probs.argsort()[::-1][:5]
        labels = load_imagenet_labels()
        top5_labels = [labels[i] if labels and i < len(labels) else str(i) for i in top5_idx]
        return {"task": "cls", "top5_idx": top5_idx, "top5_conf": probs[top5_idx], "top5_labels": top5_labels}

    blob, ratio, pad, orig_shape = preprocess_spatial(image_bgr, imgsz)
    outputs = session.run(entry["output_names"], {entry["input_name"]: blob})

    det = outputs[0]
    if det.ndim == 3:
        det = det[0]
    keep = det[:, 4] >= conf_thres
    det = det[keep]

    result = {"task": task, "boxes": np.zeros((0, 4)), "scores": np.zeros((0,)), "classes": np.zeros((0,), dtype=int)}
    if det.shape[0] == 0:
        return result

    boxes = scale_boxes_back(det[:, :4].astype(np.float32), ratio, pad, orig_shape)
    scores = det[:, 4]
    classes = det[:, 5].astype(int)

    order = extra_nms(boxes, scores, classes, iou_thres)
    if len(order) == 0:
        return result
    boxes, scores, classes, det = boxes[order], scores[order], classes[order], det[order]

    result.update(boxes=boxes, scores=scores, classes=classes)

    if task == "obb" and det.shape[1] >= 7:
        result["angles"] = det[:, 6]
    elif task == "pose" and det.shape[1] > 6:
        n_kpt = (det.shape[1] - 6) // 3
        kpts = det[:, 6:6 + n_kpt * 3].reshape(-1, n_kpt, 3).copy()
        kpts[..., :2] = scale_xy_back(kpts[..., :2], ratio, pad, orig_shape)
        result["keypoints"] = kpts
    elif task == "seg" and len(outputs) > 1:
        proto = outputs[1][0]  # (32, mh, mw)
        n_mask = proto.shape[0]
        mask_coeffs = det[:, 6:6 + n_mask]
        result["masks"] = decode_masks(mask_coeffs, proto, pad, orig_shape, imgsz)

    return result


def decode_masks(mask_coeffs, proto, pad, orig_shape, imgsz):
    n_mask, mh, mw = proto.shape
    proto_flat = proto.reshape(n_mask, -1)
    masks = 1 / (1 + np.exp(-(mask_coeffs @ proto_flat)))
    masks = masks.reshape(-1, mh, mw)
    ih, iw = imgsz
    h0, w0 = orig_shape
    left, top = pad
    out = np.zeros((masks.shape[0], h0, w0), dtype=np.uint8)
    for i, m in enumerate(masks):
        m_full = cv2.resize(m, (iw, ih), interpolation=cv2.INTER_LINEAR)
        m_cropped = m_full[top: ih - top, left: iw - left]
        if m_cropped.size == 0:
            m_cropped = m_full
        m_resized = cv2.resize(m_cropped, (w0, h0), interpolation=cv2.INTER_LINEAR)
        out[i] = (m_resized > 0.5).astype(np.uint8)
    return out


def obb_corners(box, angle):
    """box=[x1,y1,x2,y2] axis-aligned extent, angle in radians -> 4 rotated corner points.
    NOTE: verify angle sign/units against your specific export in Netron before
    relying on this for anything beyond visualization."""
    x1, y1, x2, y2 = box
    cx, cy = (x1 + x2) / 2, (y1 + y2) / 2
    w, h = x2 - x1, y2 - y1
    cos_a, sin_a = np.cos(angle), np.sin(angle)
    pts = np.array([[-w / 2, -h / 2], [w / 2, -h / 2], [w / 2, h / 2], [-w / 2, h / 2]])
    rot = np.array([[cos_a, -sin_a], [sin_a, cos_a]])
    pts = pts @ rot.T + np.array([cx, cy])
    return pts.astype(int)


# ============================================================================
# Drawing
# ============================================================================


def draw_result(image_bgr, result, show_labels=True, show_conf=True, class_names=None):
    img = image_bgr.copy()
    task = result["task"]

    if task == "cls":
        for i, (label, conf) in enumerate(zip(result["top5_labels"], result["top5_conf"])):
            text = f"{label}: {conf * 100:.1f}%" if show_conf else label
            cv2.putText(img, text, (10, 30 + 28 * i), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0), 4, cv2.LINE_AA)
            cv2.putText(img, text, (10, 30 + 28 * i), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 1, cv2.LINE_AA)
        return img

    names = class_names or (COCO80 if task != "pose" else ["person"])
    boxes, scores, classes = result["boxes"], result["scores"], result["classes"]

    for i in range(len(boxes)):
        cls_id = int(classes[i])
        color = class_color(cls_id)
        label_txt = names[cls_id] if cls_id < len(names) else str(cls_id)
        if show_conf:
            label_txt = f"{label_txt} {scores[i]:.2f}"

        if task == "obb" and "angles" in result:
            pts = obb_corners(boxes[i], result["angles"][i])
            cv2.polylines(img, [pts], True, color, 2)
            anchor = tuple(pts[0])
        else:
            x1, y1, x2, y2 = boxes[i].astype(int)
            cv2.rectangle(img, (x1, y1), (x2, y2), color, 2)
            anchor = (x1, y1)

        if show_labels:
            (tw, th), _ = cv2.getTextSize(label_txt, cv2.FONT_HERSHEY_SIMPLEX, 0.55, 1)
            ax, ay = anchor
            cv2.rectangle(img, (ax, max(0, ay - th - 6)), (ax + tw + 4, ay), color, -1)
            cv2.putText(img, label_txt, (ax + 2, max(12, ay - 4)), cv2.FONT_HERSHEY_SIMPLEX, 0.55, (255, 255, 255), 1, cv2.LINE_AA)

        if task == "seg" and "masks" in result and i < len(result["masks"]):
            mask = result["masks"][i].astype(bool)
            overlay = img.copy()
            overlay[mask] = color
            img = cv2.addWeighted(overlay, 0.4, img, 0.6, 0)

        if task == "pose" and "keypoints" in result:
            kpts = result["keypoints"][i]
            for x, y, v in kpts:
                if v > 0.3:
                    cv2.circle(img, (int(x), int(y)), 3, (0, 255, 0), -1)
            for a, b in POSE_SKELETON:
                if a < len(kpts) and b < len(kpts) and kpts[a][2] > 0.3 and kpts[b][2] > 0.3:
                    pa, pb = kpts[a][:2].astype(int), kpts[b][:2].astype(int)
                    cv2.line(img, tuple(pa), tuple(pb), (0, 200, 255), 2)

    return img


# ============================================================================
# Gradio callbacks
# ============================================================================


def predict_image(img, conf_threshold, iou_threshold, model_name, show_labels, show_conf, imgsz):
    if img is None or model_name not in MODEL_CACHE:
        return None
    image_bgr = cv2.cvtColor(np.array(img.convert("RGB")), cv2.COLOR_RGB2BGR)
    result = run_inference(model_name, image_bgr, conf_threshold, iou_threshold, imgsz)
    annotated = draw_result(image_bgr, result, show_labels, show_conf)
    return Image.fromarray(cv2.cvtColor(annotated, cv2.COLOR_BGR2RGB))


def predict_video(video_path, conf_threshold, iou_threshold, model_name, show_labels, show_conf, imgsz):
    if video_path is None or model_name not in MODEL_CACHE:
        return None

    cap = cv2.VideoCapture(video_path)
    if not cap.isOpened():
        return None

    fps = int(cap.get(cv2.CAP_PROP_FPS)) or 25
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

    temp_output = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False)
    output_path = temp_output.name
    temp_output.close()

    fourcc = cv2.VideoWriter_fourcc(*"mp4v")
    out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))

    while True:
        ret, frame = cap.read()
        if not ret:
            break
        result = run_inference(model_name, frame, conf_threshold, iou_threshold, imgsz)
        annotated = draw_result(frame, result, show_labels, show_conf)
        out.write(annotated)

    cap.release()
    out.release()
    return output_path


def predict_webcam(frame, conf_threshold, iou_threshold, model_name, show_labels, show_conf, imgsz):
    if frame is None or model_name not in MODEL_CACHE:
        return None
    if isinstance(frame, np.ndarray):
        frame_bgr = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
        result = run_inference(model_name, frame_bgr, conf_threshold, iou_threshold, imgsz)
        annotated = draw_result(frame_bgr, result, show_labels, show_conf)
        return cv2.cvtColor(annotated, cv2.COLOR_BGR2RGB)
    return None


# ============================================================================
# UI
# ============================================================================

with gr.Blocks(title="YOLO26-ONNX") as demo:
    gr.Markdown(
        f"""
# YOLO26-ONNX

Real-time detection, segmentation, OBB, pose, and classification, running
pure ONNX Runtime, no ultralytics install required at inference time.
All {len(MODEL_CHOICES)} model variants are pulled from
[{MODEL_REPO}](https://huggingface.co/{MODEL_REPO}) and preloaded at startup
({len(MODEL_CACHE)}/{len(MODEL_CHOICES)} loaded successfully).
"""
    )

    with gr.Tabs():
        with gr.TabItem("Image"):
            with gr.Row():
                with gr.Column():
                    img_input = gr.Image(type="pil", label="Upload Image")
                    img_conf = gr.Slider(minimum=0, maximum=1, value=0.25, label="Confidence threshold")
                    img_iou = gr.Slider(minimum=0, maximum=1, value=0.7, label="IoU threshold (extra NMS pass)")
                    img_model = gr.Radio(choices=MODEL_CHOICES, label="Model", value="yolo26n")
                    img_labels = gr.Checkbox(value=True, label="Show Labels")
                    img_conf_show = gr.Checkbox(value=True, label="Show Confidence")
                    img_size = gr.Radio(choices=IMAGE_SIZE_CHOICES, label="Image Size", value=640)
                    img_btn = gr.Button("Detect", variant="primary")
                with gr.Column():
                    img_output = gr.Image(type="pil", label="Result")

            img_btn.click(
                predict_image,
                inputs=[img_input, img_conf, img_iou, img_model, img_labels, img_conf_show, img_size],
                outputs=img_output,
            )

            gr.Examples(
                examples=[
                    ["https://ultralytics.com/images/bus.jpg", 0.25, 0.7, "yolo26n", True, True, 640],
                    ["https://ultralytics.com/images/zidane.jpg", 0.25, 0.7, "yolo26n-seg", True, True, 640],
                    ["https://ultralytics.com/images/boats.jpg", 0.25, 0.7, "yolo26n-obb", True, True, 1024],
                    ["https://ultralytics.com/images/zidane.jpg", 0.25, 0.7, "yolo26n-pose", True, True, 640],
                    ["https://ultralytics.com/images/bus.jpg", 0.25, 0.7, "yolo26n-cls", True, True, 224],
                ],
                inputs=[img_input, img_conf, img_iou, img_model, img_labels, img_conf_show, img_size],
            )

        with gr.TabItem("Video"):
            with gr.Row():
                with gr.Column():
                    vid_input = gr.Video(label="Upload Video")
                    vid_conf = gr.Slider(minimum=0, maximum=1, value=0.25, label="Confidence threshold")
                    vid_iou = gr.Slider(minimum=0, maximum=1, value=0.7, label="IoU threshold (extra NMS pass)")
                    vid_model = gr.Radio(choices=MODEL_CHOICES, label="Model", value="yolo26n")
                    vid_labels = gr.Checkbox(value=True, label="Show Labels")
                    vid_conf_show = gr.Checkbox(value=True, label="Show Confidence")
                    vid_size = gr.Radio(choices=IMAGE_SIZE_CHOICES, label="Image Size", value=640)
                    vid_btn = gr.Button("Process Video", variant="primary")
                with gr.Column():
                    vid_output = gr.Video(label="Result")

            vid_btn.click(
                predict_video,
                inputs=[vid_input, vid_conf, vid_iou, vid_model, vid_labels, vid_conf_show, vid_size],
                outputs=vid_output,
            )

        with gr.TabItem("Webcam"):
            gr.Markdown("### Real-time Webcam Inference")
            with gr.Row():
                with gr.Column():
                    webcam_conf = gr.Slider(minimum=0, maximum=1, value=0.25, label="Confidence threshold")
                    webcam_iou = gr.Slider(minimum=0, maximum=1, value=0.7, label="IoU threshold (extra NMS pass)")
                    webcam_model = gr.Radio(choices=MODEL_CHOICES, label="Model", value="yolo26n")
                    webcam_labels = gr.Checkbox(value=True, label="Show Labels")
                    webcam_conf_show = gr.Checkbox(value=True, label="Show Confidence")
                    webcam_size = gr.Radio(choices=IMAGE_SIZE_CHOICES, label="Image Size", value=640)
                with gr.Column():
                    webcam_input = gr.Image(sources=["webcam"], type="numpy", label="Webcam (streaming)", streaming=True)
                    webcam_output = gr.Image(type="numpy", label="Detection Result")

            webcam_input.stream(
                predict_webcam,
                inputs=[webcam_input, webcam_conf, webcam_iou, webcam_model, webcam_labels, webcam_conf_show, webcam_size],
                outputs=webcam_output,
            )

if __name__ == "__main__":
    demo.launch(ssr_mode=False)

Output Format Notes

  • Detection heads are exported end-to-end (NMS-free): the primary output is shaped (1, 300, 6) as [x1, y1, x2, y2, confidence, class_id] in letterboxed pixel coordinates, already filtered without a separate NMS step.
  • Segmentation, pose, and OBB variants append extra columns to that same row: mask coefficients plus a separate prototype tensor for segment, keypoints for pose, and a rotation angle for OBB.
  • Classification variants output a single (1, num_classes) logits vector; softmax is applied client-side.
  • The OBB angle convention (sign and units) has not been independently verified against every export; check it in Netron before relying on it beyond visualization.
  • Semantic segmentation (-sem) variants are not included in this repository, only the five task heads shown above.

License

Ultralytics YOLO26 code, training, and export paths are distributed under AGPL-3.0, with a separate Enterprise License available from Ultralytics for closed-source use. These ONNX exports inherit that license from the base model.

Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for prithivMLmods/YOLO26-ONNX

Quantized
(30)
this model