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 <noreply@anthropic.com>
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user