Inspiration

College teams film games on a phone from the stands. I wanted to turn that footage into tactics like team shape and heatmaps. But in my test clip the camera drifted about 135 pixels, so every player position silently slid several metres. Numbers that look right but aren't are worse than no numbers. So Touchline AI became analysis that knows when it's wrong.

What it does

Upload a 10–30 s clip and mark four points on the pitch. An agent then checks each ~4 s segment:

  • Perceive: track players, map them onto a top-down pitch, and measure its own quality.
  • Decide: camera moved → update the calibration; tracking broke up → sample frames more densely.
  • Act: rerun that segment and keep the fix only if it measurably helps on the same frames.
  • Escalate: after two failed attempts, flag the segment and ask the coach.

It's rule-based, with no LLM in the loop, so every decision is reproducible and logged.

How I built it

OpenCV 5 does the vision: field segmentation, line detection, homography calibration, camera-motion tracking (ORB / optical flow + MAGSAC), Kalman tracking, and a YOLOX-S detector run through cv2.dnn. To check the geometry, it warps each frame's painted lines onto the calibration frame and scores how well they line up.

Stack: FastAPI, SQLite, React/TypeScript, Docker. On AWS, an EC2 worker processes clips from encrypted S3 storage.

Results

  • Fixed camera drift in all 4 segments of a real clip (line alignment 0.2–0.5 → 0.8–0.9)
  • Position error after camera movement: 7.9 m → 0.6 m
  • Right action in 8 of 9 stress tests
  • Runs end to end on EC2 + S3

Challenges

  • My quality check fooled me: photographers at the pitch edge slipped past the spectator filter, so I fixed the filter instead of loosening the threshold.
  • Checks that fought each other: a valid camera fix was vetoed by unrelated tracking noise, so each fix is now judged on its own evidence.
  • Lying video files: a header claimed 120 fps, so I now read timing from the decoded frames.
  • Real-world AWS: a region lock, free-tier limits, and a changing IP, each solved with a script.

What I learned

  • "I'm not sure" is a feature, not a failure.
  • Compare fixes on identical frames.
  • Say what you don't measure.
  • Test your tests.

What's next

Catching calibrations that are wrong from the start, adding player re-identification, and getting human-verified evaluation labels.

Built With

Share this project:

Updates

Submission history