Nathan Zhou
← all projects

Squash Review

Phone footage of a squash match in, a positional match review out.

Squash Review turns ordinary phone video of a squash match into a post-match review. It tracks both players onto a to-scale model of the court, computes positional stats such as time on the T, court coverage and pressure, and has a language model turn those into a few coaching notes — each one citing the stat behind it.

A match report with coaching notes, each citing a statistic
The report: a few coaching notes, each citing the stat behind it.
A position heatmap, time on the T, rally pattern and rally length charts
Where you stood, how long you held the T, and how much of the rally you spent attacking.
The first step of a new review: uploading the match video
A new review: upload the video, pick a frame, mark the court.
The Squash Review landing page with a court diagram
The app itself, marbled in its own Court Red — where this site's background comes from.

How it works

  1. 01

    Court homography maps points, not pixels. You tap court landmarks on one frame, and each player's foot position (the midpoint of the ankle keypoints) becomes metres on the court. The image is never warped: only the floor is flat, so standing players would come out skewed.

  2. 02

    Code does the counting; the model only interprets. A deterministic stats engine writes a compact stat sheet in named zones and human units, with handedness applied in code. The model never sees per-frame data and must cite a stat for every claim, so a bad insight traces to bad data or bad reasoning.

  3. 03

    Tracking with a fixed cast of two: exactly two players on a known court is a two-target assignment problem, matched frame by frame with the Hungarian algorithm. When the players overlap it records a gap rather than guessing, and identity is anchored to your own tap on yourself.

  4. 04

    Rally structure from sound plus position: ball strikes pulled from the soundtrack mark where rallies start and end, fused with the tracks for each rally's length, shot count and where each player stood at the deciding shot.

  5. 05

    The vision worker pulls jobs from a Postgres queue, claims them atomically, sends heartbeats, and needs no inbound ports; a scheduled task reclaims jobs from workers that go quiet. The video is deleted once processed.

Built with

  • Next.js 16
  • TypeScript
  • Supabase
  • Cloudflare R2
  • Python
  • YOLO11 pose
  • OpenCV
  • React Native / Expo

Status

Runs end to end on real footage — upload, tracking, report — validated on one venue and camera so far. An iOS client is written but not yet tried on a device.

Worth knowing