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