From 5db23597e94585f2ef3241e29990b7c643ae21c9 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 20:45:41 +0000 Subject: [PATCH] fix: More robust handling of feathered_mask normalization This commit provides a more robust fix for the RuntimeWarning (invalid value encountered in divide/cast) that could occur in the `apply_mouth_area` function within `modules/processors/frame/face_swapper.py`. The previous check for `feathered_mask.max() == 0` was not sufficient for all floating point edge cases. The updated logic now: - Checks if `feathered_mask.max()` is less than a small epsilon (1e-6). - If true, it logs a warning and explicitly sets `feathered_mask` to an all-zero `uint8` array of the correct shape. - Otherwise, it proceeds with the normalization and casting to `uint8`. This ensures that division by zero or by extremely small numbers is prevented, and the `feathered_mask` is always in a valid state for subsequent blending operations. --- modules/processors/frame/face_swapper.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/processors/frame/face_swapper.py b/modules/processors/frame/face_swapper.py index 03db2a2..6b2b823 100644 --- a/modules/processors/frame/face_swapper.py +++ b/modules/processors/frame/face_swapper.py @@ -553,11 +553,13 @@ def apply_mouth_area( feathered_mask = cv2.GaussianBlur( polygon_mask.astype(float), (0, 0), feather_amount ) - if feathered_mask.max() == 0: - logging.warning("Mouth mask's feathered_mask is all zeros. Skipping normalization to prevent division by zero.") - # feathered_mask remains all zeros, which is safe for subsequent blending + + mask_max_value = feathered_mask.max() + if mask_max_value < 1e-6: # Check if max is effectively zero + logging.warning("Mouth mask's feathered_mask is all zeros or near-zeros after blur. Resulting mask will be black.") + feathered_mask = np.zeros_like(polygon_mask, dtype=np.uint8) else: - feathered_mask = (feathered_mask / feathered_mask.max() * 255).astype(np.uint8) + feathered_mask = (feathered_mask / mask_max_value * 255).astype(np.uint8) face_mask_roi = face_mask[min_y:max_y, min_x:max_x] combined_mask = feathered_mask * (face_mask_roi / 255.0)