Add complex-background matting mode to the service via background_mode

Backports master's non-flat matting (chroma.enabled: false + the hue-free
cross-check gate) into server-edition, and exposes it over HTTP without
surfacing the internal "chroma" wording: /remove-background gains a
background_mode form field (flat, default | complex). complex maps to
chroma disabled -- no colour key, segmentation alone drives the trimap and
every colour-keyed stage (auto-detect, hue split, chroma suppression,
despill) is bypassed. The cross-check veto still works in complex mode via
its second-opinion-confidence gate (cross_check.second_lo/hi) but defaults
OFF there (it costs the HR-matting forward); an explicit cross_check=on
re-enables it.

No new model weights: complex mode reuses the already-provisioned BiRefNet
seg + ViTMatte (+ optional HR-matting cross-check). Flat mode is unchanged
(bit-identical), and server-edition's own extras (cross_check.lock,
foreground.use_gpu CuPy path) are preserved -- the port is surgical, not a
copy of master's files.

- settings: ChromaSettings.enabled, CrossCheckSettings.second_lo/hi
- config: override_settings chroma passthrough
- despill/foreground: model=None safe guards (foreground keeps GPU path)
- alpha_post: cross_check_alpha hue-free gate when proj is None
- pipeline: _process_rgb complex branch (seg-only trimap, skip colour stages)
- service/app: process(chroma=), background_mode field, complex-defaults-off
  cross-check, X-BGFilter-Background-Mode header
- cli: --chroma/--no-chroma
- configs/docs: gpu.yaml + default.yaml + README/README_ZH

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 14:04:58 +08:00
parent 28d3fe8842
commit c56e58affe
13 changed files with 166 additions and 33 deletions
+12 -3
View File
@@ -208,9 +208,10 @@ is expected to authenticate). `/healthz` is always open. See [DEPLOY.md](DEPLOY.
| Field | Required | Values | Meaning |
| --- | --- | --- | --- |
| `file` | yes | image file | Source image (field name fixed as `file`). |
| `screen_color` | no | `#RRGGBB`, or omit/empty/`auto` | Background-colour prior; omit to auto-detect from the border. |
| `background_mode` | no | `flat` (default) / `complex` | `flat` = solid-colour background (colour-keyed pipeline). `complex` = non-flat/scene background: no colour key, the segmenter alone drives the matte. `screen_color` is ignored in `complex`; expect flat backgrounds to stay stronger on hair detail. |
| `screen_color` | no | `#RRGGBB`, or omit/empty/`auto` | Background-colour prior; omit to auto-detect from the border. Ignored when `background_mode=complex`. |
| `seg_model` | no | `birefnet` (default) / `anime-seg` | Segmentation backend. |
| `cross_check` | no | `1`/`0` (also `true`/`false`/`yes`/`no`/`on`/`off`) | Per-request override of the cross-model veto; omit/empty = service default. |
| `cross_check` | no | `1`/`0` (also `true`/`false`/`yes`/`no`/`on`/`off`) | Per-request override of the cross-model veto; omit/empty = service default in `flat` mode, but **defaults off** in `complex` mode (set `on` to enable its hue-free gate). |
### Response headers (on `200`)
@@ -220,13 +221,14 @@ is expected to authenticate). `/healthz` is always open. See [DEPLOY.md](DEPLOY.
| `X-BGFilter-Seg-Model` | `birefnet` | Segmenter actually used. |
| `X-BGFilter-Screen-Color` | `#CFEFFF` / `auto` | Background colour used. |
| `X-BGFilter-Cross-Check` | `on` / `off` | Effective cross-check state. |
| `X-BGFilter-Background-Mode` | `flat` / `complex` | Background mode actually used. |
### Status codes
| Code | When |
| --- | --- |
| `200` | Success — body is the RGBA PNG. |
| `400` | Bad input: unreadable image, invalid `screen_color`/`seg_model`/`cross_check`, or auto-detect failed (pass `screen_color`). |
| `400` | Bad input: unreadable image, invalid `screen_color`/`seg_model`/`cross_check`/`background_mode`, or auto-detect failed (pass `screen_color`). |
| `401` | Auth enabled and the token is missing or wrong. |
| `413` | Image exceeds `BGFILTER_MAX_IMAGE_PIXELS` (~4 MP by default). |
| `500` | Inference failed. |
@@ -247,6 +249,13 @@ curl -sS \
-F "seg_model=anime-seg" \
-F "cross_check=off" \
http://127.0.0.1:18083/remove-background -o output.png
# non-flat / scene background (no colour key); cross-check defaults off here,
# add cross_check=on to enable the hue-free residue veto
curl -sS \
-F "file=@scene.jpg" \
-F "background_mode=complex" \
http://127.0.0.1:18083/remove-background -o output.png
```
Config comes from `BGFILTER_CONFIG` (defaults to `configs/default.yaml` when present);