Add recolor pass to clean residual contamination colour
Add bgfilter/recolor.py: after despill, propagate clean neighbour chroma into pixels whose colour is still off (residual green, or the magenta a green unmix overshoots into), keeping luminance partway so hair texture survives. It installs a real observed colour rather than subtracting, so it cannot overshoot. Despill already neutralises the matte edge (off ~ 0 there), so recolor only touches the contaminated interior and the wisps the dropout-fill rescued. Runs as a final colour pass on the despilled foreground; pymatting + despill keep their stronger edge handling. On the samples the magenta fringe drops sharply (TestImage vis-magenta 0.065->0.014, TestImage2 0.085->0.031) with edge green unchanged (vis-green ~0.02). Debug output color_mask.png replaces the despill / foreground-background / foreground-correction maps; smoke updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+5
-1
@@ -11,6 +11,7 @@ from .settings import (
|
||||
ForegroundSettings,
|
||||
ModelSettings,
|
||||
PipelineSettings,
|
||||
RecolorSettings,
|
||||
SegmentationSettings,
|
||||
TrimapSettings,
|
||||
)
|
||||
@@ -43,7 +44,7 @@ def _update_dataclass(instance: T, values: dict[str, Any] | None) -> T:
|
||||
|
||||
|
||||
def settings_from_dict(data: dict[str, Any]) -> PipelineSettings:
|
||||
allowed_sections = {"chroma", "trimap", "alpha_post", "foreground", "despill", "model", "segmentation"}
|
||||
allowed_sections = {"chroma", "trimap", "alpha_post", "foreground", "despill", "recolor", "model", "segmentation"}
|
||||
unknown_sections = sorted(set(data) - allowed_sections)
|
||||
if unknown_sections:
|
||||
raise ValueError(f"Unknown config section(s): {', '.join(unknown_sections)}")
|
||||
@@ -54,6 +55,7 @@ def settings_from_dict(data: dict[str, Any]) -> PipelineSettings:
|
||||
alpha_post=_update_dataclass(AlphaPostSettings(), data.get("alpha_post")),
|
||||
foreground=_update_dataclass(ForegroundSettings(), data.get("foreground")),
|
||||
despill=_update_dataclass(DespillSettings(), data.get("despill")),
|
||||
recolor=_update_dataclass(RecolorSettings(), data.get("recolor")),
|
||||
model=_update_dataclass(ModelSettings(), data.get("model")),
|
||||
segmentation=_update_dataclass(SegmentationSettings(), data.get("segmentation")),
|
||||
)
|
||||
@@ -71,6 +73,7 @@ def override_settings(settings: PipelineSettings, **overrides: Any) -> PipelineS
|
||||
alpha_post = settings.alpha_post
|
||||
foreground = settings.foreground
|
||||
despill = settings.despill
|
||||
recolor = settings.recolor
|
||||
model = settings.model
|
||||
segmentation = settings.segmentation
|
||||
|
||||
@@ -102,6 +105,7 @@ def override_settings(settings: PipelineSettings, **overrides: Any) -> PipelineS
|
||||
alpha_post=alpha_post,
|
||||
foreground=foreground,
|
||||
despill=_update_dataclass(despill, despill_updates),
|
||||
recolor=recolor,
|
||||
model=_update_dataclass(model, model_updates),
|
||||
segmentation=_update_dataclass(segmentation, seg_updates),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user