Skip to content

Architecture

Padex is organized into three layers, each building on the previous.

Three-Layer Pipeline

Layer 1: Tracking          Layer 2: Events           Layer 3: Tactics
┌──────────────────┐      ┌──────────────────┐      ┌──────────────────┐
│  Court Calibration│      │  Bounce Detection │      │  Rally Metrics   │
│  Player Detection │ ───▶ │  Shot Detection   │ ───▶ │  Player Metrics  │
│  Ball Tracking    │      │  Shot Classification│    │  Team Metrics    │
└──────────────────┘      └──────────────────┘      └──────────────────┘

Layer 1: Tracking (padex.tracking)

CV pipeline that processes video frame-by-frame.

Component Model Purpose
Player detection YOLO v26m Bounding box detection, confidence > 0.5, max 4 players
Player tracking ByteTrack Cross-frame ID assignment
Team classification K-means on HSV histograms Jersey color clustering into T_1 / T_2
Pose estimation YOLO-Pose v26m 17 COCO keypoints per player
Ball detection TrackNet 3-frame CNN, 640x360 heatmap output
Ball tracking Kalman filter 4D state [x, y, vx, vy], gap-filling
Court calibration Homography 12-point pixel-to-meter mapping

Layer 2: Events (padex.events)

Derives discrete match events from tracking data.

  • Bounce detection — Velocity direction reversal on smoothed trajectories, classified by court geometry (ground, back_wall, side_wall, etc.)
  • Shot detection — Proximity + velocity change between ball and player
  • Shot classification — Three-signal decision tree: pre-contact ball state + player pose + post-contact trajectory

Layer 3: Tactics (padex.tactics)

Computes tactical metrics from events. Rally-level, player-level, and team-level analytics.

Coordinate System

         y = 20.0 (far baseline)
    ┌─────────────────────┐
    │                     │
    │    Far service box   │  y = 17.0
    │─────────────────────│
    │                     │
    │        NET          │  y = 10.0
    │                     │
    │─────────────────────│
    │   Near service box   │  y = 3.0
    │                     │
    └─────────────────────┘
  x=0                   x=10.0
         y = 0.0 (near baseline)
  • Origin: Bottom-left corner of the court
  • x-axis: 0 to 10.0 meters (court width)
  • y-axis: 0 to 20.0 meters (court length)
  • z-axis: Height in meters (optional, used for 3D ball position)
  • Net: y = 10.0

Data Flow

raw video
    ├─► Court Calibration ──► homography matrix (3x3)
    ├─► Player Detection ──► PlayerFrame (bbox, position, pose, team)
    └─► Ball Detection ────► BallFrame (position, visibility)
            ├─► Bounce Detection ──► Bounce (type, position, timestamp)
            └─► Shot Detection ────► Shot (type, player, timestamp, confidence)

Data Formats

Layer Format Reason
Tracking Parquet Columnar, efficient for millions of rows at 30fps
Events JSONL Streaming, nested structures (trajectory arrays)
Structure JSON Match/set/game/point hierarchy
Calibration JSON Small, human-readable

Package Structure

src/padex/
├── __init__.py          # Top-level API: Padex, process, export_video
├── pipeline.py          # Pipeline orchestrator
├── calibration.py       # Interactive court calibration
├── weights.py           # Model weight management + auto-download
├── cli.py               # Command-line interface
├── tracking/            # Layer 1
│   ├── pipeline.py      # TrackingPipeline
│   ├── court.py         # Court detection + homography
│   ├── player.py        # Player detection + tracking + pose
│   ├── ball.py          # Ball detection (TrackNet / SAHI+YOLO)
│   └── device.py        # Hardware auto-detection
├── events/              # Layer 2
│   ├── shot.py          # Shot detection + classification
│   ├── bounce.py        # Bounce detection
│   ├── point.py         # Point/rally segmentation
│   └── taxonomy.py      # Shot type definitions
├── tactics/             # Layer 3
│   ├── metrics.py       # Metric computation
│   ├── heatmap.py       # Spatial analysis
│   └── report.py        # Report generation
├── schemas/             # Pydantic data models
├── io/                  # Video, Parquet, JSONL I/O
└── viz/                 # Visualization + annotation