The green in the finger gap survives keying because it is dark and desaturated (brightness ~0.58, hue-shifted), so chroma confidence reads ~0 and the trimap leaves it in the unknown band, where ViTMatte fills the pocket as foreground. It is also connected to the exterior screen (an open notch), so neither confidence suppression nor classic hole-filling removes it. Add carve_background_holes (doc section 10): a pixel that is clearly green-dominant in the input *and* mostly surrounded by genuine (non-green) foreground is set to alpha 0. The surround cue separates such an intrusion (finger gaps, inter-strand pockets) from the outer hair edge, which has background on one side and is preserved. Runs after alpha cleanup. On TestImage the finger-gap survivors (green & alpha>0.5) drop 170 -> 28 with no visible loss of hair wisps; inter-strand green pockets clear too. Knobs in AlphaPostSettings (hole_*, default on, surround_min 0.4). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
BgFilter
Offline green screen character matting for AI-generated character images.
The first implementation follows the workflow in
docs/green_screen_matting_workflow.md:
RGB input -> chroma confidence -> trimap -> ViTMatte -> alpha cleanup -> despill -> RGBA PNG -> QA previews
Environment
Use the conda environment lightML.
conda activate lightML
pip install -r requirements.txt
If the shell is not activated, call the environment Python directly:
D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli --help
Single Image
D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli `
--input Samples\TestImage.png `
--output Outputs\TestImage_rgba.png `
--debug-dir Outputs\TestImage_debug `
--config configs\default.yaml `
--device cuda
The CLI reads configs/default.yaml when --config is provided. Command-line
options override config values, so tuning can usually happen in YAML while
runtime choices such as --device cpu stay on the command line.
Use CPU for validation when CUDA is unavailable:
D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli `
--input Samples\TestImage.png `
--output Outputs\TestImage_rgba.png `
--debug-dir Outputs\TestImage_debug `
--config configs\default.yaml `
--device cpu
Batch
D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli `
--input-dir Samples `
--output-dir Outputs `
--debug-dir Outputs\debug `
--config configs\default.yaml `
--device cuda
Chroma-Only Debug Mode
This mode skips ViTMatte and uses chroma confidence as an alpha seed. It is useful for fast debugging of chroma confidence, trimap, despill, and QA outputs.
D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli `
--input-dir Samples `
--output-dir Outputs\chroma `
--debug-dir Outputs\chroma_debug `
--config configs\default.yaml `
--matting-method chroma `
--device cpu
Outputs
For each processed image, the CLI writes an RGBA PNG and optional debug files:
bg_confidence.png
trimap.png
alpha.png
foreground_rgb.png
foreground_background.png
foreground_correction.png
despill_mask.png
preview_black.png
preview_white.png
preview_gray.png
preview_red.png
preview_blue.png
qa_grid.png
metadata.json
Quality Check
The quality checker measures alpha validity and green spill on semi-transparent edge pixels.
D:\MiniConda\envs\lightML\python.exe -m bgfilter.quality_cli `
Outputs\TestImage_rgba.png `
--max-edge-green-excess-p95 0.30
Run the bundled sample smoke check:
D:\MiniConda\envs\lightML\python.exe scripts\smoke_samples.py `
--samples-dir Samples `
--output-dir Outputs\smoke_samples `
--config configs\default.yaml `
--device cpu `
--fallback-to-chroma-alpha `
--max-edge-green-excess-p95 0.30
Current Notes
Samples/andOutputs/are ignored by Git.ViTMattemodel weights are loaded from Hugging Face on first use.- Foreground color estimation uses pymatting's
estimate_foreground_mlto propagate clean foreground colour into semi-transparent edges before final de-spill, writing the estimated foreground, background, and a correction map. Setforeground.method: unmixto fall back to the legacy heuristic.