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
Possession Tracker sportvision/possession_tracker@v1 Tracks ball possession per team over time
Distance Calculator sportvision/distance_calculator@v1 Cumulative pixel distance per tracked player
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)
result = team_block.run(image=image, detections=detections, n_teams=2)
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

# --- Compute distances ---
distance_block = DistanceCalculatorBlockV1()
result = distance_block.run(detections=detections)
print(result["detections"].data["distance"])  # cumulative px 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
    },
    {
      "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"
    }
  ]
}

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.0.tar.gz (601.6 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.0-py3-none-any.whl (25.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: sportvision-0.2.0.tar.gz
  • Upload date:
  • Size: 601.6 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.0.tar.gz
Algorithm Hash digest
SHA256 79547c79fce883222c568f258d5b005879987fbd676d80f8250348fece7911c7
MD5 80ad4552afe3c49c8101c63ab451e516
BLAKE2b-256 f22dbb6caff1539a212144d088fb2c909ebb5018f7e1323d775adc13d2599b26

See more details on using hashes here.

File details

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

File metadata

  • Download URL: sportvision-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 25.2 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 562c3ce4cfcd642cf300d6a882a94e628f7defd5ee47a624d4b41c46caa9bdca
MD5 01f17f61f910fd688248a7b4318feea5
BLAKE2b-256 eeeac4ce9d525ade642651684fb2a2452b9fdfa6534d4e286c6cadaecd07625a

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