Pipeline Guide¶
The Padex pipeline processes a padel match video through three stages: tracking, bounce detection, and shot classification.
Basic Usage¶
This is equivalent to:
The Padex Class¶
padex.Padex(
video_path="match.mp4",
calibration=None, # CourtCalibration, Path, or None
enable_pose=True, # Run pose estimation (needed for shot classification)
cache_tracking=True, # Cache tracking results as pickle
cache_dir=None, # Directory for cache files (default: next to video)
)
Calibration Resolution¶
When calibration is:
CourtCalibrationobject — Used directlyPathorstr— Loaded from JSON fileNone— Looks for<video_stem>_calibration.jsonnext to the video. If not found, raisesValueErrorwith instructions.
Pipeline Stages¶
Stage 1: Tracking¶
The slowest stage (~5 FPS on Apple Silicon). Processes every frame:
- Player detection: YOLO v26m detects up to 4 players, filtered by court boundaries
- Player tracking: ByteTrack assigns persistent IDs across frames
- Team classification: K-means clustering on jersey color histograms
- Pose estimation: YOLO-Pose extracts 17 keypoints per player (if
enable_pose=True) - Ball detection: TrackNet processes 3 consecutive frames as 9-channel input
- Ball tracking: Kalman filter fills detection gaps
Stage 2: Bounce Detection¶
Detects ball bounces by finding velocity direction reversals on smoothed trajectories. Each bounce is classified by surface:
ground— Ball hits the playing surfaceback_wall— Ball hits the back glass wallside_wall— Ball hits the side glass/fencenet— Ball hits the net
Stage 3: Shot Classification¶
Detects player-ball contact events and classifies each shot. See Shot Classification for details.
The PadexResult Object¶
result = padex.process("match.mp4", calibration="cal.json")
result.tracking # TrackingResult (player_frames, ball_frames)
result.bounces # list[Bounce]
result.shots # list[Shot]
result.calibration # CourtCalibration or None
Each shot contains:
shot.shot_id # e.g. "shot_001"
shot.shot_type # ShotType enum (e.g. ShotType.VOLLEY)
shot.player_id # e.g. "P_001"
shot.timestamp_ms # Contact time in milliseconds
shot.confidence # Classification confidence (0-1)
Tracking Cache¶
Tracking results are cached as pickle files to avoid re-running the slow tracking stage:
On subsequent runs, only bounce detection, shot classification, and video export run — taking seconds instead of minutes.
Disable caching:
Exporting Annotated Video¶
Or using the Padex instance:
p = padex.Padex("match.mp4", calibration="cal.json")
result = p.run()
p.export_video(result, "output/annotated.mp4")
The annotated video includes player bounding boxes, ball markers, court overlay lines, shot type labels (displayed for 1.5 seconds after each contact), and a stats overlay.