yolov9-soccer-ball

Custom YOLOv9 ball detector for amateur-level soccer footage. ~22 MB.

Standard YOLO weights (COCO etc.) struggle to detect a soccer ball at the small pixel scales typical of sideline-camera amateur footage (~3-5 px ball at 50 m distance, 1080p). This checkpoint was fine-tuned specifically on that regime and is the ball detector used by the soccer-video-pipeline project for per-frame ball grounding.

Two inference paths

Both v9b_best.pt (Ultralytics format) and v9b_best.onnx are in this repo. Use the ONNX path if you want to avoid the AGPL Ultralytics runtime dependency.

Option A β€” ONNX + onnxruntime (Apache 2.0 dependency chain)

pip install onnxruntime opencv-python numpy
import cv2, numpy as np, onnxruntime as ort

sess = ort.InferenceSession("v9b_best.onnx",
                            providers=["CPUExecutionProvider"])  # or CUDAExecutionProvider
img = cv2.imread("path/to/frame.jpg")
# preprocess: BGR->RGB, resize to 1280, normalize 0-1, NCHW
resized = cv2.resize(img, (1280, 1280))
x = resized[..., ::-1].transpose(2, 0, 1).astype(np.float32) / 255.0
x = x[None]  # (1, 3, 1280, 1280)

outputs = sess.run(None, {sess.get_inputs()[0].name: x})
# outputs[0] shape: (1, 5, N) for single-class YOLOv9 β€” x,y,w,h,conf per anchor
# Apply NMS + confidence threshold; see ultralytics/utils/ops.py for reference

Option B β€” Ultralytics (AGPL-3.0)

from ultralytics import YOLO
model = YOLO("v9b_best.pt")
results = model("path/to/frame.jpg")
for r in results:
    for box in r.boxes:
        x1, y1, x2, y2 = box.xyxy[0].tolist()
        conf = box.conf[0].item()
        print(f"ball at ({x1:.0f},{y1:.0f})-({x2:.0f},{y2:.0f})  conf={conf:.2f}")

The model outputs a single class (ball). The pipeline default threshold is conf > 0.2 β€” at amateur-distance footage ball-class confidence typically sits in 0.15-0.35.

Training data

Custom labeled set of amateur soccer match frames, sideline camera, 1080p, varied venues + lighting. Training data not redistributed.

Performance characteristics

  • Ball detection coverage: ~63% of frames in production (vs <5% for stock YOLO weights at this camera distance)
  • Useful confidence band: 0.15-0.35 β€” well below the typical "useful" threshold for object detection but the right band for tiny objects
  • Frame sampling rate in production: 5 seconds (so ~63% of those sparse samples have a detected ball)

Intended use

Per-frame ball grounding in the soccer-video-pipeline kickoff-pattern detector. Also useful as a standalone amateur-soccer ball detector.

Limitations

  • Trained for sideline-camera framings at amateur match distances. Performs worse on close-up footage or drone shots.
  • Single-class output (just ball) β€” no player detection.

License

The weights themselves carry AGPL-3.0 (inherited from the Ultralytics training framework that produced them). The ONNX runtime path lets you use the WEIGHTS without bundling the AGPL CODE β€” which is the relevant distinction for many downstream projects (your code and the AGPL training tool stay separable).

Related

Downloads last month
56
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support