Custom YOLOv9 ball detector for amateur-level soccer footage. 22 MB.
Fuente del modelo
Descripción de la fuente
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.
Both (Ultralytics format) and are in this repo.
Fuentes
1 fuenteVerificado 27 sept
Artefactos del modelo
2 artefactosExtractos de fuentes
2 extractosv9b_best.ptv9b_best.onnxpip 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
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.
Custom labeled set of amateur soccer match frames, sideline camera, 1080p, varied venues + lighting. Training data not redistributed.
Per-frame ball grounding in the soccer-video-pipeline kickoff-pattern detector. Also useful as a standalone amateur-soccer ball detector.
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).
--- license: agpl-3.0 tags: - yolo - yolov9 - object-detection - soccer - ball-detection - ultralytics library_name: ultralytics --- # 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](https://github.com/acato/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) ```bash pip install onnxruntime opencv-python numpy ``` ```python 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) ```python 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 typ...
Source context: 94 downloads · 2 likes · Pipeline object-detection · Library ultralytics · Repo acatorcini/yolov9-soccer-ball