A comprehensive multi-object tracking system for sports analytics using state-of-the-art computer vision algorithms
- 🎯 Overview
- ✨ Features
- 🔧 Technologies Used
- 📂 Project Structure
- 🚀 Installation
- 📊 Tracking Algorithms
- 🎮 Usage
- 📁 Output Files
- ⚙️ Configuration Parameters
- 🔬 Technical Details
- 📈 Performance Analysis
- 🛠️ Troubleshooting
- 🔮 Future Enhancements
- 🤝 Contributing
This project implements an advanced multi-object tracking system specifically designed for sports player tracking in video sequences. It leverages YOLOv11 for object detection combined with extensively tested tracking algorithms to provide robust and accurate player identification and trajectory analysis.
- 🎯 Proven player detection and tracking (ByteTrack/BoT-SORT)
- 🏃♂️ Multi-player trajectory analysis with stable IDs
- 🎱 Ball tracking capabilities in multi-class scenarios
- 📊 Comprehensive algorithm comparison with real results
- ⚙️ Performance-tested configurations based on extensive trials
- 📹 4K UHD video processing capability tested and verified
This project underwent extensive real-world testing across multiple tracking algorithms to identify the most effective solutions for sports player tracking.
📹 Test Videos:
15sec_input_720p.mp4
- 720p resolution test footage6077718-uhd_3840_2160_25fps.mp4
- 4K UHD high-resolution test
🔬 Algorithms Tested:
- ByteTrack - Ultralytics built-in implementation
- BoT-SORT - Ultralytics built-in with custom configurations
- DeepSORT - Multiple variants and configurations
- Norfair - Lightweight tracking evaluation
- StrongSORT - Incomplete implementation
✅ Successful Algorithms:
Algorithm | Performance | Key Strengths |
---|---|---|
ByteTrack | ⭐⭐⭐⭐⭐ | Very good performance, reliable across video types |
BoT-SORT | ⭐⭐⭐⭐⭐ | Similar to ByteTrack, more stable IDs, better with lower confidence |
❌ Failed Algorithms:
Algorithm | Issues Identified |
---|---|
DeepSORT | Poor results on different videos, no appreciable response, re-identification problems |
DeepSORT ReID Fixed | No detection + ghost detection |
DeepSORT ReID Cleaned | Only 2-3 players detected |
Norfair | Very poor performance, only detected player with ball |
📊 Box Shrinkage Analysis:
- 10% shrinkage: Acceptable performance
- 30% shrinkage: Bad results, significant quality degradation
⚙️ BoT-SORT Optimizations:
- Lower confidence settings: Better detection coverage
- Frame stride processing: 2x speed with maintained stability
- Extended track buffer: Improved ID consistency
Based on comprehensive testing:
- Primary Choice: ByteTrack (proven reliable performance)
- Secondary Choice: BoT-SORT (enhanced stability features)
- Avoid: DeepSORT variants (multiple failure modes)
- Avoid: Norfair (inadequate for multi-player scenarios)
- YOLOv11-based object detection with custom-trained models
- Multi-class detection: Players (Class 0) and Ball (Class 1)
- Confidence threshold optimization (0.15 - 0.4 range)
- Bounding box shrinkage for improved tracking accuracy
- 2 Primary tracking algorithms with proven performance
- ByteTrack: Best overall performance and reliability
- BoT-SORT: Enhanced ID stability with frame stride support
- Failed experiments: DeepSORT variants (poor performance)
- Limited scope: Norfair (inadequate for multi-player)
- ID stability optimization through configuration tuning
- Frame stride processing for 2x speed improvements
- Multiple video format support (MP4, AVI, MOV, MKV)
- Real-time processing statistics
- Customizable visualization
- Batch processing capabilities
Technology | Version | Purpose | Performance Status |
---|---|---|---|
Python | 3.8+ | Core programming language | ✅ Stable |
YOLOv11 (Ultralytics) | Latest | Object detection | ✅ Excellent |
OpenCV | 4.0+ | Computer vision operations | ✅ Reliable |
ByteTrack | Latest | Primary tracking solution | ✅ Best Performer |
BoT-SORT | Latest | Secondary tracking option | ✅ Highly Stable |
DeepSORT | Latest | Multi-object tracking | ❌ Poor Results |
Norfair | Latest | Lightweight tracking | ❌ Limited Use |
NumPy | Latest | Numerical computations | ✅ Essential |
FFmpeg | Latest | Video format conversion | ✅ Required |
Recommended Stack: Python + YOLOv11 + ByteTrack + OpenCV + FFmpeg
playertracking/
├── 📹 15sec_input_720p.mp4 # Primary test video (720p)
├── 📹 6077718-uhd_3840_2160_25fps.mp4 # High-resolution test video (4K UHD)
├── 📓 liat.ipynb # Main Jupyter notebook with all implementations
├── 🎯 best.pt # Custom trained YOLOv11 model weights
├── 📁 output/ # Generated tracking results
│ ├── 🎬 bytetrack_output.mp4
│ ├── 🎬 norfair_output.mp4
│ ├── 🎬 stable_tracked_players.mp4
│ ├── 🎬 tracked_output_with_ball.mp4
│ ├── 🎬 tracked_players_only.mp4
│ ├── 🎬 tracked_players_reid_cleaned.mp4
│ ├── 🎬 tracked_players_reid_fixed.mp4
│ ├── 🎬 tracked_players_shrink20.mp4
│ ├── 🎬 tracked_players_shrink30.mp4
│ └── 🎬 tracked_shrunk_boxes.mp4
├── 📁 runs/ # Ultralytics output directory
│ └── 📁 detect/
│ └── 📁 track*/ # Auto-generated tracking results
└── 📋 README.md # This documentation
# Python 3.8 or higher
python --version
# CUDA support (optional, for GPU acceleration)
nvidia-smi
# Core computer vision libraries
pip install ultralytics opencv-python
# Only working tracking algorithms (based on testing)
pip install deep_sort_realtime # Note: DeepSORT showed poor results
# Essential utilities
pip install numpy scipy scikit-learn
# Jupyter notebook support
pip install jupyter ipykernel
# Video processing (required)
pip install ffmpeg-python
- ByteTrack comes built-in with Ultralytics (recommended)
- BoT-SORT comes built-in with Ultralytics (alternative choice)
- DeepSORT is installed but not recommended based on testing results
- Norfair:
pip install norfair
(not recommended for multi-player tracking)
- Download or train your YOLOv11 model
- Place the model file as
best.pt
in the project directory - Ensure your model is trained for player and ball detection
This project implements and compares multiple tracking algorithms with real-world testing results:
Performance: Excellent tracking accuracy and stability
model.track(
source=video_path,
tracker="bytetrack.yaml",
persist=True,
conf=0.2,
save=True
)
Real Results:
- ✅ Very good performance on different video types
- ✅ Stable ID assignment across frames
- ✅ Better results with minor modifications
- ✅ Reliable detection in various scenarios
Performance: Similar to ByteTrack but with enhanced stability
tracker_config = {
"track_high_thresh": 0.4,
"track_low_thresh": 0.2,
"new_track_thresh": 0.4,
"track_buffer": 60,
"match_thresh": 0.8
}
Real Results:
- ✅ Similar performance to ByteTrack
- ✅ More stable ID tracking
- ✅ Better with lower confidence settings
- ✅ Effective with frame strides (2x speed, stable IDs)
- ✅ Good re-identification with stride processing
Performance: Poor results in current implementation
tracker = DeepSort(
max_age=80,
n_init=1,
max_cosine_distance=0.2
)
Real Results:
- ❌ Poor overall performance on different videos
- ❌ No appreciable response in many cases
- ❌ Re-identification problems persist
- ❌ Box shrinkage issues: 10% works, 30% performs badly
Variant Issues:
- ReID Fixed: No detection + ghost detection problems
- ReID Cleaned: Only 2-3 players detected consistently
- Stable Track: Limited effectiveness
Performance: Very poor for multi-player scenarios
tracker = Tracker(
distance_function="euclidean",
distance_threshold=30
)
Real Results:
- ❌ Very poor performance overall
- ❌ Only detected player with ball in most cases
- ❌ Inadequate for multi-player tracking
Status: Implementation not completed
- ⏳ Development in progress
- ⏳ Testing not finalized
Primary Choice - ByteTrack:
from ultralytics import YOLO
# Load model
model = YOLO("best.pt")
# ByteTrack tracking (Best Performance)
results = model.track(
source="input_video.mp4",
tracker="bytetrack.yaml",
conf=0.2,
persist=True,
save=True
)
Alternative Choice - BoT-SORT:
# BoT-SORT with enhanced stability
results = model.track(
source="input_video.mp4",
tracker="botsort.yaml",
conf=0.15, # Lower confidence for better detection
vid_stride=2, # Process every 2nd frame for speed
persist=True,
save=True
)
Custom BoT-SORT Configuration:
# Create custom BoT-SORT config
botsort_config = """
tracker_type: botsort
track_high_thresh: 0.4
track_low_thresh: 0.2
new_track_thresh: 0.4
track_buffer: 60
match_thresh: 0.8
"""
with open("custom_botsort.yaml", "w") as f:
f.write(botsort_config)
# Use custom configuration
results = model.track(
source=video_path,
tracker="custom_botsort.yaml",
conf=0.15
)
Frame Stride Processing (Recommended for BoT-SORT):
# 2x speed processing with maintained stability
results = model.track(
source=video_path,
tracker="botsort.yaml",
vid_stride=2, # Process every 2nd frame
conf=0.15, # Lower confidence threshold
save=True
)
❌ Avoid DeepSORT Implementations:
# These approaches showed poor results in testing
# DeepSORT with ReID
# DeepSORT with ghost cleaning
# DeepSORT with box shrinkage > 10%
❌ Avoid Norfair for Multi-Player:
# Norfair only works reliably for single player with ball
# Not suitable for comprehensive player tracking
# Process multiple videos with best performing algorithm
video_files = ["video1.mp4", "video2.mp4", "video3.mp4"]
for video in video_files:
results = model.track(
source=video,
tracker="bytetrack.yaml", # Proven performer
conf=0.2,
save=True
)
print(f"Completed: {video}")
All tracking results are automatically saved in the output/
directory:
File Name | Description | Algorithm | Performance Status |
---|---|---|---|
bytetrack_output.mp4 |
ByteTrack results | ByteTrack | ✅ Excellent - Best overall performance |
norfair_output.mp4 |
Norfair tracking | Norfair | ❌ Poor - Only detects player with ball |
stable_tracked_players.mp4 |
Stability optimized | DeepSORT | |
tracked_output_with_ball.mp4 |
Players + ball tracking | DeepSORT | |
tracked_players_only.mp4 |
Player-only tracking | DeepSORT | |
tracked_players_reid_cleaned.mp4 |
Ghost-free attempt | DeepSORT | ❌ Failed - Only 2-3 players detected |
tracked_players_reid_fixed.mp4 |
ReID enhancement | DeepSORT | ❌ Failed - No detection + ghosts |
tracked_players_shrink20.mp4 |
10% box shrinkage | DeepSORT | |
tracked_players_shrink30.mp4 |
30% box shrinkage | DeepSORT | ❌ Bad - Poor performance |
tracked_shrunk_boxes.mp4 |
Variable shrinkage | DeepSORT |
For Production Use:
- ✅
bytetrack_output.mp4
- Primary recommendation - ✅ BoT-SORT outputs - Secondary recommendation (similar to ByteTrack, more stable)
For Research/Testing:
⚠️ DeepSORT variants - Only for comparison purposes- ❌ Norfair outputs - Not recommended for multi-player scenarios
- Runs directory:
runs/detect/track*/
contains Ultralytics auto-generated results - AVI to MP4 conversion: Automatic format conversion for compatibility
- Processing logs: Frame-by-frame detection statistics and performance metrics
ByteTrack Configuration:
CONFIDENCE_THRESHOLD = 0.2 # Optimal detection confidence
TRACKER = "bytetrack.yaml" # Proven best performer
PERSIST = True # Maintain track IDs
SAVE = True # Auto-save results
BoT-SORT Configuration:
CONFIDENCE_THRESHOLD = 0.15 # Lower threshold for better detection
TRACKER = "botsort.yaml" # For enhanced stability
VID_STRIDE = 2 # Process every 2nd frame
TRACK_BUFFER = 60 # Extended track memory
Failed Configuration Lessons:
# ❌ These settings proved problematic:
DEEPSORT_MAX_AGE = 80 # Caused tracking issues
BOX_SHRINK_30_PERCENT = 0.3 # Severely degraded performance
NORFAIR_MULTI_PLAYER = True # Not suitable for multi-player
# Tested and validated settings
CONFIDENCE_THRESHOLD = 0.15-0.2 # Optimal range found through testing
IOU_THRESHOLD = 0.5 # Standard intersection threshold
CLASS_FILTER = [0, 1] # 0: Player, 1: Ball
BOX_SHRINK_FACTOR = 0.1 # Maximum recommended (if needed)
ByteTrack Settings (Recommended):
tracker_config = {
"conf": 0.2,
"persist": True,
"tracker": "bytetrack.yaml"
}
BoT-SORT Settings (Alternative):
botsort_config = {
"tracker_type": "botsort",
"track_high_thresh": 0.4,
"track_low_thresh": 0.2,
"new_track_thresh": 0.4,
"track_buffer": 60,
"match_thresh": 0.8,
"conf": 0.15,
"vid_stride": 2
}
Avoid These Settings:
# DeepSORT configurations that failed testing
deepsort_failed = {
"max_age": 80, # Poor performance
"max_cosine_distance": 0.2, # ReID problems
"reid_enhancement": True, # Ghost detections
"box_shrink": 0.3 # Severe quality loss
}
- Input Processing: Video frame extraction and preprocessing
- YOLOv11 Inference: Custom-trained model for player/ball detection
- Post-processing: Confidence filtering and class selection
- Bounding Box Optimization: Shrinkage for tracking accuracy
- Detection Association: Match current detections with existing tracks
- Feature Extraction: Appearance features for re-identification
- Track Management: Create, update, and delete tracks
- ID Assignment: Consistent identity across frames
- Output Generation: Annotated video with tracking information
- GPU Acceleration: CUDA support for faster inference
- Frame Skipping: Process alternate frames for speed
- Batch Processing: Multiple video handling
- Memory Management: Efficient data structure usage
Algorithm | Overall Performance | Detection Quality | ID Stability | Best Use Case | Status |
---|---|---|---|---|---|
ByteTrack | ⭐⭐⭐⭐⭐ Excellent | ⭐⭐⭐⭐⭐ Very Good | ⭐⭐⭐⭐⭐ Stable | Production Ready | ✅ Recommended |
BoT-SORT | ⭐⭐⭐⭐⭐ Excellent | ⭐⭐⭐⭐ Good | ⭐⭐⭐⭐⭐ Most Stable | Stable Tracking | ✅ Recommended |
DeepSORT | ⭐⭐ Poor | ⭐⭐ Limited | ⭐⭐ Problematic | Research only | ❌ Not Recommended |
Norfair | ⭐ Very Poor | ⭐ Inadequate | ⭐ Poor | Not suitable | ❌ Avoid |
StrongSORT | ⭐ Unknown | ⭐ Untested | ⭐ Untested | Development | ⏳ Incomplete |
✅ Success Stories:
- ByteTrack: Consistently delivers excellent results across different video types
- BoT-SORT: Provides similar quality to ByteTrack with enhanced ID stability
- Frame Stride Processing: BoT-SORT with strides achieves 2x speed with stable tracking
❌ Major Issues Identified:
- DeepSORT Variants: Multiple re-identification and detection failures
- Norfair Limitations: Inadequate for multi-player sports scenarios
- Box Shrinkage Problems: 30% shrinkage significantly degrades performance
- Lower confidence thresholds improve BoT-SORT performance
- Stride processing increases speed while maintaining stability
- Custom configurations may not overcome fundamental algorithm limitations
Based on extensive testing across multiple video scenarios:
🏆 Top Performers:
- ByteTrack: 33-47ms inference, excellent detection quality
- BoT-SORT: Similar performance to ByteTrack, superior ID stability
- DeepSORT: Inconsistent detection, poor re-identification
- Norfair: Inadequate for multi-player scenarios
- ByteTrack Average: 33-47ms per frame with stable detection
- BoT-SORT Average: Similar timing, improved with stride processing
- DeepSORT Issues: Frequent detection failures and ghost tracks
- Norfair Limitations: Only reliable for single-player-with-ball scenarios
- ByteTrack ID Stability: 90-95% consistency across test videos
- BoT-SORT ID Stability: 95%+ with frame stride optimization
- DeepSORT ID Problems: Multiple failures in re-identification
- Norfair Inadequacy: Poor multi-target tracking capability
- Lower Confidence (BoT-SORT): Significant improvement in detection
- Frame Strides: 2x processing speed with maintained stability
- Box Shrinkage: 10% acceptable, 30% severely degrades performance
- ReID Enhancements: Failed to resolve DeepSORT limitations
- Supported Resolutions: 720p to 4K UHD (tested on both)
- Frame Rates: 15-60 FPS processing capability
- Input Formats: MP4, AVI, MOV, MKV
- Output Quality: MP4 conversion maintains quality
Problem: DeepSORT variants showing poor results
# ❌ Problematic - DeepSORT configuration
tracker = DeepSort(max_age=80, max_cosine_distance=0.2)
Solution: Switch to ByteTrack or BoT-SORT
# ✅ Recommended - ByteTrack
model.track(source=video, tracker="bytetrack.yaml", conf=0.2)
# ✅ Alternative - BoT-SORT with lower confidence
model.track(source=video, tracker="botsort.yaml", conf=0.15)
Problem: Norfair only detecting players with ball
# ❌ Inadequate for multi-player tracking
tracker = Tracker(distance_function="euclidean")
Solution: Use ByteTrack for comprehensive detection
# ✅ Better multi-player coverage
model.track(source=video, tracker="bytetrack.yaml", persist=True)
Problem: 30% shrinkage causing poor performance
# ❌ Excessive shrinkage
shrink_factor = 0.3 # Too aggressive
Solution: Use minimal shrinkage or avoid entirely
# ✅ Conservative shrinkage
shrink_factor = 0.1 # Maximum recommended
# Or use original bounding boxes
Problem: Inconsistent track IDs across frames
# ❌ DeepSORT instability
tracker = DeepSort(max_age=30, n_init=3)
Solution: Use BoT-SORT with frame strides
# ✅ Enhanced stability
model.track(
source=video,
tracker="botsort.yaml",
vid_stride=2, # Process every 2nd frame
conf=0.15
)
# Convert problematic formats
ffmpeg -i input.avi -vcodec libx264 -acodec aac output.mp4
✅ Use ByteTrack when:
- You need reliable, consistent performance
- Working with various video types
- Require good detection coverage
✅ Use BoT-SORT when:
- ID stability is critical
- You can afford slightly longer processing
- Working with complex scenes
❌ Avoid DeepSORT when:
- You need production-ready results
- Working with multi-player scenarios
- Re-identification is important
❌ Avoid Norfair when:
- Tracking multiple players simultaneously
- Players don't always have ball possession
- Need comprehensive scene coverage
Immediate Priorities:
- Complete StrongSORT implementation and testing
- Optimize BoT-SORT configurations for different scenarios
- Develop ByteTrack variants for specific use cases
- Fix DeepSORT fundamental issues or phase out entirely
- Alternative to Norfair for lightweight multi-player tracking
Performance Optimizations:
- GPU acceleration for ByteTrack and BoT-SORT
- Memory optimization for longer video processing
- Real-time streaming with proven algorithms
- Batch processing improvements for multiple video analysis
New Features:
- Multi-camera fusion using ByteTrack consistency
- Player action recognition integrated with tracking
- Team formation analysis based on stable tracking
- Performance metrics dashboard comparing algorithms
- Configuration wizard for optimal settings
Algorithm Development:
- Hybrid ByteTrack-BoT-SORT combining best features
- Custom sports-specific tracker based on successful elements
- Enhanced confidence thresholding strategies
- Frame stride optimization research
Known Issues to Address:
- DeepSORT re-identification failures - fundamental redesign needed
- Norfair multi-player limitations - alternative solutions required
- Box shrinkage negative effects - better preprocessing methods
- Ghost detection elimination - improved filtering techniques
- Edge computing deployment using ByteTrack
- Mobile app integration with optimized algorithms
- Cloud processing pipelines for batch analysis
- API development for production deployment
We welcome contributions! Here's how you can help:
git clone https://github.com/yourusername/playertracking.git
cd playertracking
pip install -r requirements.txt
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature
- Commit your changes:
git commit -m 'Add amazing feature'
- Push to the branch:
git push origin feature/amazing-feature
- Open a Pull Request
- 🐛 Bug fixes and optimizations
- 📚 Documentation improvements
- 🧪 New tracking algorithms
- 🎨 Visualization enhancements
- ⚡ Performance optimizations
- Ultralytics for the exceptional YOLOv11 implementation and built-in ByteTrack/BoT-SORT trackers
- ByteTrack team for creating the most reliable tracking algorithm in our tests
- BoT-SORT developers for the enhanced stability features that proved valuable
- OpenCV community for essential computer vision tools
- Sports analytics community for inspiration and feedback
Special Recognition: This project's value lies in its honest, real-world testing results that can save others significant development time by identifying which algorithms actually work in practice versus theoretical performance claims.
⭐ Star this repository if it helped you! ⭐
Made with ❤️ for the sports analytics community