Skip to content

Repository files navigation

⚽ Football Match Analytics Computer Vision Pipeline

End-to-end football video analysis using deep learning, multi-object tracking, and perspective geometry.

Python YOLOv8 OpenCV License: MIT

Project Output Preview

🧠 What This Project Does

Most football analytics tools are locked behind expensive broadcast infrastructure. This project brings professional-grade match analysis to any game footage detecting players, tracking their movement, measuring speed, and estimating ball possession automatically.

Given a raw match video, the pipeline outputs:

  • 🟢 Player & ball detection with YOLOv8 (custom-trained weights)
  • 🔁 Multi-object tracking with ByteTrack IDs persist across frames even through occlusion
  • 👕 Automatic team assignment via jersey color clustering (KMeans)
  • 📐 Perspective-corrected positioning pixel coordinates → real-world field meters
  • 📷 Camera motion compensation using Lucas-Kanade optical flow
  • 🏃 Per-player speed (km/h) and distance covered (m)
  • ⚽ Frame-by-frame ball possession with team-level aggregation
  • 🎬 Annotated video output with overlays for all the above

🏗️ Architecture Overview

Video Input
    │
    ▼
┌──────────────────────────────────────────┐
│  YOLO Detection  →  ByteTrack Tracking   │  trackers/
└──────────────────────────────────────────┘
    │
    ▼
┌──────────────────────────────────────────┐
│  Camera Motion Estimation (Lucas-Kanade) │  camera_movement_estimator/
│  → Position Compensation per Frame       │
└──────────────────────────────────────────┘
    │
    ▼
┌──────────────────────────────────────────┐
│  Perspective Transform (Homography)      │  view_transformer/
│  Pixel Space → Real-World Field Coords   │
└──────────────────────────────────────────┘
    │
    ▼
┌──────────────────────────────────────────┐
│  Ball Interpolation (Pandas)             │
│  Speed & Distance Estimation             │  speed_and_distance_estimator/
└──────────────────────────────────────────┘
    │
    ▼
┌──────────────────────────────────────────┐
│  Team Color Clustering (KMeans)          │  team_assigner/
│  Ball Possession Assignment              │  player_ball_assigner/
└──────────────────────────────────────────┘
    │
    ▼
Annotated Video Output

🔍 Technical Highlights

Tracking Robustness Ball detections are often noisy or missing across frames. Rather than propagating gaps, I use Pandas interpolation with directional fill to reconstruct a smooth, continuous ball trajectory.

Camera Motion Problem In broadcast football, the camera pans constantly which makes player motion estimates meaningless in pixel space. I extract stable background features using goodFeaturesToTrack, track them across frames with Lucas-Kanade optical flow, and subtract the dominant camera shift from all object positions before any analytics runs.

Real-World Coordinates Speed and distance can't be computed in pixels. I define four known pitch points (in pixels and real-world meters), compute a homography matrix via getPerspectiveTransform, and project all compensated positions into field coordinates before doing any motion math.

Team Assignment No labeling required. For each player bounding box, I take the top half (avoiding pitch bleed), run a 2-cluster KMeans on pixel colors, filter out the background cluster by checking image corners, and use the remaining cluster center as the jersey color. A second KMeans across all players separates Team 1 from Team 2.

Possession Heuristic Ball possession is assigned per frame using minimum-distance to player foot positions, with a configurable threshold. Cumulative team possession percentages are overlaid in real-time on the output video.


🛠️ Tech Stack

Library Role
Ultralytics YOLOv8, YOLO26 Object detection
Supervision + ByteTrack Multi-object tracking
OpenCV Frame processing, optical flow, perspective transform
scikit-learn KMeans jersey color clustering
Pandas Ball position interpolation
NumPy Numerical operations
FilterPy Kalman filter support

📁 Project Structure

Football_Analysis/
├── main.py                          # Entry point runs full pipeline
├── requirements.txt
│
├── trackers/
│   └── tracker.py                   # YOLO detection + ByteTrack + annotation drawing
│
├── team_assigner/
│   └── team_assigner.py             # KMeans jersey color → team ID assignment
│
├── player_ball_assigner/
│   └── player_ball_assigner.py      # Nearest-player ball possession logic
│
├── camera_movement_estimator/
│   └── camera_movement_estimator.py # Lucas-Kanade optical flow compensation
│
├── view_transformer/
│   └── view_transformer.py          # Homography: pixels → real-world meters
│
├── speed_and_distance_estimator/
│   └── speed_and_distnace_estimator.py  # Speed (km/h) + cumulative distance
│
├── utils/
│   ├── video_utils.py               # read_video / save_video helpers
│   └── bobx_utils.py                # BBox geometry utilities
│
├── stubs/                           # Cached detections & camera movement (for fast re-runs)
├── development_and_analysis/        # Notebooks for color clustering exploration
└── output_videos/                   # Annotated output

🚀 Getting Started

1. Clone and install

git clone https://github.com/Rudraksh225/Football_Analysis.git
cd Football_Analysis
pip install -r requirements.txt

2. Add model weights and input video

By default, main.py expects:

  • Model weights → models/best.pt
  • Input video → test/test (19).mp4

Download them here:

Asset Link
YOLO weights (yolov8) (best.pt) Google Drive
YOLO weights (yolo26) (best_2.pt) Google Drive
Sample match video Google Drive

3. Run

python main.py

Output saved to: output_videos/output_video.avi


⚡ Fast Re-runs with Stubs

Detection and camera motion estimation are the most expensive steps. Pre-computed results are cached as stubs:

stubs/track_stubs.pkl
stubs/camera_movement_stub.pkl

These are enabled by default in main.py. To run everything fresh end-to-end:

# In main.py, change these two calls:
tracker.get_object_tracks(..., read_from_stub=False)
camera_movement_estimator.get_camera_movement(..., read_from_stub=False)

📊 Output Overlays

Each output frame contains:

  • Colored ellipses under players (team color-coded)
  • Player IDs in small rectangles
  • Green triangle above the ball
  • Red triangle on the player currently in possession
  • Team ball control % cumulative, shown in bottom-right panel
  • Camera shift (X/Y) shown in top-left panel
  • Speed (km/h) and distance (m) overlaid near each player's feet

⚠️ Current Limitations

  • Input/output paths are hardcoded in main.py config file or CLI args would be a clean improvement
  • Perspective transform vertices are manually defined for a single camera view not generalizable out of the box
  • Team color clustering initializes from the first frame only might fail on extreme lighting changes mid-match
  • Possession uses a simple nearest-distance heuristic no physics or velocity context
  • Frame rate is hardcoded at 24 FPS for speed calculations should be auto-detected from video metadata

📄 License

MIT free to use, modify, and build on. Attribution appreciated.


Built with curiosity and way too many hours of football footage.

About

An end-to-end computer vision pipeline for football analytics. Uses YOLO, ByteTrack, and OpenCV to automatically detect players, track ball possession, compensate for camera motion, and calculate real-world speed and distance from raw match footage.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages