From 26b0bc8388583c0b424d4b721cdc52ad066531dd Mon Sep 17 00:00:00 2001 From: lingh Date: Tue, 30 Jun 2026 23:29:14 +0800 Subject: [PATCH] Filter speckle noise from the segmentation dropout-fill The rescue floored alpha with BiRefNet's soft mask verbatim, which sprinkled ~800 isolated <10px specks (burrs) across the matte from the mask's scattered low-confidence noise. Drop rescued connected components below a min area, keeping only the connected wisp structures. On TestImage2 the rescued components fall from 900 (818 isolated specks) to 91 and the added pixels from 5124 to 1886 -- the genuine wisp strands stay, the burrs go. smoke still passes. Co-Authored-By: Claude Opus 4.8 --- bgfilter/alpha_post.py | 6 ++++++ bgfilter/settings.py | 1 + configs/default.yaml | 1 + 3 files changed, 8 insertions(+) diff --git a/bgfilter/alpha_post.py b/bgfilter/alpha_post.py index 72911fa..07704bb 100644 --- a/bgfilter/alpha_post.py +++ b/bgfilter/alpha_post.py @@ -104,5 +104,11 @@ def fill_seg_dropouts( out = alpha.astype(np.float32).copy() rescued = settings.seg_fill_strength * np.clip(seg_mask, 0.0, 1.0) dropout = (out < settings.seg_fill_alpha_max) & (seg_mask >= settings.seg_fill_seg_min) + # The segmentation mask carries scattered low-confidence noise; rescuing it + # verbatim sprinkles isolated specks (burrs) over the matte. Keep only + # connected structures (genuine wisps), drop the isolated specks. + if settings.seg_fill_min_area_ratio > 0: + min_area = max(4, int(round(alpha.size * settings.seg_fill_min_area_ratio))) + dropout = _remove_small_components(dropout, min_area) out[dropout] = np.maximum(out[dropout], rescued[dropout]) return np.clip(out, 0.0, 1.0) diff --git a/bgfilter/settings.py b/bgfilter/settings.py index a5f4a7e..100d4ff 100644 --- a/bgfilter/settings.py +++ b/bgfilter/settings.py @@ -48,6 +48,7 @@ class AlphaPostSettings: seg_fill_alpha_max: float = 0.10 seg_fill_seg_min: float = 0.10 seg_fill_strength: float = 0.70 + seg_fill_min_area_ratio: float = 0.00002 # drop rescued specks below this area @dataclass(frozen=True) diff --git a/configs/default.yaml b/configs/default.yaml index 458a757..3f9a95d 100644 --- a/configs/default.yaml +++ b/configs/default.yaml @@ -27,6 +27,7 @@ alpha_post: seg_fill_alpha_max: 0.10 seg_fill_seg_min: 0.10 seg_fill_strength: 0.70 + seg_fill_min_area_ratio: 0.00002 foreground: enabled: true