Add directional trimap mode (default); keep seg/hard-bg via trimap.mode

Replace the two experimental bools (directional, bg_hued_to_bg) with a single
TrimapSettings.mode selector for the segmentation pipeline:
  - "directional" (new default): chroma magnitude + seg + a Lab hue-direction
    split. In the chroma-unknown zone a confidently-segmented pixel stays
    foreground unless it is displaced toward the background hue, so a neutral
    background-coloured garment (e.g. a white shirt) is kept while a background-
    hued residual (blue between hair strands) is left unknown for ViTMatte /
    chroma-suppress to clear.
  - "seg": original fuse_trimap, unchanged.
  - "directional-hard-bg": aggressive variant that hard-removes background-hued
    pixels (can eat cool/shadowed white cloth).

Selectable via configs/default.yaml (trimap.mode) or CLI --trimap-mode; unknown
modes raise. Default CLI output verified byte-identical to the reviewed UNK
result on the pastel sample.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 19:27:09 +08:00
parent 22ef1d6336
commit 5f48f7a2cd
6 changed files with 122 additions and 2 deletions
+21 -2
View File
@@ -13,7 +13,12 @@ from .foreground import estimate_foreground_rgb
from .io import load_rgb, save_gray, save_rgb, save_rgba, write_text
from .qa import BACKGROUND_COLORS, composite, make_qa_grid, save_previews
from .settings import PipelineSettings
from .trimap import fuse_trimap, generate_trimap, trimap_to_alpha_seed
from .trimap import (
fuse_trimap,
fuse_trimap_directional,
generate_trimap,
trimap_to_alpha_seed,
)
from .vitmatte_infer import ViTMatteRunner
@@ -80,7 +85,21 @@ def _run_image(
)
if settings.segmentation.enabled:
seg_mask = pipeline._segment(rgb)
trimap, trimap_stats = fuse_trimap(seg_mask, bg_confidence, settings.trimap)
mode = settings.trimap.mode
if mode == "seg":
trimap, trimap_stats = fuse_trimap(seg_mask, bg_confidence, settings.trimap)
elif mode in ("directional", "directional-hard-bg"):
from .chroma import convert_color_spaces
lab = convert_color_spaces(rgb)[2]
trimap, trimap_stats = fuse_trimap_directional(
seg_mask, bg_confidence, lab, model.lab_center, settings.trimap
)
else:
raise RuntimeError(
f"Unknown trimap.mode '{mode}'. "
"Use 'directional', 'seg', or 'directional-hard-bg'."
)
else:
seg_mask = None
trimap, trimap_stats = generate_trimap(bg_confidence, settings.trimap)