Downloads · 30 days
117
13% of all-time downloads
julianzu9612/RFDETR-Soccernet
RFDETR-Soccernet is a object detection model from julianzu9612. Use it when you need objects located in an image. The card lists the license as apache-2.0.
A state-of-the-art RF-DETR-Large model fine-tuned on the SoccerNet-Tracking dataset for detecting objects in soccer videos. This model achieves 85.7% mAP@50 and provides professional-grade analysis capabilities for so…
Downloads · 30 days
117
13% of all-time downloads
All-time downloads
883
Public
Repo size
1.6 GB
Likes
19
Public
Click a slice to open those files.
.pth1.6 GB · 100%
From the Hugging Face model README
A state-of-the-art RF-DETR-Large model fine-tuned on the SoccerNet-Tracking dataset for detecting objects in soccer videos. This model achieves 85.7% mAP@50 and provides professional-grade analysis capabilities for soccer broadcasts.
| Metric | Value | Target |
|---|---|---|
| mAP@50 | 85.7% | 84.95% ✅ |
| mAP | 49.8% | - |
| mAP@75 | 52.0% | - |
| Training Time | ~14 hours | NVIDIA A100 40GB |
| Parameters | 128M | RF-DETR-Large |
The model can detect 4 essential classes in soccer videos:
pip install rfdetr pandas opencv-python pillow tqdm numpy torch torchvision
from inference import RFDETRSoccerNet
# Initialize model (auto-detects CUDA/CPU)
model = RFDETRSoccerNet()
# Process video and get DataFrame
df = model.process_video('soccer_match.mp4', confidence_threshold=0.5)
# Display first 5 detections
print(df.head())
# Save results
model.save_results(df, 'match_analysis.csv')
The model returns a pandas DataFrame with comprehensive detection data:
| Column | Description | Type |
|---|---|---|
frame | Frame number in video | int |
timestamp | Time in seconds | float |
class_name | Detected class | str |
class_id | Class ID (0-3) | int |
x1, y1 | Top-left corner coordinates | float |
x2, y2 | Bottom-right corner coordinates | float |
width, height | Bounding box dimensions | float |
confidence | Detection confidence (0-1) | float |
center_x, center_y | Object center coordinates | float |
area | Bounding box area | float |
# Process entire match
df = model.process_video(
'full_match.mp4',
confidence_threshold=0.5,
save_results=True
)
print(f"Processed {len(df):,} detections")
print(df['class_name'].value_counts())
# Process every 5th frame for speed
df = model.process_video(
'match.mp4',
frame_skip=5, # 5x faster processing
confidence_threshold=0.6
)
# Process first 10 minutes only
df = model.process_video(
'match.mp4',
max_frames=18000, # ~10 minutes at 30fps
confidence_threshold=0.5
)
# Process single image
df = model.process_image('soccer_frame.jpg', confidence_threshold=0.5)
# Display results
for _, detection in df.iterrows():
print(f"{detection['class_name']}: {detection['confidence']:.2f}")
# Analyze which players are near the ball
possession_df = model.analyze_ball_possession(
df,
distance_threshold=100 # pixels
)
print(f"Found {len(possession_df)} possession events")
# Get high-confidence ball detections
ball_df = df[(df['class_name'] == 'ball') & (df['confidence'] > 0.8)]
# Calculate average players per frame
avg_players = df[df['class_name'] == 'player'].groupby('frame').size().mean()
# Find frames with goalkeepers
goalkeeper_frames = df[df['class_name'] == 'goalkeeper']['frame'].unique()
# Analyze referee positioning
referee_df = df[df['class_name'] == 'referee']
referee_activity = referee_df.groupby('frame').size()
# Save as CSV (recommended for analysis)
model.save_results(df, 'detections.csv', format='csv')
# Save as JSON (with metadata)
model.save_results(df, 'detections.json', format='json')
# Save as Parquet (for big data)
model.save_results(df, 'detections.parquet', format='parquet')
| Class | Precision | Recall | F1-Score |
|---|---|---|---|
| Ball | 78.5% | 71.2% | 74.7% |
| Player | 91.3% | 89.7% | 90.5% |
| Referee | 85.2% | 82.1% | 83.6% |
| Goalkeeper | 88.9% | 85.4% | 87.1% |
# Class-specific confidence tuning
df = model.process_video('match.mp4')
# Filter by class-specific confidence
high_conf_players = df[(df['class_name'] == 'player') & (df['confidence'] > 0.7)]
high_conf_ball = df[(df['class_name'] == 'ball') & (df['confidence'] > 0.5)]
import os
# Process multiple videos
video_files = ['match1.mp4', 'match2.mp4', 'match3.mp4']
for video in video_files:
print(f"Processing {video}...")
df = model.process_video(video, save_results=True)
print(f"Completed: {len(df)} detections")
import pandas as pd
import matplotlib.pyplot as plt
# Process video
df = model.process_video('match.mp4')
# Create timeline analysis
timeline = df.groupby('timestamp')['class_name'].value_counts().unstack(fill_value=0)
timeline.plot(kind='line', figsize=(15, 8))
plt.title('Object Detection Timeline')
plt.show()
import cv2
# Load video and predictions
cap = cv2.VideoCapture('match.mp4')
df = model.process_video('match.mp4')
# Draw detections on video frames
for frame_num in range(100): # First 100 frames
ret, frame = cap.read()
if not ret:
break
# Get detections for this frame
frame_detections = df[df['frame'] == frame_num]
# Draw bounding boxes
for _, det in frame_detections.iterrows():
x1, y1, x2, y2 = int(det['x1']), int(det['y1']), int(det['x2']), int(det['y2'])
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(frame, f"{det['class_name']}: {det['confidence']:.2f}",
(x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
cv2.imshow('Detections', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
frame_skip=5 for fast processing without significant accuracy lossIf you use this model in your research, please cite:
@misc{rfdetr-soccernet-2025,
title={RF-DETR SoccerNet: High-Performance Soccer Object Detection},
author={Computer Vision Research Team},
year={2025},
publisher={Hugging Face},
url={https://huggingface.co/YOUR-USERNAME/rf-detr-soccernet}
}
Ready to analyze soccer like never before? 🚀⚽
Get started with python example.py and explore the power of AI-driven sports analytics!