Skip to content

About

It is a repo where with machine learning I will try to analyze the position of the ball, the position of the players and the relative position of all of them in respective the field.

Resources

Stars

1 star

Watchers

2 watching

Forks

Repository files navigation

🤽 Water Polo Analytics

Python 3.12+ YOLOv8 License: GPL v3 Code style: ruff Streamlit OpenCV scikit-learn NumPy Docker

Real-time water polo match analysis using YOLOv8 object detection, ByteTrack multi-object tracking, cap-color team classification, and homography-based field mapping. Extracts player positions, ball trajectories, team possession, and generates tactical heatmaps from broadcast footage.

Architecture

┌──────────────┐    ┌──────────┐    ┌────────────┐    ┌──────────┐    ┌──────────────┐    ┌───────────┐    ┌────────┐
│ Video Input  │───▶│  YOLO    │───▶│  ByteTrack │───▶│  Team    │───▶│  Homography  │───▶│ Analytics │───▶│ Output │
└──────────────┘    │ Detection│    │  Tracking  │    │ Classify │    │  Projection  │    └───────────┘    └────────┘
                    └──────────┘    └────────────┘    └──────────┘    └──────────────┘          │
                                                     Cap Color                            Per-team heatmaps
                                                     K-Means                              Possession stats
                                                                                          Annotated video
                                                                                          CSV export

Features

  • Ball Tracking — Detect and track the water polo ball across frames with carry-forward interpolation
  • Player Detection — Identify all visible players using YOLOv8 with confidence filtering
  • Team Classification — Assign players to teams via K-Means clustering on cap HSV colors
  • Per-Team Heatmaps — Separate positional heatmaps for each team
  • Ball Possession by Team — Proximity-based possession: nearest player within threshold owns the ball
  • Zone Possession — Left/right half ball time distribution
  • Streamlit Web UI — Upload video, configure parameters, view results interactively
  • CSV Export — Frame-by-frame player positions with team labels

Quick Start

CLI

git clone https://github.com/yourusername/waterpolo_analytics.git
cd waterpolo_analytics
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python main.py --input match.mp4 --output results/

Web UI (Streamlit)

streamlit run app.py

Upload a video, adjust detection confidence, team sampling frames, and possession threshold in the sidebar. View heatmaps and possession stats instantly.

Docker

make docker-build
make docker-run INPUT=match.mp4 OUTPUT=results/

Output

File Description
annotated.mp4 Video with team-colored bounding boxes and ball tracking
heatmap.png Combined player position heatmap
heatmap_team_0.png Team 0 position heatmap
heatmap_team_1.png Team 1 position heatmap
stats.csv Per-frame player positions with team IDs

Console output includes zone possession (left/right %) and team possession (proximity-based %).

Configuration

Edit configs/default.yaml:

detection:
  confidence: 0.3
  model: yolov8n.pt

tracking:
  activation_threshold: 0.25
  lost_track_buffer: 30

team_classification:
  sample_frames: 100        # Frames to sample for cap color fitting
  possession_threshold: 3.0 # Meters — max distance for ball possession

field:
  length: 30.0
  width: 20.0
  pixel_corners:            # Calibrate to your camera angle
    - [100, 200]
    - [1800, 200]
    - [1800, 900]
    - [100, 900]

Tech Stack

Component Library
Object Detection Ultralytics YOLOv8
Multi-Object Tracking Supervision (ByteTrack)
Team Classification scikit-learn (KMeans)
Computer Vision OpenCV
Web UI Streamlit
Numerical Computing NumPy
Visualization Matplotlib
Data Export Pandas

Project Structure

waterpolo_analytics/
├── main.py                 # CLI entry point (2-phase pipeline)
├── app.py                  # Streamlit web UI
├── src/
│   ├── detector.py         # YOLOv8 detection wrapper
│   ├── tracker.py          # ByteTrack multi-object tracker
│   ├── team_classifier.py  # K-Means cap color team classification
│   └── analytics.py        # Homography, heatmaps, possession, export
├── configs/
│   └── default.yaml        # Detection/tracking/team parameters
├── Dockerfile
├── Makefile
└── requirements.txt

How Team Classification Works

  1. Phase 1 (Sampling): The first N frames are processed to extract the dominant HSV color from the top 25% of each player bounding box (the cap region).
  2. Fitting: K-Means (k=2) clusters these color samples into two groups.
  3. Phase 2 (Inference): Each player in every subsequent frame is classified into a team by predicting which cluster their cap color belongs to.

This assumes the two teams wear distinguishable cap colors (e.g., white vs. blue), which is standard in competitive water polo.

License

GPL-3.0

About

It is a repo where with machine learning I will try to analyze the position of the ball, the position of the players and the relative position of all of them in respective the field.

Resources

Stars

1 star

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages