AI sports app

Court Evolution Stroke Analyzer

A mobile web app for Court Evolution, a tennis and pickleball coaching program. Record a stroke on your phone and get a score, a breakdown by phase and specific fixes.

Court Evolution Stroke Analyzer phone screens: stroke picker, a forehand scored 88, and feedback with improvement tips
8stroke types across two sports
13body landmarks measured per frame
6key frames sent to the vision model

The challenge

I play tennis and pickleball, and the hardest part of fixing a stroke is seeing it. Lessons are expensive, and phone video alone doesn't tell you whether your knees were bent enough or your contact was out in front.

Court Evolution wanted something players could use between sessions: point a phone at yourself, swing, and get feedback that sounds like a coach rather than a generic score.

The approach

The backend runs a hybrid pass on each clip. OpenCV samples about 40 frames, MediaPipe Pose finds the body in each one, and the code turns 13 landmarks into 21 joint angles and distances: shoulder-hip separation (the X-factor), knee bend, how far the wrist reaches from the shoulder, stance width. Six evenly spaced frames plus that summary then go to Claude Vision with a stroke-specific prompt, so the coaching is grounded in measured numbers instead of guesses from pixels.

If there's no API key or the model's reply doesn't parse, a rule-based scorer takes over using fixed thresholds. The rules know that touch shots are different: for a dink, third-shot drop or volley, less rotation scores higher, because those strokes should stay compact.

  • Two sports, eight strokesForehand, backhand, serve and volley for tennis; dink, drive, serve and third-shot drop for pickleball.
  • Measured, not guessedKnee bend, X-factor, contact reach and wrist height come from MediaPipe landmarks on every sampled frame.
  • Coach-style feedbackEach stroke is compared with a reference model, such as a Sinner forehand or a Sampras serve, and every aspect gets one concrete fix.
  • Works without the AIA threshold scorer returns the same JSON shape when the vision model is unavailable, so the app never dead-ends.

From swing to score

  1. 01RecordUp to 10 s of WebM from the phone camera
  2. 02SampleOpenCV keeps about 40 frames
  3. 03MeasureMediaPipe landmarks to 21 angles per frame
  4. 04CoachClaude Vision, or threshold rules as fallback

Pick a sport, pick a stroke.

Choose tennis or pickleball and one of four strokes, then record. The clip stops itself at 10 seconds and uploads straight to the analysis endpoint.

Pickleball stroke picker with Third Shot Drop selected, and the Analyzing your stroke loading screen

One endpoint, whole pipeline.

Upload, frame sampling, pose detection, measurement and scoring all happen in a single FastAPI request. Every number in this diagram comes from the backend code.

Diagram of the pipeline: record, sample frames, MediaPipe landmarks, joint measurements, then Claude Vision or the fallback scorer, with the fallback thresholds listed

What the pose model sees.

Skeletons drawn from the landmarks the backend extracted on a test forehand. Pose was found in all 42 sampled frames, and the summary of those frames is what gets scored.

Five stick-figure skeletons from a forehand with knee angle, X-factor and wrist reach for each, plus the stroke summary and a fallback score of 88

Tools

  • Python
  • FastAPI
  • MediaPipe Pose
  • OpenCV
  • NumPy
  • Claude Vision API
  • Docker
  • PWA (HTML, CSS, JS)

Private repo, not deployed. Screens captured from the app served locally (April 2026 code) with the FastAPI backend running in MediaPipe-only mode, so the results shown come from the fallback scorer; the Claude Vision path was not run. The test clip and pose skeletons come from a CC BY-SA 2.5 instructional video by Evdcoldeportes on Wikimedia Commons.

Next projectHighlanderNowHighlanderNow interactive UC Riverside campus map