Commit Graph

5 Commits

Author SHA1 Message Date
lhk229 adbbb9d620 Add cross-model veto of hair-gap background residue (default on)
Colour-drifted background trapped between hair strands defeats every
single-signal defence: the chroma key reads it as foreground (bgc ~0.07),
the segmenter backs it, ViTMatte rates it opaque, and post-hoc removal is
a proven dead end (it shreds the hair volume the same pixels belong to).
A second, trimap-free matting model (BiRefNet_HR-matting) is the only
tested model that separates this residue from the subject, so its opinion
is fused in as a veto: min-fusion that may only LOWER alpha, restricted to
the background-hued bright suspect zone (proj >= 3, L >= 45, feathered)
and gated by primary-alpha confidence (0.70 -> 0.95 ramp) so soft wisps
and dark hair are exempt by construction.

- settings/config/CLI: cross_check block, --cross-check/--no-cross-check
- alpha_post.cross_check_alpha after clean_alpha; second opinion reuses
  BiRefNetSegmenter; saved to debug as cross_check_alpha.png
- chroma.bg_hue_projection extracted and shared with the trimap
- docs: methodology.md (new), hair_gap_artifacts.md (investigation log)

Verified: cross-check ON reproduces the visually-reviewed B1gate
prototype byte-for-byte on TestImage3; --no-cross-check reproduces the
previous baseline byte-for-byte; pink-bg FixImage1 face untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 19:52:24 +08:00
lhk229 fe97d692a7 Remove dead colour-model/despill code; simplify despill; refresh stale docs
- chroma: drop BackgroundModel.hsv_center/hue_sigma (unused since the green gating
  went away), their estimation, _hue_distance, and the now-unused hsv channel from
  convert_color_spaces (one fewer cvtColor per image).
- despill: delete the dead green-channel-algebra path (the pipeline always passes a
  colour) and fold the remaining Lab-direction despill into a single despill() with
  no screen_color arg (127 -> 60 lines). Renamed despill_green -> despill.
- settings: remove the now-dead ChromaSettings.hue_sigma_min and
  DespillSettings.green_excess_margin (plus the matching config lines).
- docs/comments: generalise stale "green" wording to "background colour" (module
  docstring, alpha_post/trimap/foreground/settings) and rename the trimap variable
  green_bg -> screen_bg.

Kept: the unmix foreground fallback, --matting-method chroma, and green/blue as
illustrative examples. Verified: package compiles, both configs parse, and an
auto-detect end-to-end run is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 17:49:20 +08:00
lhk229 5f48f7a2cd 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>
2026-07-01 19:27:09 +08:00
lhk229 711669ea51 Fuse semantic segmentation mask into the trimap
Wire BiRefNet into the pipeline (lazy-loaded) and build the trimap from the
semantic subject mask refined by the green key, used when segmentation is
enabled. generate_trimap (chroma-only) stays as the no-segmentation fallback.

Authority split: the mask decides subject topology (keeps green-tinted hair as
foreground, drops see-through holes), the bright-green key sharpens the screen
boundary, ViTMatte refines a small protective band. Background follows the mask
directly so interior holes survive; the band is small so it does not swallow
finger gaps.

End-to-end on the samples: green hair preserved, finger-gap green 99%
transparent (BiRefNet marks it background; was 100% foreground before), leg
edges smooth -- topology/colour/edge problems local cues could not solve, with
no hard alpha surgery.

- SegmentationSettings wired into PipelineSettings/config; --device propagates.
- TrimapSettings: seg_core_threshold, seg_loose_threshold.
- New debug output seg_mask.png.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 21:32:38 +08:00
Codex 8fc53925e0 Implement green screen matting pipeline 2026-06-30 14:14:15 +08:00