mmo9 commited on
Commit
c66dc60
·
verified ·
1 Parent(s): 9b65601

Smart feather: hard inner mask + 2px soft boundary only

Browse files
Files changed (1) hide show
  1. app.py +19 -7
app.py CHANGED
@@ -913,13 +913,25 @@ def _lama_inpaint_tile(img_rgb: np.ndarray, mask: np.ndarray, size: int = 512) -
913
  out_img_512 = np.clip(out[0].transpose(1, 2, 0) * 255.0, 0.0, 255.0).astype(np.uint8)
914
  out_img_orig = cv2.resize(out_img_512, (cw, ch), interpolation=cv2.INTER_CUBIC)
915
 
916
- # FIX: Hard mask replacement - no alpha blending to prevent text ghosts.
917
- # Only pixels where crop_mask==255 are replaced with LaMa output.
918
- # Pixels outside the mask keep the original artwork 100% untouched.
919
- hard_mask = (crop_mask > 127).astype(np.uint8)
920
- hard_mask_3ch = np.stack([hard_mask, hard_mask, hard_mask], axis=-1)
921
- result_crop = np.where(hard_mask_3ch, out_img_orig, crop_img)
922
- img_out[y0:y1, x0:x1] = result_crop
 
 
 
 
 
 
 
 
 
 
 
 
923
 
924
  return img_out
925
 
 
913
  out_img_512 = np.clip(out[0].transpose(1, 2, 0) * 255.0, 0.0, 255.0).astype(np.uint8)
914
  out_img_orig = cv2.resize(out_img_512, (cw, ch), interpolation=cv2.INTER_CUBIC)
915
 
916
+ # SMART FEATHER: hard mask for ALL inner text pixels (no ghost text),
917
+ # + thin 2px soft feather ONLY at the outer boundary (no sharp visible edges).
918
+ # Step 1: inner mask = pixels that were definitely text (hard replacement)
919
+ inner_mask = (crop_mask > 127).astype(np.uint8)
920
+ # Step 2: compute 2px outer boundary ring of the mask
921
+ boundary_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
922
+ dilated_boundary = cv2.dilate(inner_mask, boundary_kernel, iterations=1)
923
+ boundary_ring = (dilated_boundary - inner_mask).astype(np.float32) # only outer edge
924
+ # Step 3: soft feather weight for the boundary ring only (0→1 over 2px)
925
+ feather = cv2.GaussianBlur(boundary_ring, (5, 5), 1.0)
926
+ feather_3ch = np.stack([feather, feather, feather], axis=-1)
927
+ # Step 4: inner = hard LaMa, boundary = soft blend, outside = original
928
+ inner_3ch = np.stack([inner_mask.astype(np.float32)] * 3, axis=-1)
929
+ result_crop = (
930
+ inner_3ch * out_img_orig.astype(np.float32)
931
+ + feather_3ch * out_img_orig.astype(np.float32)
932
+ + (1.0 - inner_3ch - feather_3ch) * crop_img.astype(np.float32)
933
+ )
934
+ img_out[y0:y1, x0:x1] = np.clip(result_crop, 0, 255).astype(np.uint8)
935
 
936
  return img_out
937