Gate chroma suppression by the matte's own confidence

suppress_alpha_by_chroma was the one stage where colour evidence could veto the
matting model outright, and every observed failure had the same shape: ViTMatte
was right (raw ~0.97 on a white shirt over pastel blue, on blush over pink) and
the bgc-keyed suppression crushed it, because bgc magnitude cannot tell a
background-coloured subject from background residue. The matte's raw alpha can:
it rates enclosed background pockets low (~0.28 median) and subject texture high.

Suppression is now scaled by (1 - smoothstep(raw_alpha, suppress_raw_lo,
suppress_raw_hi)) (defaults 0.85/0.98): colour evidence only vetoes the matte
where the matte itself is unsure. The gate applies only when alpha really comes
from ViTMatte; chroma-seeded alpha passes raw_alpha=None and keeps old behaviour.
Set suppress_raw_lo: 1.0 to disable (verified byte-identical to the old output).

Validated on both screen colours: pink #F4D8E8 face restored (skin alpha 0.841 ->
0.993, holes 17.2% -> 0.6%), pastel blue #CFEFFF unchanged-to-better (shirt +0.01,
wisps identical, gap clearing 99.8%). Also fixes the long-deferred chroma-only
pipeline defects (white shirt 0.900, light skin 0.989). CLI output verified
byte-identical to the reviewed prototype on both images.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-03 23:54:28 +08:00
parent cf0ceec496
commit 639fdf01b6
4 changed files with 31 additions and 3 deletions
+8 -3
View File
@@ -103,10 +103,15 @@ def _run_image(
else:
seg_mask = None
trimap, trimap_stats = generate_trimap(bg_confidence, settings.trimap)
alpha, alpha_source = pipeline._predict_alpha(rgb, trimap, bg_confidence)
raw_alpha, alpha_source = pipeline._predict_alpha(rgb, trimap, bg_confidence)
alpha = enforce_trimap(alpha, trimap)
alpha = suppress_alpha_by_chroma(alpha, bg_confidence, trimap, settings.alpha_post)
alpha = enforce_trimap(raw_alpha, trimap)
alpha = suppress_alpha_by_chroma(
alpha, bg_confidence, trimap, settings.alpha_post,
# The matte-confidence gate only makes sense for a real matting prediction;
# a chroma-seeded alpha is itself colour evidence, so no gate there.
raw_alpha=raw_alpha if alpha_source == "vitmatte" else None,
)
alpha = clean_alpha(alpha, trimap, settings.alpha_post)
foreground = estimate_foreground_rgb(
rgb, alpha, bg_confidence, model, settings.foreground