Align defaults with server-edition: reuse-as-seg and despill both OFF

Adopt server-edition's settings.py and default.yaml verbatim (zero diff on
these files between branches now):

- reuse_as_seg: false. The reuse equivalence holds for solid figures but
  breaks on thin pale strokes over a low-contrast background: HR-matting
  (trained on P3M-10k portraits + AM-2k animals) reads them as
  semi-transparent wisps, and as the trimap topology source it destroys
  white calligraphy (TestImage4: stroke alpha 0.92 -> 0.51, 48% of stroke
  pixels below 0.5) that the DIS5K-trained segmenter keeps solid (seg 0.97
  vs 0.40). As the gated cross-check veto the same signal stays harmless
  (hue gate excludes neutral strokes; confidence gate exempts soft edges).
  Opt in with --cross-check-as-seg for character batches.

- despill.enabled: false (mirrors server ba5d667): no positional/semantic
  guard, desaturates and hue-shifts subjects sharing the background's hue.

README updated accordingly; the performance table notes its numbers were
measured with reuse on.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-11 12:37:02 +08:00
parent 18c6918e45
commit f22af16517
4 changed files with 41 additions and 25 deletions
+20 -14
View File
@@ -25,9 +25,12 @@ Two pipelines, selected by `segmentation.enabled` in the config:
`trust_remote_code`) or `anime-seg` (ONNX, tuned for anime characters). Switch at
runtime with `--seg-backend anime-seg` (it also selects the matching weights).
Both share pymatting foreground estimation and a colour de-spill. There is **no**
green-contamination rescue / recolour layer — with clean source images it is
unnecessary, so it was removed.
Both share pymatting foreground estimation and an optional colour de-spill
(**off by default**: de-spill has no positional/semantic guard, so a subject
sharing the background's hue — a blue suit on a blue backdrop — gets
desaturated and hue-shifted; enable with `--despill` when edge spill genuinely
matters). There is **no** green-contamination rescue / recolour layer — with
clean source images it is unnecessary, so it was removed.
Both also run a **cross-model veto** by default: a second, trimap-free matting
model (`ZhengPeng7/BiRefNet_HR-matting`) may only *lower* alpha, only on
@@ -38,15 +41,17 @@ download (~0.9 GB) and one inference pass per image; disable with
`--no-cross-check` (see the `cross_check` config section, and
`docs/hair_gap_artifacts.md` for the analysis behind it).
When the cross-check is on, that same HR-matting forward is **reused as the
segmentation mask by default**, skipping the primary seg model entirely (one
less model to load, ~20 s faster per image on CPU). Pilot-validated
(TestImage3 / FixImage1): trimap 99.8% identical, no structural change to
fingers, hair wisps or thin lines. Disable with `--no-cross-check-as-seg` to
run the dedicated seg model instead. The reuse is a same-family swap, so it
applies to the `birefnet` backend only: with `--seg-backend anime-seg` the
anime segmenter keeps its own forward and the cross-check veto still runs
independently on top.
When the cross-check is on, `--cross-check-as-seg` reuses that same HR-matting
forward as the segmentation mask, skipping the primary seg model entirely (one
less model to load, ~20 s faster per image on CPU). **Off by default** — use it
only when the subjects are characters or similar solid figures. HR-matting is
trained on portrait/animal matting (P3M-10k, AM-2k) and reads thin pale strokes
on a low-contrast background as semi-transparent wisps: white calligraphy on
the pastel backdrop (TestImage4) loses half its strokes under reuse, while the
dedicated DIS5K-trained segmenter keeps them solid. The reuse is a same-family
swap, so it applies to the `birefnet` backend only: with `--seg-backend
anime-seg` the anime segmenter keeps its own forward and the cross-check veto
still runs independently on top.
The segmentation trimap defaults to `directional` mode (chroma + seg + a hue-direction
split: it keeps a background-coloured garment such as a white shirt while dropping a
@@ -119,8 +124,9 @@ D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli `
## Performance (CPU reference numbers)
Measured on a Ryzen 9700X (Zen 5, native bf16), 32 GB RAM, default settings
(cross-check on, reused as seg; chunked global attention on):
Measured on a Ryzen 9700X (Zen 5, native bf16), 32 GB RAM, with cross-check on
and `--cross-check-as-seg` (reuse); chunked global attention on. Without reuse
(the default) add ~9 s fp32 / ~6 s bf16 for the dedicated seg forward:
| input | precision | warm / image | peak memory |
|---|---|---|---|