PitchVision AI is a fully automated football match analysis system that uses a custom-trained YOLOv8 model and ByteTrack multi-object tracking to extract rich tactical and physical insights from raw match footage.
It detects and tracks every player, goalkeeper, referee, and the ball across an entire match video β then overlays real-time analytics directly onto the output video, including:
- π― Player tracking with persistent IDs
- π Automatic team identification via jersey color clustering
- β‘ Speed & distance metrics per player
- π Ball possession tracking per team
- π· Camera movement compensation
- πΊοΈ Perspective-transformed real-world coordinates
| Annotation | Description |
|---|---|
| π· Team Convex Hulls | Real-time semi-transparent team formation polygons on camera view & 2D radar |
| π Top HUD Dashboard | Live FRAME counter, team possession split progress bar, and Team Spread metrics |
| πΊοΈ Tactical 2D Pitch Map | 105m x 68m top-down pitch radar displaying 2D player dots, team hulls & ball tracking |
| π Top Distance Leaderboard | Live leaderboards box tracking top player distances covered in real-time |
| π’ Green triangle | Ball position tracking |
| π΄ Red triangle | Player with active ball control |
| π‘ Yellow ellipse | Referee tracking |
| π΅π’ Ellipses | Team identification colors & persistent tracking IDs |
km/h & m |
Real-time speed & cumulative distance covered |
- Trained specifically on football footage to detect 4 classes:
ball,goalkeeper,player,referee - Far superior to generic COCO models β no misclassifying goalkeepers as random objects
- Trained on a curated football dataset with 750+ annotated frames
- Assigns persistent IDs to each player across all frames
- Maintains identity even through occlusions and collisions
- Goalkeepers are merged into the player class for tracking consistency
- Crops each player's bounding box and samples their jersey color from the top half
- Runs K-Means clustering (k=2) to separate the two teams automatically
- No manual labeling β fully unsupervised from jersey colors alone
- Applies
cv2.getPerspectiveTransformto map pixel positions onto real-world pitch dimensions (68m Γ 23.32m) - Allows physically accurate speed and distance measurements
- Calculates distance traveled using transformed real-world positions
- Computes speed in km/h using a 5-frame sliding window
- Overlaid directly on each player in the output video
- Uses Lucas-Kanade Optical Flow to detect and measure camera panning
- Adjusts all player positions to compensate for camera motion
- Ensures speed/distance measurements reflect actual player movement, not camera drift
- Assigns ball possession to the nearest player (within a 70px threshold)
- Tracks cumulative possession percentage per team throughout the match
- Displayed as a real-time overlay in the output video
- Saves YOLO tracking and camera movement results to
.pklstub files - Subsequent runs skip expensive inference and load from cache instantly
- Massive time savings when tweaking downstream analysis
PitchVision-AI/
β
βββ main.py # π Entry point β orchestrates the full pipeline
β
βββ trackers/
β βββ tracker.py # YOLOv8 inference + ByteTrack + annotation drawing
β
βββ team_assigner/
β βββ team_assigner.py # K-Means jersey color clustering for team ID
β
βββ player_ball_assigner/
β βββ player_ball_assigner.py # Nearest-player ball possession assignment
β
βββ camera_movement_estimator/
β βββ camera_movement_estimator.py # Lucas-Kanade optical flow camera compensation
β
βββ view_transformer/
β βββ view_transformer.py # Perspective transform to real-world coordinates
β
βββ speed_and_distance_estimator/
β βββ speed_and_distance_estimator.py # Speed (km/h) & distance (m) per player
β
βββ utils/
β βββ video_utils.py # read_video / save_video helpers
β βββ bbox_utils.py # Bounding box utility functions
β
βββ training/
β βββ train.py # YOLOv8 training script
β βββ yolo_inference.py # Quick inference test
β βββ runs/detect/train-3/
β βββ weights/
β βββ best.pt # β Best custom-trained model weights
β βββ last.pt # Last epoch model weights
β
βββ stubs/ # Cached inference results (.pkl)
βββ input/ # Input match video
βββ output_videos/ # Generated annotated output video
βββ yolov8x.pt # Base YOLOv8x pretrained weights
graph TD
A[πΉ Input Video] --> B[YOLOv8 Detection\ncustom trained]
B --> C[ByteTrack\nMulti-Object Tracking]
C --> D[Camera Movement\nCompensation]
D --> E[Perspective\nTransform]
E --> F[Speed & Distance\nEstimation]
C --> G[Team Assignment\nK-Means Clustering]
G --> H[Ball Possession\nTracking]
F --> I[Draw Annotations]
H --> I
I --> J[π¬ Output Video]
- Python 3.8+
- pip
- Git LFS (for cloning large model files)
# Install Git LFS first (required for model weights & videos)
git lfs install
# Clone the repo
git clone https://github.com/NAMEER97/PitchVision-AI.git
cd PitchVision-AIpip install ultralytics supervision scikit-learn pandas numpy opencv-pythonMake sure the custom trained weights are present:
training/runs/detect/train-3/weights/best.pt
python main.pyThis will:
- Read the input video from
input/08fd33_4.mp4 - Run YOLOv8 detection on all frames (or load from stub cache)
- Track all players, referees, and ball using ByteTrack
- Compensate for camera movement
- Transform positions to real-world coordinates
- Calculate speed and distance for each player
- Assign team colors and ball possession
- Render and save the annotated video to
output_videos/output_video.mp4
python yolo_inference.pyThe core detection and tracking engine.
| Method | Description |
|---|---|
detect_frames() |
Batched YOLOv8 inference (batch size 20) |
get_object_tracks() |
Full tracking pipeline with stub caching |
add_position_to_tracks() |
Appends foot/center positions to track data |
interpolate_ball_positions() |
Fills missing ball positions via interpolation |
draw_annotations() |
Renders ellipses, triangles, IDs, and stats |
Unsupervised team color detection.
| Method | Description |
|---|---|
get_player_color() |
Crops player bbox, runs K-Means on top half |
assign_team_color() |
Fits global K-Means (k=2) across all players |
get_player_team() |
Predicts team for a given player, with caching |
Optical flow-based camera stabilization.
| Method | Description |
|---|---|
get_camera_movement() |
Lucas-Kanade optical flow per frame |
add_adjust_positions_to_tracks() |
Subtracts camera delta from all positions |
draw_camera_movement() |
Overlays camera X/Y movement on frames |
Converts pixel coordinates to real-world meters.
| Method | Description |
|---|---|
transform_point() |
Applies perspective warp to a single point |
add_transformed_position_to_tracks() |
Bulk-transforms all track positions |
Physical metrics computation.
| Method | Description |
|---|---|
add_speed_and_distance_to_tracks() |
5-frame window speed/distance calculation |
draw_speed_and_distance() |
Renders km/h & meters under each player |
Ball possession logic.
| Method | Description |
|---|---|
assign_ball_to_player() |
Finds nearest player to ball (max 70px) |
The custom YOLOv8 model was trained on a football-specific dataset:
cd training
python train.pyTraining config:
- Base model:
yolov8m.pt - Dataset:
football-players-detection-1(custom annotated) - Classes:
ball,goalkeeper,player,referee - Epochs: ~100+
- Results: See
training/runs/detect/train-3/
Training results and performance curves are available in:
training/runs/detect/train-3/
βββ results.png # Loss & mAP curves
βββ confusion_matrix.png # Class confusion matrix
βββ BoxPR_curve.png # Precision-Recall curve
βββ val_batch*.jpg # Validation predictions
ultralytics
supervision
scikit-learn
pandas
numpy
opencv-python
Nameer
GitHub: @NAMEER97
Creating a comprehensive, beautifully formatted README.md for the PitchVision-AI project.
