Automatic court detection, and four corners you still have to click
🏸 AI Badminton Hawk-Eye System
At a glance
- What is it?
- A computer vision pipeline for badminton match video: pose estimation across three model families, shuttlecock tracking, image-to-court coordinate mapping, rally detection, heatmaps and an annotated video. The parts worth reading are the ones where a person is still in the loop, the two OpenCV packages installed side by side, the split between the CPU and GPU ONNX pins, and the single benchmark line the project offers.
- Who is it for?
- Good-Badminton is a research-grade analysis tool rather than a finished product, and the project is fairly direct about that, listing hit-point recognition, a better shuttlecock model, fuller technique statistics and batch processing as unfinished. Use it if you want per-frame pose and shuttlecock data with court coordinates and rally numbering out of a match recording, and if you are willing to click four court corners once per camera angle.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 100 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 4, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Both OpenCV packages pinned to the same version, and a Python floor nothing verifies
The requirements file is short and mostly pinned:
opencv-python==4.10.0.84
opencv-contrib-python==4.10.0.84
numpy>=1.21.6,<2.0
pillow>=9.2.0,<12.0
--extra-index-url https://download.pytorch.org/whl/cpu
torch==2.5.1+cpu
torchvision==0.20.1+cpu
ultralytics>=8.0.0
rtmlib>=0.0.1
onnxruntime==1.18.1
pandas>=1.3.0
matplotlib>=3.5.0
seaborn>=0.11.0
moviepy>=1.0.3,<2.0
scipy>=1.7.0
scikit-learn>=1.0.0
openpyxl>=3.0.0Two things stand out. The standard and contrib OpenCV packages are both pinned to the same build, which is the pairing most likely to overwrite one of the two module trees in an environment. And the documentation asks for Python 3.8 or newer while every pinned wheel here is a current-generation one, so the floor is asserted in prose and never checked against the pins.
There is no packaging manifest at all, no pyproject and no setup script, only requirements.txt plus a separate requirements-webui.txt for the optional Gradio interface. Everything runs from a clone with python main.py, which is why the install instructions are two nearly identical venv blocks for Windows and for Linux and macOS.
The rest of the list explains the outputs: moviepy writes the annotated video, matplotlib and seaborn draw the heatmaps and scatter plots, openpyxl is what makes the exported detection data a spreadsheet, and the extra index URL is why the default install resolves a CPU build of PyTorch.
The GPU path installs onnxruntime-gpu 1.20.1 over a requirements file pinning 1.18.1
The default install is CPU-only: CPU PyTorch and ONNX Runtime, both pulled through the extra index URL in the requirements file. GPU acceleration is a separate documented procedure that starts by removing what the CPU install brought:
pip uninstall -y torch torchvision onnxruntime onnxruntime-gpu
pip install torch==2.5.1+cu121 torchvision==0.20.1+cu121 --index-url https://download.pytorch.org/whl/cu121
pip install onnxruntime-gpu==1.20.1Note the version. The requirements file pins onnxruntime at 1.18.1 and the GPU procedure installs onnxruntime-gpu at 1.20.1, so the two paths do not agree on which release of that library you end up with, and moving between them is a reinstall rather than a flag.
The verification step is thorough: one command prints the torch version, whether CUDA is available and the device name, a second prints the ONNX Runtime version and its available providers, and the expected output is cuda: True and CUDAExecutionProvider.
Then comes the warning that tells you to ignore your package manager. After installing the GPU runtime, pip check may report that rtmlib requires onnxruntime, which is not installed, and the instruction is that as long as the provider check shows CUDAExecutionProvider you should not install the CPU onnxruntime package again because it may overwrite the GPU one. Going back to CPU is a force reinstall of the requirements file.
Automatic court detection, and a template image you still have to supply
Automatic court boundary detection is on the finished list, and the changelog shows it was tuned on 2026-06-27 to reduce mismatches. The model matches the white or yellow court lines of a standard badminton court, and the WebUI lets you correct the four corners by hand afterwards.
The workflow around it is where the manual part stays. In the browser interface you upload the match video and a court template image, click the detect-court button, and then, if the result is wrong, click four corners on the image yourself and press the button that applies the manual corners. Automatic detection saves a preview, and accepting it still takes a keypress.
The command line is the same story with fewer affordances. Running the entry point without a template path pops up a file picker for the template image, the suggestion being a frame from the video where the view is steady and the lines are clear. Automatic detection writes a preview image, and Enter or Y accepts it while M, R or Escape drops into manual annotation. The manual order is fixed: top-left, top-right, bottom-right, bottom-left.
So automatic detection decides where to start, and a person still decides where the court is.
The corner cache is keyed by output directory, so a new camera angle reuses old corners
Once you have clicked the four points, the coordinates are written to court_annotations.txt inside the output directory, and the next run in the same directory reuses that file instead of asking again. That is a good default for iterating on parameters and a trap when the geometry changes.
Nothing validates the cache. The documentation's own instruction is that if you change the video angle, the cropping, or the template image, you must delete the matching court_annotations.txt from the output directory and annotate again. The cache is identified by output directory, and the output directory defaults to outputs/ followed by the video's filename, so it is keyed by which file you are analysing and not by what the camera was doing.
The four points are load-bearing in a way that is spelled out clearly, which is to the project's credit. They establish the mapping from image coordinates to standard court coordinates. Player filtering depends mainly on that mapping, which is how spectators, umpires and people off court get excluded. The upper-half and lower-half player judgement, movement distance, current and maximum speed, rally counts, heatmaps and scatter plots all sit downstream of it. Rally detection itself is template matching against the court view: consecutive frames identified as the match view open a rally, consecutive frames leaving it close one, and the rally number is written into both the video overlay and the detection data.
The pose ROI shrinks the inference area, and the shuttlecock stays on the whole frame
After the four points are set, the window shows a green court box and a blue pose-detection ROI box, and the ROI is generated automatically by expanding out from the court bounds. The stated purpose is narrow and sensible: it exists only to cut the area the pose model has to look at, and therefore to go faster.
The exception is the interesting part. Shuttlecock detection still runs on the entire frame. Trajectory drawing is filtered afterwards, using the court's horizontal extent plus a padding margin, which is a display filter rather than a detection one.
That is a deliberate trade with a real cost. The shuttlecock is the fastest object in the scene and the one a global detector has to find against a background of crowd, court and advertising boards, so the one detection that most needs full-frame resolution is the one excluded from the optimisation. Everything else in the list of reasons to annotate, from player filtering to the rally counter, does benefit from the ROI.
The pose models themselves come in three families with a tier selector. RTMPose is two-stage and defaults to the balanced tier, with lightweight for speed and performance for a larger, slower model that favours detection quality. RTMO is the lighter one-stage option. Ultralytics YOLO Pose is selected by family name with a model file, and the documented default is yolo11n-pose.pt, the smallest of the set.
One benchmark line, at 720p, on the smallest pose model, naming no hardware
The performance section recommends a GPU with 6GB or more of memory, 16GB or more of system memory and an SSD, and says explicitly that the numbers depend on the graphics card, the video resolution, the pose model, whether the preview window is displayed, and whether audio is kept. A CPU can run the whole pipeline, with pose and shuttlecock detection markedly slower, which is described as fine for short clips or feature checks.
The single concrete figure offered is a GPU inference log line, given for 720p input with the YOLO Pose family, the nano pose model and weights/yolo11s-ball.pt:
pose 0.02s, shuttlecock 0.02s, shuttle draw 0.00s, players draw 0.01s, court draw 0.00sTwo tenths of a second of inference per frame, on the smallest pose model available, with no GPU named and no end-to-end throughput figure to go with it. No frame rate, no video length, no test set. Turning on the performance-stats flag prints a summary roughly every five seconds so you can see whether the bottleneck is pose inference, shuttlecock detection or drawing, which is the more useful way to find out.
The recommendation list is honest about the shape of the problem: more memory suits higher resolutions and larger pose models, which is the same relationship the log line cannot show you.
The documented default for skeletons is written as tr
The parameter table is the reference section, and one value in it is mistyped. Every flag is given with a default, and the skeleton overlay's default is printed as tr rather than true:
--video-path 输入视频路径,必填
--output-dir 输出目录,默认 outputs/<视频文件名>
--ball-model YOLO 羽毛球检测模型路径,默认 weights/yolo11s-ball.pt
--pose-family 姿态模型族:rtmpose、rtmo 或 yolo-pose
--pose-mode RTMPose / RTMO 档位:lightweight、balanced、performance
--yolo-pose-model YOLO pose 模型路径或模型名,默认 yolo11n-pose.pt
--template-path 球场模板图路径;不传时会弹出文件选择框
--pose-roi true|false 是否显示姿态检测 ROI 框,默认 true
--display true|false 是否显示 OpenCV 预览窗口,默认 true
--skeletons true|false 是否显示人体骨架,默认 trSmall thing, but it is in the one table a user reads to find out what they can turn off, and a reader has no way to tell whether that flag means tr is accepted or whether the default is genuinely broken.
The outputs listed under it are more thorough: metadata.json for the video, models, court annotations and output files; detections.jsonl with per-frame rally numbers, players, hands, court coordinates, speed and shuttlecock coordinates; the annotated MP4 with skeleton, trajectory, statistics and rally overlays; the annotation cache; and heatmap and scatter directories. The visual overlay language is switched with a separate flag taking zh or en.
A Chinese font at the root, one release, and two sibling projects with an empty Stars column
The repository root explains several things at a glance: a requirements file for the runtime, a second one for the optional web interface, the main entry script, an analysis package, a webui package, assets, templates, a videos directory that holds the demo clip the usage examples reference, and simhei.ttf sitting at the top level. That font file is the reason the overlay language is switchable between Chinese and English, since rendering Chinese text into a video needs a font shipped alongside the code.
There is one release, v0.1.0 on 2026-06-20, which the changelog marks as the formal open-sourcing. The last push to main is 2026-07-03. The badminton detection weights the documentation tells you to download are attached to GitHub Releases, so in practice that single release is also the weights distribution, and there is no versioned model history behind it.
The README is in Chinese with an English version linked at the top and a second README file in the tree. It opens by placing the project in a family: Good-Tennis and Good-Pickleball run on the same ideas, with player detection, ball tracking, court mapping, trajectory statistics and visual output, differing only in court model, detection target and rules. The comparison table above that has a Stars column whose cells hold only badge images rather than numbers.
The project structure listing at the end starts at main.py, described as the command line entry point and argument parsing, and stops partway through that line's description, so the layout of the analysis package is not shown.
Editorial conclusion
Good-Badminton is a research-grade analysis tool rather than a finished product, and the project is fairly direct about that, listing hit-point recognition, a better shuttlecock model, fuller technique statistics and batch processing as unfinished. Use it if you want per-frame pose and shuttlecock data with court coordinates and rally numbering out of a match recording, and if you are willing to click four court corners once per camera angle. Skip it if you need turnkey batch processing, if your matches are filmed from an angle the court template matching does not recognise, or if you need hit-point analysis today. Three practical checks first: whether your Python is actually new enough for the pinned wheels, whether you are installing both OpenCV packages as the requirements file asks, and whether you want the CPU or GPU ONNX runtime, because the two pins differ in version and the documentation tells you to ignore what pip check reports.
Frequently asked questions
What does yo-WASSUP/Good-Badminton need to run?
Python 3.8 or newer per the documentation, FFmpeg on the system PATH, and the badminton YOLO detection weights downloaded from the project's GitHub Releases. A GPU with 6GB or more of memory and 16GB or more of system memory is recommended, though a CPU can run the whole pipeline more slowly. Default dependencies are CPU builds of PyTorch and ONNX Runtime.
Does Good-Badminton detect the court automatically?
It attempts to, by matching white or yellow court lines against a standard badminton court model. You still supply a court template image, and if the automatic result is wrong you click four corners yourself and apply them, in the order top-left, top-right, bottom-right, bottom-left. The automatic preview still needs a keypress to accept.
How do I install the GPU version of yo-WASSUP/Good-Badminton?
Uninstall torch, torchvision, onnxruntime and onnxruntime-gpu, then install torch 2.5.1 and torchvision 0.20.1 from the cu121 wheel index plus onnxruntime-gpu 1.20.1. Verify that the ONNX Runtime providers list includes CUDAExecutionProvider, and note that pip check may then report that rtmlib requires onnxruntime, which the documentation says to ignore.
What files does Good-Badminton write for a match video?
Everything goes to outputs/ followed by the video filename: metadata.json, detections.jsonl with per-frame rally numbers, players, hands, court coordinates, speed and shuttlecock coordinates, an annotated MP4, the court_annotations.txt cache, and heatmap and scatter plot directories under position_visualizations.
What is Good-Badminton's relationship to Good-Tennis and Good-Pickleball?
They are described as the same family of computer vision sports video analysis projects, sharing player detection, ball tracking, court coordinate mapping, trajectory statistics and visual output, and differing in the court model, the detection target and the sport rules. All three are under the same owner.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/yo-wassup-good-badminton)