Skip to main content

Real-time sports analytics toolkit built on the Roboflow ecosystem

Project description

SportVision

Real-time sports analytics toolkit built on the Roboflow ecosystem. Detects players and ball via RF-DETR, tracks with ByteTrack, classifies teams by jersey color, and computes possession, speed, distance, and heatmaps.

Features

  • Detection — RF-DETR (base/large) with COCO→sports class mapping
  • Tracking — ByteTrack via supervision with fallback sequential IDs
  • Team Classification — KMeans on HSV jersey histograms
  • Homography — Pixel→field coordinate mapping via cv2.findHomography
  • Analytics — Possession, speed, distance, and heatmap generation
  • Annotation — Team-colored bounding boxes, stats overlay, player trails

Quick Start

pip install sportvision
from sportvision.pipeline import SportVisionPipeline

pipeline = SportVisionPipeline()
result = pipeline.process_frame(frame)

Roboflow Workflows Plugin

SportVision ships as a Roboflow Workflows plugin. Install with inference and activate:

pip install "sportvision[workflows]"
export WORKFLOWS_PLUGINS="sportvision.workflows"

This registers 4 blocks you can use in any Roboflow Workflow:

Block Type Identifier Description
Team Classifier sportvision/team_classifier@v1 Clusters players into teams by jersey color. refit_every=N to periodically refit KMeans.
Possession Tracker sportvision/possession_tracker@v1 Tracks ball possession per team over time. Warns when team_id is missing.
Distance Calculator sportvision/distance_calculator@v1 Cumulative distance per tracked player. Supports homography_matrix for field-unit distances.
Sports Detection Filter sportvision/sports_detection_filter@v1 Filters COCO detections to sports classes

Example: Using blocks directly in Python

import cv2
import numpy as np
import supervision as sv

from sportvision.workflows.team_classifier.v1 import TeamClassifierBlockV1
from sportvision.workflows.possession_tracker.v1 import PossessionTrackerBlockV1
from sportvision.workflows.distance_calculator.v1 import DistanceCalculatorBlockV1
from sportvision.workflows.sports_detection_filter.v1 import SportsDetectionFilterBlockV1

# --- Filter COCO detections to sports classes ---
det_filter = SportsDetectionFilterBlockV1()
# Assume `raw_detections` comes from a COCO model (person=0, sports_ball=32)
result = det_filter.run(detections=raw_detections)
detections = result["detections"]  # now player=0, ball=1

# --- Classify players into teams ---
team_block = TeamClassifierBlockV1()
# `image` must have a .numpy_image attribute (or use WorkflowImageData)
# refit_every=10 refits KMeans every 10 frames (0 = fit once, default)
result = team_block.run(image=image, detections=detections, n_teams=2, refit_every=10)
detections = result["detections"]  # detections.data["team_id"] is now set

# --- Track possession ---
possession_block = PossessionTrackerBlockV1()
result = possession_block.run(
    detections=detections,
    ball_class_id=1,
    ball_proximity_threshold=100.0,
)
print(result["possession_stats"])   # {0: 0.6, 1: 0.4}
print(result["possessing_team"])    # 0
print(result["warning"])            # "" or warning if team_id missing

# --- Compute distances ---
distance_block = DistanceCalculatorBlockV1()
# Optional: pass a 3x3 homography matrix for field-unit distances (e.g. meters)
result = distance_block.run(detections=detections, homography_matrix=[[0.01,0,0],[0,0.01,0],[0,0,1]])
print(result["detections"].data["distance"])  # cumulative distance per tracker

Example: Workflow JSON definition

{
  "steps": [
    {
      "type": "sportvision/sports_detection_filter@v1",
      "name": "filter",
      "detections": "$steps.model.predictions"
    },
    {
      "type": "sportvision/team_classifier@v1",
      "name": "teams",
      "image": "$inputs.image",
      "detections": "$steps.filter.detections",
      "n_teams": 2,
      "refit_every": 10
    },
    {
      "type": "sportvision/possession_tracker@v1",
      "name": "possession",
      "detections": "$steps.teams.detections",
      "ball_proximity_threshold": 100.0
    },
    {
      "type": "sportvision/distance_calculator@v1",
      "name": "distance",
      "detections": "$steps.teams.detections",
      "homography_matrix": [[0.01,0,0],[0,0.01,0],[0,0,1]]
    }
  ]
}

Try it on Colab

Open In Colab

Architecture

src/sportvision/
├── detection.py      # SportsDetector — wraps RF-DETR, maps COCO→sports classes
├── tracking.py       # SportsTracker — ByteTrack via supervision
├── teams.py          # TeamClassifier — KMeans on HSV jersey histograms
├── homography.py     # FieldHomography — pixel→field coords
├── analytics/
│   ├── possession.py # PossessionTracker — nearest-player-to-ball per frame
│   ├── speed.py      # SpeedEstimator — displacement/time → km/h
│   ├── distance.py   # DistanceCalculator — cumulative path length
│   └── heatmap.py    # HeatmapGenerator — 2D histogram + gaussian blur
├── annotators.py     # TeamColorAnnotator, StatsOverlayAnnotator, TrailAnnotator
├── pipeline.py       # SportVisionPipeline — orchestrates all modules
└── workflows/            # Roboflow Workflows plugin
    ├── _compat.py        # Inference compatibility shim
    ├── kinds.py          # Custom kind definitions
    ├── team_classifier/  # Team classification block
    ├── possession_tracker/   # Possession tracking block
    ├── distance_calculator/  # Distance calculation block
    └── sports_detection_filter/  # COCO→sports filter block

Sports Class IDs

ID Class
0 Player
1 Ball
2 Referee
3 Goalkeeper

Dependencies

Package Purpose Required
numpy Arrays Yes
opencv-python Image processing, annotation Yes
supervision Detection/tracking data structures Yes
scikit-learn KMeans for team classification Yes
pydantic Workflow block manifests Yes
inference Roboflow Workflows engine Optional ([workflows])
rfdetr Detection model Optional ([inference])

Development

git clone https://github.com/MohibShaikh/sportvision.git
cd sportvision
pip install -e ".[all]"

# Tests
pytest tests/ -v

# Lint
ruff check src/ tests/ && ruff format --check src/ tests/

License

Apache-2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sportvision-0.2.1.tar.gz (601.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sportvision-0.2.1-py3-none-any.whl (25.4 kB view details)

Uploaded Python 3

File details

Details for the file sportvision-0.2.1.tar.gz.

File metadata

  • Download URL: sportvision-0.2.1.tar.gz
  • Upload date:
  • Size: 601.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for sportvision-0.2.1.tar.gz
Algorithm Hash digest
SHA256 b839b381d39bc49aefd8427a309cb38e897bd8518695958c6c5957d821d9c35e
MD5 d975e9a0d3d7007710e2577083d33f53
BLAKE2b-256 b5629eb752fd90771437d60de074a8f31a3b196c1c40fc51f296c288871f61e6

See more details on using hashes here.

File details

Details for the file sportvision-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: sportvision-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 25.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for sportvision-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a09dbb63ed36e9c0b6d0920d7a69f13ad686655e7d23bee7192b4a1d4543f64f
MD5 92c13770a5df42db472b8a76c22889d8
BLAKE2b-256 a97187949e055693eda299e59ecefdf5fc7ee810713567ca18ddaa5bc3639bf6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page