Add/update INFERENCE_GUIDE.md - Enhanced repository with examples and documentation
Browse files- INFERENCE_GUIDE.md +482 -0
INFERENCE_GUIDE.md
ADDED
@@ -0,0 +1,482 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# RF-DETR SoccerNet - Complete Inference Guide
|
2 |
+
|
3 |
+
This guide provides comprehensive instructions for using the RF-DETR SoccerNet model for soccer video analysis.
|
4 |
+
|
5 |
+
## ๐ Quick Start
|
6 |
+
|
7 |
+
### Installation
|
8 |
+
|
9 |
+
```bash
|
10 |
+
# Clone the repository
|
11 |
+
git clone https://huggingface.co/julianzu9612/RFDETR-Soccernet
|
12 |
+
cd RFDETR-Soccernet
|
13 |
+
|
14 |
+
# Install dependencies
|
15 |
+
pip install -r requirements.txt
|
16 |
+
|
17 |
+
# Run the example
|
18 |
+
python example.py
|
19 |
+
```
|
20 |
+
|
21 |
+
### Basic Usage
|
22 |
+
|
23 |
+
```python
|
24 |
+
from inference import RFDETRSoccerNet
|
25 |
+
|
26 |
+
# Initialize model (auto-detects GPU/CPU)
|
27 |
+
model = RFDETRSoccerNet()
|
28 |
+
|
29 |
+
# Process a single image
|
30 |
+
df = model.process_image("your_image.jpg", confidence_threshold=0.5)
|
31 |
+
|
32 |
+
# Process a video
|
33 |
+
df = model.process_video("your_video.mp4", confidence_threshold=0.5)
|
34 |
+
```
|
35 |
+
|
36 |
+
## ๐ Output Format
|
37 |
+
|
38 |
+
All methods return a pandas DataFrame with these columns:
|
39 |
+
|
40 |
+
| Column | Type | Description |
|
41 |
+
|--------|------|-------------|
|
42 |
+
| `frame` | int | Frame number (for videos) |
|
43 |
+
| `timestamp` | float | Time in seconds (for videos) |
|
44 |
+
| `class_name` | str | Object class (ball, player, referee, goalkeeper) |
|
45 |
+
| `class_id` | int | Numeric class ID (0-3) |
|
46 |
+
| `x1, y1, x2, y2` | float | Bounding box coordinates |
|
47 |
+
| `width, height` | float | Bounding box dimensions |
|
48 |
+
| `confidence` | float | Detection confidence (0.0-1.0) |
|
49 |
+
| `center_x, center_y` | float | Bounding box center coordinates |
|
50 |
+
| `area` | float | Bounding box area in pixelsยฒ |
|
51 |
+
|
52 |
+
## ๐ฏ Detection Classes
|
53 |
+
|
54 |
+
| Class ID | Class Name | Color (BGR) | Description |
|
55 |
+
|----------|------------|-------------|-------------|
|
56 |
+
| 0 | ball | (0, 0, 255) | Soccer ball |
|
57 |
+
| 1 | player | (0, 255, 0) | Field players |
|
58 |
+
| 2 | referee | (255, 255, 0) | Referees and officials |
|
59 |
+
| 3 | goalkeeper | (0, 255, 255) | Goalkeepers |
|
60 |
+
|
61 |
+
## โ๏ธ Configuration Options
|
62 |
+
|
63 |
+
### Model Initialization
|
64 |
+
|
65 |
+
```python
|
66 |
+
# Default initialization (auto-detects CUDA/CPU)
|
67 |
+
model = RFDETRSoccerNet()
|
68 |
+
|
69 |
+
# Specify device explicitly
|
70 |
+
model = RFDETRSoccerNet(device="cuda") # or "cpu"
|
71 |
+
|
72 |
+
# Custom model path
|
73 |
+
model = RFDETRSoccerNet(model_path="path/to/your/checkpoint.pth")
|
74 |
+
```
|
75 |
+
|
76 |
+
### Image Processing
|
77 |
+
|
78 |
+
```python
|
79 |
+
df = model.process_image(
|
80 |
+
image_path="image.jpg",
|
81 |
+
confidence_threshold=0.5 # Only detections above 50% confidence
|
82 |
+
)
|
83 |
+
```
|
84 |
+
|
85 |
+
### Video Processing
|
86 |
+
|
87 |
+
```python
|
88 |
+
df = model.process_video(
|
89 |
+
video_path="video.mp4",
|
90 |
+
confidence_threshold=0.5, # Confidence threshold
|
91 |
+
frame_skip=1, # Process every N frames (1 = all frames)
|
92 |
+
max_frames=None, # Limit frames (None = all frames)
|
93 |
+
save_results=False, # Auto-save results to files
|
94 |
+
output_dir=None # Directory for saved results
|
95 |
+
)
|
96 |
+
```
|
97 |
+
|
98 |
+
## ๐ Performance Optimization
|
99 |
+
|
100 |
+
### Hardware Recommendations
|
101 |
+
|
102 |
+
| Hardware | Expected FPS | Memory Usage | Batch Size |
|
103 |
+
|----------|--------------|--------------|------------|
|
104 |
+
| RTX 4070 8GB | 10-15 FPS | 6GB VRAM | 1-2 |
|
105 |
+
| RTX 3080 10GB | 12-18 FPS | 7GB VRAM | 2-4 |
|
106 |
+
| A100 40GB | 25-35 FPS | 8GB VRAM | 4-8 |
|
107 |
+
| CPU (16 cores) | 2-4 FPS | 4GB RAM | 1 |
|
108 |
+
|
109 |
+
### Speed vs Accuracy Trade-offs
|
110 |
+
|
111 |
+
```python
|
112 |
+
# Maximum accuracy (slower)
|
113 |
+
df = model.process_video("video.mp4", confidence_threshold=0.3, frame_skip=1)
|
114 |
+
|
115 |
+
# Balanced (recommended)
|
116 |
+
df = model.process_video("video.mp4", confidence_threshold=0.5, frame_skip=2)
|
117 |
+
|
118 |
+
# Maximum speed (less accurate)
|
119 |
+
df = model.process_video("video.mp4", confidence_threshold=0.7, frame_skip=5)
|
120 |
+
```
|
121 |
+
|
122 |
+
### Batch Processing
|
123 |
+
|
124 |
+
```python
|
125 |
+
import os
|
126 |
+
from pathlib import Path
|
127 |
+
|
128 |
+
# Process multiple images
|
129 |
+
image_dir = Path("images/")
|
130 |
+
results = []
|
131 |
+
|
132 |
+
for image_path in image_dir.glob("*.jpg"):
|
133 |
+
df = model.process_image(str(image_path))
|
134 |
+
df['source_file'] = image_path.name
|
135 |
+
results.append(df)
|
136 |
+
|
137 |
+
# Combine all results
|
138 |
+
all_results = pd.concat(results, ignore_index=True)
|
139 |
+
```
|
140 |
+
|
141 |
+
## ๐จ Visualization
|
142 |
+
|
143 |
+
### Basic Visualization
|
144 |
+
|
145 |
+
```python
|
146 |
+
import cv2
|
147 |
+
import pandas as pd
|
148 |
+
|
149 |
+
def draw_detections(image_path, df, output_path):
|
150 |
+
"""Draw bounding boxes on image."""
|
151 |
+
|
152 |
+
# Load image
|
153 |
+
image = cv2.imread(image_path)
|
154 |
+
|
155 |
+
# Colors for each class (BGR)
|
156 |
+
colors = {
|
157 |
+
'ball': (0, 0, 255), # Red
|
158 |
+
'player': (0, 255, 0), # Green
|
159 |
+
'referee': (255, 255, 0), # Yellow
|
160 |
+
'goalkeeper': (0, 255, 255) # Cyan
|
161 |
+
}
|
162 |
+
|
163 |
+
# Draw each detection
|
164 |
+
for _, det in df.iterrows():
|
165 |
+
x1, y1, x2, y2 = int(det['x1']), int(det['y1']), int(det['x2']), int(det['y2'])
|
166 |
+
class_name = det['class_name']
|
167 |
+
confidence = det['confidence']
|
168 |
+
|
169 |
+
color = colors.get(class_name, (255, 255, 255))
|
170 |
+
|
171 |
+
# Draw bounding box
|
172 |
+
cv2.rectangle(image, (x1, y1), (x2, y2), color, 2)
|
173 |
+
|
174 |
+
# Draw label
|
175 |
+
label = f"{class_name}: {confidence:.2f}"
|
176 |
+
cv2.putText(image, label, (x1, y1-10),
|
177 |
+
cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2)
|
178 |
+
|
179 |
+
# Save result
|
180 |
+
cv2.imwrite(output_path, image)
|
181 |
+
|
182 |
+
# Usage
|
183 |
+
df = model.process_image("examples/sample_soccer_frame.jpg")
|
184 |
+
draw_detections("examples/sample_soccer_frame.jpg", df, "result.jpg")
|
185 |
+
```
|
186 |
+
|
187 |
+
### Advanced Visualization with Matplotlib
|
188 |
+
|
189 |
+
```python
|
190 |
+
import matplotlib.pyplot as plt
|
191 |
+
import matplotlib.patches as patches
|
192 |
+
from PIL import Image
|
193 |
+
|
194 |
+
def plot_detections(image_path, df):
|
195 |
+
"""Plot detections using matplotlib."""
|
196 |
+
|
197 |
+
# Load image
|
198 |
+
img = Image.open(image_path)
|
199 |
+
|
200 |
+
# Create plot
|
201 |
+
fig, ax = plt.subplots(1, figsize=(12, 8))
|
202 |
+
ax.imshow(img)
|
203 |
+
|
204 |
+
# Colors for classes
|
205 |
+
colors = {'ball': 'red', 'player': 'green', 'referee': 'yellow', 'goalkeeper': 'cyan'}
|
206 |
+
|
207 |
+
# Plot each detection
|
208 |
+
for _, det in df.iterrows():
|
209 |
+
x1, y1 = det['x1'], det['y1']
|
210 |
+
width, height = det['width'], det['height']
|
211 |
+
class_name = det['class_name']
|
212 |
+
confidence = det['confidence']
|
213 |
+
|
214 |
+
# Create rectangle
|
215 |
+
rect = patches.Rectangle((x1, y1), width, height,
|
216 |
+
linewidth=2, edgecolor=colors.get(class_name, 'white'),
|
217 |
+
facecolor='none')
|
218 |
+
ax.add_patch(rect)
|
219 |
+
|
220 |
+
# Add label
|
221 |
+
ax.text(x1, y1-5, f"{class_name}: {confidence:.2f}",
|
222 |
+
color='white', fontsize=10, weight='bold',
|
223 |
+
bbox=dict(boxstyle='round,pad=0.3', facecolor=colors.get(class_name, 'white')))
|
224 |
+
|
225 |
+
ax.set_title("RF-DETR SoccerNet Detections")
|
226 |
+
ax.axis('off')
|
227 |
+
plt.tight_layout()
|
228 |
+
plt.show()
|
229 |
+
|
230 |
+
# Usage
|
231 |
+
df = model.process_image("examples/sample_soccer_frame.jpg")
|
232 |
+
plot_detections("examples/sample_soccer_frame.jpg", df)
|
233 |
+
```
|
234 |
+
|
235 |
+
## โฝ Advanced Analytics
|
236 |
+
|
237 |
+
### Ball Possession Analysis
|
238 |
+
|
239 |
+
```python
|
240 |
+
# Load video detections
|
241 |
+
df = model.process_video("match.mp4")
|
242 |
+
|
243 |
+
# Analyze ball possession (players within 100 pixels of ball)
|
244 |
+
possession_df = model.analyze_ball_possession(df, distance_threshold=100)
|
245 |
+
|
246 |
+
# Results include:
|
247 |
+
# - frame: Frame number
|
248 |
+
# - timestamp: Time in seconds
|
249 |
+
# - player_x, player_y: Player center coordinates
|
250 |
+
# - ball_x, ball_y: Ball center coordinates
|
251 |
+
# - distance_to_ball: Distance in pixels
|
252 |
+
# - ball_confidence, player_confidence: Detection confidences
|
253 |
+
|
254 |
+
print(f"Possession events: {len(possession_df)}")
|
255 |
+
print(f"Average distance to ball: {possession_df['distance_to_ball'].mean():.1f} px")
|
256 |
+
```
|
257 |
+
|
258 |
+
### Formation Analysis
|
259 |
+
|
260 |
+
```python
|
261 |
+
def analyze_formation(df, frame_number):
|
262 |
+
"""Analyze player formation for a specific frame."""
|
263 |
+
|
264 |
+
frame_data = df[df['frame'] == frame_number]
|
265 |
+
players = frame_data[frame_data['class_name'] == 'player']
|
266 |
+
|
267 |
+
if len(players) < 5:
|
268 |
+
return "Insufficient players detected"
|
269 |
+
|
270 |
+
# Calculate formation metrics
|
271 |
+
positions = players[['center_x', 'center_y']].values
|
272 |
+
|
273 |
+
# Find centroid
|
274 |
+
centroid_x = positions[:, 0].mean()
|
275 |
+
centroid_y = positions[:, 1].mean()
|
276 |
+
|
277 |
+
# Calculate spread
|
278 |
+
spread = np.sqrt(((positions - [centroid_x, centroid_y])**2).sum(axis=1)).mean()
|
279 |
+
|
280 |
+
return {
|
281 |
+
'frame': frame_number,
|
282 |
+
'num_players': len(players),
|
283 |
+
'centroid': (centroid_x, centroid_y),
|
284 |
+
'formation_spread': spread,
|
285 |
+
'player_positions': positions.tolist()
|
286 |
+
}
|
287 |
+
|
288 |
+
# Analyze formation for frame 100
|
289 |
+
formation = analyze_formation(df, 100)
|
290 |
+
print(f"Formation analysis: {formation}")
|
291 |
+
```
|
292 |
+
|
293 |
+
### Game Statistics
|
294 |
+
|
295 |
+
```python
|
296 |
+
def calculate_game_stats(df):
|
297 |
+
"""Calculate comprehensive game statistics."""
|
298 |
+
|
299 |
+
stats = {
|
300 |
+
'total_frames': df['frame'].nunique(),
|
301 |
+
'duration_seconds': df['timestamp'].max() - df['timestamp'].min(),
|
302 |
+
'total_detections': len(df),
|
303 |
+
'detections_per_second': len(df) / (df['timestamp'].max() - df['timestamp'].min()),
|
304 |
+
'class_distribution': df['class_name'].value_counts().to_dict(),
|
305 |
+
'average_confidence': df['confidence'].mean(),
|
306 |
+
'ball_detection_rate': len(df[df['class_name'] == 'ball']) / df['frame'].nunique(),
|
307 |
+
'players_per_frame': df[df['class_name'] == 'player'].groupby('frame').size().mean()
|
308 |
+
}
|
309 |
+
|
310 |
+
return stats
|
311 |
+
|
312 |
+
# Calculate stats
|
313 |
+
stats = calculate_game_stats(df)
|
314 |
+
for key, value in stats.items():
|
315 |
+
print(f"{key}: {value}")
|
316 |
+
```
|
317 |
+
|
318 |
+
## ๐พ Export and Integration
|
319 |
+
|
320 |
+
### Export Formats
|
321 |
+
|
322 |
+
```python
|
323 |
+
# CSV for spreadsheet analysis
|
324 |
+
model.save_results(df, "detections.csv", format="csv")
|
325 |
+
|
326 |
+
# JSON for web applications
|
327 |
+
model.save_results(df, "detections.json", format="json", include_metadata=True)
|
328 |
+
|
329 |
+
# Parquet for big data processing
|
330 |
+
model.save_results(df, "detections.parquet", format="parquet")
|
331 |
+
```
|
332 |
+
|
333 |
+
### Integration with Other Tools
|
334 |
+
|
335 |
+
#### Pandas Integration
|
336 |
+
|
337 |
+
```python
|
338 |
+
# Filter high-confidence ball detections
|
339 |
+
balls = df[(df['class_name'] == 'ball') & (df['confidence'] > 0.7)]
|
340 |
+
|
341 |
+
# Group by frame and calculate averages
|
342 |
+
frame_stats = df.groupby('frame').agg({
|
343 |
+
'confidence': 'mean',
|
344 |
+
'class_name': 'count'
|
345 |
+
}).rename(columns={'class_name': 'detection_count'})
|
346 |
+
|
347 |
+
# Time-based analysis
|
348 |
+
df['time_bin'] = (df['timestamp'] // 10) * 10 # 10-second bins
|
349 |
+
time_analysis = df.groupby(['time_bin', 'class_name']).size().unstack(fill_value=0)
|
350 |
+
```
|
351 |
+
|
352 |
+
#### OpenCV Integration
|
353 |
+
|
354 |
+
```python
|
355 |
+
import cv2
|
356 |
+
|
357 |
+
def create_annotated_video(video_path, df, output_path):
|
358 |
+
"""Create video with detection annotations."""
|
359 |
+
|
360 |
+
cap = cv2.VideoCapture(video_path)
|
361 |
+
fps = int(cap.get(cv2.CAP_PROP_FPS))
|
362 |
+
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
363 |
+
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
364 |
+
|
365 |
+
# Create video writer
|
366 |
+
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
367 |
+
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
|
368 |
+
|
369 |
+
frame_count = 0
|
370 |
+
while cap.isOpened():
|
371 |
+
ret, frame = cap.read()
|
372 |
+
if not ret:
|
373 |
+
break
|
374 |
+
|
375 |
+
# Get detections for this frame
|
376 |
+
frame_detections = df[df['frame'] == frame_count]
|
377 |
+
|
378 |
+
# Draw detections (add your visualization code here)
|
379 |
+
# ... drawing code ...
|
380 |
+
|
381 |
+
out.write(frame)
|
382 |
+
frame_count += 1
|
383 |
+
|
384 |
+
cap.release()
|
385 |
+
out.release()
|
386 |
+
```
|
387 |
+
|
388 |
+
## ๐ง Troubleshooting
|
389 |
+
|
390 |
+
### Common Issues
|
391 |
+
|
392 |
+
#### 1. CUDA Out of Memory
|
393 |
+
```python
|
394 |
+
# Reduce batch size or use CPU
|
395 |
+
model = RFDETRSoccerNet(device="cpu")
|
396 |
+
|
397 |
+
# Or process smaller chunks
|
398 |
+
df = model.process_video("video.mp4", max_frames=100)
|
399 |
+
```
|
400 |
+
|
401 |
+
#### 2. Low Detection Accuracy
|
402 |
+
```python
|
403 |
+
# Lower confidence threshold
|
404 |
+
df = model.process_video("video.mp4", confidence_threshold=0.3)
|
405 |
+
|
406 |
+
# Check image quality and lighting
|
407 |
+
# Ensure video resolution is adequate (720p+ recommended)
|
408 |
+
```
|
409 |
+
|
410 |
+
#### 3. Memory Issues with Large Videos
|
411 |
+
```python
|
412 |
+
# Process in chunks
|
413 |
+
chunk_size = 1000
|
414 |
+
all_results = []
|
415 |
+
|
416 |
+
for start_frame in range(0, total_frames, chunk_size):
|
417 |
+
chunk_df = model.process_video("video.mp4",
|
418 |
+
max_frames=chunk_size,
|
419 |
+
frame_skip=start_frame)
|
420 |
+
all_results.append(chunk_df)
|
421 |
+
|
422 |
+
final_df = pd.concat(all_results, ignore_index=True)
|
423 |
+
```
|
424 |
+
|
425 |
+
### Performance Monitoring
|
426 |
+
|
427 |
+
```python
|
428 |
+
import time
|
429 |
+
import psutil
|
430 |
+
import torch
|
431 |
+
|
432 |
+
def monitor_inference(model, video_path):
|
433 |
+
"""Monitor inference performance."""
|
434 |
+
|
435 |
+
start_time = time.time()
|
436 |
+
start_memory = psutil.Process().memory_info().rss / 1024 / 1024 # MB
|
437 |
+
|
438 |
+
if torch.cuda.is_available():
|
439 |
+
start_gpu_memory = torch.cuda.memory_allocated() / 1024 / 1024 # MB
|
440 |
+
|
441 |
+
# Run inference
|
442 |
+
df = model.process_video(video_path, max_frames=100)
|
443 |
+
|
444 |
+
end_time = time.time()
|
445 |
+
end_memory = psutil.Process().memory_info().rss / 1024 / 1024
|
446 |
+
|
447 |
+
print(f"Processing time: {end_time - start_time:.2f}s")
|
448 |
+
print(f"Memory usage: {end_memory - start_memory:.2f} MB")
|
449 |
+
print(f"Frames processed: {df['frame'].nunique()}")
|
450 |
+
print(f"FPS: {df['frame'].nunique() / (end_time - start_time):.2f}")
|
451 |
+
|
452 |
+
if torch.cuda.is_available():
|
453 |
+
end_gpu_memory = torch.cuda.memory_allocated() / 1024 / 1024
|
454 |
+
print(f"GPU memory usage: {end_gpu_memory - start_gpu_memory:.2f} MB")
|
455 |
+
|
456 |
+
# Usage
|
457 |
+
monitor_inference(model, "test_video.mp4")
|
458 |
+
```
|
459 |
+
|
460 |
+
## ๐ Additional Resources
|
461 |
+
|
462 |
+
- **Model Card**: Detailed performance metrics and training information
|
463 |
+
- **Example Scripts**: Complete working examples in `example.py`
|
464 |
+
- **Sample Data**: Test images and detection results in `examples/`
|
465 |
+
- **GitHub Issues**: Report bugs and request features
|
466 |
+
- **Documentation**: Full API reference and tutorials
|
467 |
+
|
468 |
+
## ๐ Best Practices
|
469 |
+
|
470 |
+
1. **Data Quality**: Use high-quality video (720p+) with good lighting
|
471 |
+
2. **Confidence Thresholds**: Start with 0.5, adjust based on results
|
472 |
+
3. **Performance**: Use GPU for real-time processing, CPU for batch jobs
|
473 |
+
4. **Memory**: Monitor memory usage for long videos
|
474 |
+
5. **Validation**: Always validate results on sample data first
|
475 |
+
6. **Export**: Save results in appropriate format for downstream analysis
|
476 |
+
|
477 |
+
## ๐ Support
|
478 |
+
|
479 |
+
For technical support, bug reports, or feature requests:
|
480 |
+
- **Repository**: [Hugging Face Model Page](https://huggingface.co/julianzu9612/RFDETR-Soccernet)
|
481 |
+
- **Issues**: Use the Issues tab for bug reports
|
482 |
+
- **Community**: Join discussions in the Community tab
|