- Python 98.6%
- Shell 1.4%
| configs | ||
| docs | ||
| scripts | ||
| src/zamboni | ||
| test | ||
| .gitignore | ||
| CHANGELOG.txt | ||
| dataset.yaml | ||
| LICENSE-apache.txt | ||
| LICENSE-CC.txt | ||
| ORCHESTRATOR_PROMPT_FOR_IMPLEMENTATION.md | ||
| pyproject.toml | ||
| README.md | ||
| SOTA_OPTICAL_FLOW_COMPARISON.md | ||
| test_phase2_components.py | ||
| test_phase3_integration.py | ||
| ZAMBONI_CLEAN_COMPLETE_IMPLEMENTATION_PLAN.md | ||
| ZAMBONI_CLEAN_COMPLETE_IMPLEMENTATION_PLAN_PART2.md | ||
| zamboni_config.yaml.example | ||
Zamboni
Zamboni cleans hockey game videos by removing ads from the hockey rink boards.
Installation
Thusly, suit to taste:
git clone https://spacecruft.org/deepcrayon/zamboni
cd zamboni/
python -m venv venv
source venv/bin/activate
pip install -U setuptools pip wheel
pip install -e .
The ffmpeg binary needs to be installed as well, such as:
apt install ffmpeg
Overview
To create a model that removes ads from the view, do this:
- Record a video to an
.mp4file withzamboni-rec. - Optionally extract images from video with
zamboni-vid2img. - Create labels of video frames using
zamboni-label. - Train a new model using
zamboni-train. - Create mask video using
zamboni-mask. - Create final video using
zamboni-clean(to be written).
Help
Usage help:
zamboni-rec
$ zamboni-rec --help
usage: zamboni-rec [-h] [-a AUDIO_CODEC] [-A AUDIO_INPUT] [-c VIDEO_CODEC] [-D] [-C AUDIO_CHANNELS] [-d DIR] [-l] [-m] [-o] [-p PREFIX] [-r FRAMERATE] [-s SIZE] [-t TIME] [-T | -N] [-v] [-V]
Record screen and save to mp4
options:
-h, --help show this help message and exit
-a AUDIO_CODEC, --audio-codec AUDIO_CODEC
Audio codec to use (default: aac)
-A AUDIO_INPUT, --audio-input AUDIO_INPUT
Audio input source (default: pulse)
-c VIDEO_CODEC, --video-codec VIDEO_CODEC
Video codec to use (default: hevc_nvenc)
-D, --debug Debugging
-C AUDIO_CHANNELS, --audio-channels AUDIO_CHANNELS
Number of audio channels (default: 2)
-d DIR, --dir DIR Directory to save the output video file
-l, --loop Loop input until stream is terminated manually
-m, --mouse Record the mouse cursor (default false)
-o, --overwrite Overwrite existing files (default: true)
-p PREFIX, --prefix PREFIX
Prefix for the output video file name
-r FRAMERATE, --framerate FRAMERATE
Framerate for recording (default: 30)
-s SIZE, --size SIZE Video size (default: 1920x1080)
-t TIME, --time TIME Length of recording in HH:MM:SS format (default: 00:01:00)
-T, --timestamp Add timestamp to filename (default)
-N, --no-timestamp Do not add timestamp to filename
-v, --verbose Increase output verbosity
-V, --version Show version
zamboni-vid2img
$ zamboni-vid2img --help
usage: zamboni-vid2img [-h] [-D] [-f FILENAME] [-o OUTPUT] [-p PREFIX] [-s FPS] [-v] [-V]
Extract images from video
options:
-h, --help show this help message and exit
-D, --debug Debugging
-f FILENAME, --filename FILENAME
File name of video (default: hockey.mp4)
-o OUTPUT, --output OUTPUT
Output directory (default: datasets/train/images)
-p PREFIX, --prefix PREFIX
Filename prefix (default: hockey)
-s FPS, --fps FPS Frames per second to extract (default: 1)
-v, --verbose Increase output verbosity
-V, --version Show version
To process an entire directory of .mp4 files, run something like this:
for i in *.mp4 ; do echo $i ; mkdir -p `basename $i .mp4` ; zamboni-vid2img -f $i -o `basename $i .mp4` -p `basename $i .mp4` ; done
zamboni-label
$ zamboni-label --help
usage: zamboni-label [-h] [--reset-config] [--logger-level {debug,info,warning,fatal,error}] [--output OUTPUT] [--config CONFIG] [--nodata] [--autosave] [--nosortlabels] [--flags FLAGS] [--labelflags LABEL_FLAGS] [--labels LABELS]
[--validatelabel {exact}] [--keep-prev] [--epsilon EPSILON]
[filename]
positional arguments:
filename image or label filename; If a directory path is passed in, the folder will be loaded automatically
options:
-h, --help show this help message and exit
--reset-config reset qt config
--logger-level {debug,info,warning,fatal,error}
logger level
--output OUTPUT, -O OUTPUT, -o OUTPUT
output file or directory (if it ends with .json it is recognized as file, else as directory)
--config CONFIG config file or yaml-format string (default: /home/jebba/.ailabelerrc)
--nodata stop storing image data to JSON file
--autosave auto save
--nosortlabels stop sorting labels
--flags FLAGS comma separated list of flags OR file containing flags
--labelflags LABEL_FLAGS
yaml string of label specific flags OR file containing json string of label specific flags (ex. {person-\d+: [male, tall], dog-\d+: [black, brown, white], .*: [occluded]})
--labels LABELS comma separated list of labels OR file containing labels
--validatelabel {exact}
label validation types
--keep-prev keep annotation of previous frame
--epsilon EPSILON epsilon to find nearest vertex on canvas
Steps:
- Run
zamboni-label. - Open directory of images,
datasets/train/imagesordatasets/valid/images, withFile --> Open Dir. - Alternatively, use
File --> Open Videoto convert a video to images. When importing images, optionally using1to convert every frame, to30to select one image per second. - Click the "AI" button in the left hand column.
- At
AutoNo Modeldropdown, selectSegment Anything 2 Video (Large). The first time it runs, it will download the model. - Select
Point (q)and click on an ad. - Select
Point (e)and click outside the ad, to exclude an area if too large of an area was selected. - Repeat this select over and over on the image.
- Save image with
Ctrl+S. - Hit right-arrow or
dto move to next image. - Repeat selections on new image until all images are processed.
- Add a file
datasets/train/images/classes.txtanddatasets/valid/images/classes.txtwith the lineAdvertisement. - Click on
Export --> Export YOLO-Seg Annotations. - For
Select a specific classes file, usedatasets/train/images/classes.txt. - For
Export optionsuse pathdatasets/train/labels. Leave unchecked both optionsSave with images?andSkip empty labels?.
zamboni-train
Note, Ultralytics may save defaults and override options with values set in these files:
~/.config/Ultralytics/settings.json~/.config/Ultralytics/settings.yaml
You may need to remove these files or remove the entire
~/.config/Ultralytics directory.
$ zamboni-train --help
usage: zamboni-train [-h] [-b BATCH] [-D] [-d DATA] [-e EPOCHS] [-m MODEL] [-s IMGSZ] [-v] [-V]
Train a model
options:
-h, --help show this help message and exit
-b BATCH, --batch BATCH
Batch size (default: 8)
-D, --debug Debugging
-d DATA, --data DATA Data file (default: dataset.yaml)
-e EPOCHS, --epochs EPOCHS
Number of epochs (default: 100)
-m MODEL, --model MODEL
Model to use (default: yolo11x-seg.pt)
-s IMGSZ, --size IMGSZ
Image size (default: 1920)
-v, --verbose Increase output verbosity
-V, --version Show version
zamboni-download
$ zamboni-download --help
usage: zamboni-download [-h] [-D] [-u URL] [-v] [-V]
Download model
options:
-h, --help show this help message and exit
-D, --debug Debugging
-u URL, --url URL URL for model (default: https://spacecruft.org/deepcrayon/zamboni-model/media/branch/main/zamboni.pt)
-v, --verbose Increase output verbosity
-V, --version Show version
zamboni-mask
$ zamboni-mask -h
usage: zamboni-mask [-h] [-D] [-f FILENAME] [-H HEIGHT] [-m MODEL] [-o OUTPUT] [-v] [-V] [-w WIDTH]
Create mask for a video
options:
-h, --help show this help message and exit
-D, --debug Debugging
-f FILENAME, --filename FILENAME
Video file to process (default: hockey.mp4)
-H HEIGHT, --height HEIGHT
Video height size, must be factor of 4 (default: 1088)
-m MODEL, --model MODEL
Model to use (default: zamboni.pt)
-o OUTPUT, --output OUTPUT
Video output file name (default: hockey-mask.mp4)
-v, --verbose Increase output verbosity
-V, --version Show version
-w WIDTH, --width WIDTH
Video width size, must be factor of 4 (default: 1920)
scripts/rename-images.sh
Crufty script to rename images to unique names.
Dataset
The datasets/ directory with test/, train/, and valid/ subdirectories
should be in the parent directory of the zamboni directory (e.g. one
directory above zamboni/).
The training datasets directory should be laid out thusly:
datasets/train/images/classes.txt
datasets/train/images/00000.jpg
...
datasets/train/images/99999.jpg
datasets/train/images/00000.json
...
datasets/train/images/99999.json
datasets/train/labels/00000.txt
...
datasets/train/labels/99999.txt
The validation datasets directory is similar to above:
datasets/valid/images/classes.txt
datasets/valid/images/00000.jpg
...
datasets/valid/images/99999.jpg
datasets/valid/images/00000.json
...
datasets/valid/images/99999.json
datasets/valid/labels/00000.txt
...
datasets/valid/labels/99999.txt
Status
Alpha.
Under development.
Most parts minimally work.
Masking is used to remove ads with a single color.
Eventually inpainting will be used to remove ads as it will match colors better.
License
Apache 2.0 or Creative Commons CC by SA 4.0 International. You may use this code, files, and text under either license.
Unofficial project, not related to upstream projects.
Upstream sources under their respective copyrights.
Copyright © 2025 Jeff Moe.