fix(demo): harden mask hole-filling for border-touching cases

This commit is contained in:
2026-03-02 16:45:20 +08:00
parent cbb3284c13
commit f6859cfa79
2 changed files with 52 additions and 0 deletions
+24
View File
@@ -64,6 +64,29 @@ def _to_numpy_array(value: object) -> NDArray[np.generic]:
return cast(NDArray[np.generic], np.asarray(current))
def _fill_binary_holes(mask_u8: UInt8Array) -> UInt8Array:
mask_bin = np.where(mask_u8 > 0, np.uint8(255), np.uint8(0)).astype(np.uint8)
h, w = cast(tuple[int, int], mask_bin.shape)
if h <= 2 or w <= 2:
return mask_bin
seed_candidates = [(0, 0), (w - 1, 0), (0, h - 1), (w - 1, h - 1)]
seed: tuple[int, int] | None = None
for x, y in seed_candidates:
if int(mask_bin[y, x]) == 0:
seed = (x, y)
break
if seed is None:
return mask_bin
flood = mask_bin.copy()
flood_mask = np.zeros((h + 2, w + 2), dtype=np.uint8)
_ = cv2.floodFill(flood, flood_mask, seed, 255)
holes = cv2.bitwise_not(flood)
filled = cv2.bitwise_or(mask_bin, holes)
return cast(UInt8Array, filled)
def _bbox_from_mask(mask: UInt8[ndarray, "h w"]) -> BBoxXYXY | None:
"""Extract bounding box from binary mask in XYXY format.
@@ -248,6 +271,7 @@ def mask_to_silhouette(
or None if conversion fails.
"""
mask_u8 = np.where(mask > 0, np.uint8(255), np.uint8(0)).astype(np.uint8)
mask_u8 = _fill_binary_holes(mask_u8)
if int(np.count_nonzero(mask_u8)) < MIN_MASK_AREA:
return None