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:
@@ -168,6 +168,23 @@ def _normalize_cross_check(value: str | None) -> bool | None:
|
||||
raise HTTPException(status_code=400, detail="invalid cross_check")
|
||||
|
||||
|
||||
def _normalize_background_mode(value: str | None) -> str | None:
|
||||
"""None/empty -> service default (flat); else "flat" or "complex".
|
||||
|
||||
"flat" (default) is the colour-keyed pipeline; "complex" is non-flat/scene
|
||||
matting with no colour key (segmentation drives the trimap). We deliberately
|
||||
do not surface the internal "chroma" wording here.
|
||||
"""
|
||||
if value is None:
|
||||
return None
|
||||
v = value.strip().lower()
|
||||
if v == "":
|
||||
return None
|
||||
if v in ("flat", "complex"):
|
||||
return v
|
||||
raise HTTPException(status_code=400, detail="invalid background_mode")
|
||||
|
||||
|
||||
def _decode_image(data: bytes) -> np.ndarray:
|
||||
if not data:
|
||||
raise HTTPException(status_code=400, detail="empty image")
|
||||
@@ -202,6 +219,7 @@ async def remove_background(
|
||||
screen_color: str | None = Form(None),
|
||||
seg_model: str | None = Form(None),
|
||||
cross_check: str | None = Form(None),
|
||||
background_mode: str | None = Form(None),
|
||||
_auth: None = Depends(require_auth),
|
||||
):
|
||||
if _manager is None:
|
||||
@@ -210,6 +228,15 @@ async def remove_background(
|
||||
normalized_color = _normalize_screen_color(screen_color)
|
||||
normalized_seg = _normalize_seg_model(seg_model) or _manager.default_seg_model
|
||||
normalized_cc = _normalize_cross_check(cross_check)
|
||||
# None/"flat" -> flat (chroma on); "complex" -> non-flat (chroma off).
|
||||
normalized_bg = _normalize_background_mode(background_mode)
|
||||
chroma_enabled = normalized_bg != "complex"
|
||||
effective_bg = "complex" if not chroma_enabled else "flat"
|
||||
# Complex mode defaults the cross-check veto OFF (it costs the HR-matting
|
||||
# forward and only clears residue near strands); an explicit cross_check=on
|
||||
# still enables its hue-free gate.
|
||||
if not chroma_enabled and normalized_cc is None:
|
||||
normalized_cc = False
|
||||
# Honors the lane lock (a locked cpu-fast box reports/runs "off" even on cross_check=on).
|
||||
effective_cc = _manager.effective_cross_check(normalized_cc)
|
||||
|
||||
@@ -226,6 +253,7 @@ async def remove_background(
|
||||
screen_color=normalized_color,
|
||||
seg_model=normalized_seg,
|
||||
cross_check=normalized_cc,
|
||||
chroma=chroma_enabled,
|
||||
),
|
||||
)
|
||||
except RuntimeError as exc:
|
||||
@@ -248,5 +276,6 @@ async def remove_background(
|
||||
"X-BGFilter-Seg-Model": normalized_seg,
|
||||
"X-BGFilter-Screen-Color": normalized_color if normalized_color else "auto",
|
||||
"X-BGFilter-Cross-Check": "on" if effective_cc else "off",
|
||||
"X-BGFilter-Background-Mode": effective_bg,
|
||||
}
|
||||
return Response(content=png, media_type="image/png", headers=headers)
|
||||
|
||||
Reference in New Issue
Block a user