BikeControl (SwiftControl)
Use Zwift Click, Zwift Play, Shimano Di2, or any Bluetooth controller with MyWhoosh, Rouvy, Zwift, and more. Free to try on iOS, Android, Windows, and macOS.
翻訳待ち
PitchIQ turns a high school soccer match into stats a coach can use: tagged live from the sideline, read from the match video, and a private page for every player.
翻訳待ち
スポーツ・フィットネスPython · JavaScriptGitHub @Vega-77接続状況の再確認が必要です所有者未確認
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗PitchIQ turns video of a high-school football (soccer) match into stats a
coach can use: possession, territory, shape, a top-down map of every player,
shots and xG. Players get reports of their own as well. A tablet on the
touchline tags what the camera can't settle by itself (kick-off,
substitutions, restarts). The computer-vision pipeline in pitchiq/ turns the
match video and that tag log into a report JSON, and the site (GitHub Pages
and Firestore) shows the report to the coach and the players.
PitchIQ is source-available under the PolyForm Noncommercial License 1.0.0: free for non-commercial use, see License.
Working on the team's own footage: a panning (Hudl) camera calibrated from the match itself, the Hybrid 90 ball tracker, and reports on the site for the coach and the players. It is a research tool used by one team, not a finished product. The ball tracker finds about three balls in four on held-out clips and abstains on the rest, by design, but under floodlights it loses the ball almost entirely. Players and ball together on one top-down map is the next piece, and real footage needs a CUDA GPU. ROADMAP.md has where things stand and what is next.
Python 3.12, from a clone of the repo (Setup has the rest):
pip install -e .[test]
python -m pitchiq demo
demo draws a nine-second scripted match (coloured boxes: a long pass, a
touch, a shot), fits a fixed-camera calibration to it and runs
analyse_match with a scripted detector standing in for YOLO. It needs no
footage, GPU or weights and finishes in seconds; --out DIR keeps the clip,
the calibration and the report JSON. The numbers show the chain working, not
how well it sees a real match. On real fixed-camera footage the same steps
are grab_frame, calibrate and match_report (see FOOTAGE_DAY.md).
Fixed camera (pitchiq/calibration.py). One homography per camera position
maps pixels to metres. It is fitted once from landmarks clicked on a single
frame. This is the pipeline FOOTAGE_DAY.md was first written for. A tripod,
a locked-off shot, and that is all it needs.
Panning camera (pitchiq/panning_camera.py + pitchiq/balltrack/). The footage the team
actually has is from a Hudl camera that follows the play. Every frame gets its
own frame-to-pitch homography:
pitchiq/autocal.py calibrates the camera from the match itself, using the
paint plus SIFT between frames, andpitchiq/balltrack/pitch_registration/register_frames.py registers frames to a venue map.The ball comes from the Hybrid 90 tracker in pitchiq/balltrack/, and
PannedCamera moves everything into one still reference view. After that,
pitchiq/pipeline.py runs unchanged. This example requires a GPU and
generated data, so it does not run from a fresh clone:
from pitchiq.panning_camera import PannedCamera
from pitchiq.pipeline import analyse_match
camera = PannedCamera.from_tracker('fr00') # needs hybrid.sh outputs, see below
report = analyse_match(video, panned=camera, start_s=..., end_s=...)
from_tracker reads files that sh pitchiq/balltrack/hybrid.sh <lo> <hi> <tag>
(one window) or pitchiq/balltrack/half.py (a whole half) writes. They are
generated outputs, not in git (see pitchiq/balltrack/README.md, "Generated, not
in git"). Accuracy figures for the tracker are in that README too, and
FOOTAGE_DAY.md ("Fixed or panning") sets out which pipeline a camera needs.
| path | what |
|---|---|
pitchiq/ | the pipeline: detection, tracking, identity, calibration, ball, possession, events, top-down map, report JSON, publishing to Firestore |
pitchiq/cli/ | the match-day commands, run as python -m pitchiq <command>: grab_frame, calibrate, event_report, match_report, compare_reports, publish_report, demo |
pitchiq/experiments/ | research tools and labs: spike_detect, track_report, speed_report, autocal_run, player_lab, ... |
pitchiq/balltrack/ | the ball tracker for panning footage (Hybrid 90: detector + classifier + TAPNext++ bridges + 3D flight chain), and the venue map and registration in pitch_registration/ |
shared/ | shared frontend modules and CSS (no build step, plain ES modules) |
index.html | landing page and sign-in |
coach/ | coach dashboard: season, roster, matches, staff, player reports |
player/ | a player's own reports |
halftime/ | the three-minute read for the touchline |
live-tagging/ | match-day tablet tool |
calibrate/ | landmark pins on a frame or a panorama, exported for both calibrators |
xg_training/ | xG model training (main.py, StatsBomb open data -> ONNX) |
baselines/ | committed report JSONs that compare_reports checks changes against |
tests/ | Python (pytest) and JavaScript (node --test, Firestore emulator) suites |
docs/ | architecture, glossary, report schema, conventions, per-module design notes, history and generated figures |
tools/ | repo maintenance (audit_metrics.py) |
Python 3.12 (requires-python = ">=3.12"; CI tests 3.12 only). Clone the
repo and install it editable into a virtual environment. That is the only
supported install: the ball tracker and the panning-camera path read data
files that sit beside the code (the venue map, the ball ranker and
classifier), and a wheel or a plain pip install . does not carry them.
This is the beginning of the README. Read the rest at the original. Read the full README ↗
.github/workflows/ | CI: tests.yml (pytest, pyflakes, ruff, the JS suites, the rules emulator) and static.yml (deploys the site to GitHub Pages from main) |