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.
pull/1376/head
google-labs-jules[bot] 2025-06-23 20:45:41 +00:00
parent 84ae5810bf
commit 5db23597e9
1 changed files with 6 additions and 4 deletions

View File

@ -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)