Spaces:
Paused
Paused
_process_saree_core_preserve_alpha UPDATED
Browse files
app.py
CHANGED
|
@@ -71,7 +71,7 @@ def _process_saree_core_preserve_alpha(base_image: Image.Image, pattern_image: I
|
|
| 71 |
model.eval()
|
| 72 |
|
| 73 |
with torch.no_grad():
|
| 74 |
-
target_size = base_rgb.size[::-1]
|
| 75 |
depth_map = model(img_tensor.to(device), target_size=target_size)
|
| 76 |
depth_map = depth_map.squeeze().cpu().numpy()
|
| 77 |
|
|
@@ -124,15 +124,55 @@ def _process_saree_core_preserve_alpha(base_image: Image.Image, pattern_image: I
|
|
| 124 |
mask_blurred = cv2.GaussianBlur(mask_eroded, (15, 15), sigmaX=3, sigmaY=3)
|
| 125 |
mask_final = mask_blurred.astype(np.float32) / 255.0
|
| 126 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
# ----------------------------------------
|
| 128 |
# 6. Apply mask to final pattern
|
| 129 |
# ----------------------------------------
|
| 130 |
-
mask_stack = np.stack([
|
| 131 |
pattern_final = pattern_folded * mask_stack
|
| 132 |
pattern_rgb = (pattern_final * 255).astype(np.uint8)
|
| 133 |
-
alpha_channel = (mask_final * 255).astype(np.uint8)
|
| 134 |
-
pattern_rgba = np.dstack((pattern_rgb, alpha_channel))
|
| 135 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
return Image.fromarray(pattern_rgba, mode="RGBA")
|
| 137 |
|
| 138 |
|
|
|
|
| 71 |
model.eval()
|
| 72 |
|
| 73 |
with torch.no_grad():
|
| 74 |
+
target_size = base_rgb.size[::-1]
|
| 75 |
depth_map = model(img_tensor.to(device), target_size=target_size)
|
| 76 |
depth_map = depth_map.squeeze().cpu().numpy()
|
| 77 |
|
|
|
|
| 124 |
mask_blurred = cv2.GaussianBlur(mask_eroded, (15, 15), sigmaX=3, sigmaY=3)
|
| 125 |
mask_final = mask_blurred.astype(np.float32) / 255.0
|
| 126 |
|
| 127 |
+
# ----------------------------------------
|
| 128 |
+
# 5.5 MAGIC-WAND STYLE CLEANUP for black background (connected to borders)
|
| 129 |
+
# (Simulates Mac Preview's wand: threshold + keep only border-connected dark regions)
|
| 130 |
+
# ----------------------------------------
|
| 131 |
+
# Tune these two params if needed:
|
| 132 |
+
black_thresh = 30 # 0..255 – raise if some dark bg remains; lower if it eats shadows
|
| 133 |
+
feather_px = 9 # odd kernel radius for blur/feathering
|
| 134 |
+
|
| 135 |
+
# Build a candidate black mask from the CURRENT composite (what will be visible)
|
| 136 |
+
preview_rgb_u8 = (pattern_folded * 255).astype(np.uint8)
|
| 137 |
+
gray = cv2.cvtColor(preview_rgb_u8, cv2.COLOR_RGB2GRAY)
|
| 138 |
+
|
| 139 |
+
# Binary mask of "near-black"
|
| 140 |
+
black_mask = cv2.threshold(gray, black_thresh, 255, cv2.THRESH_BINARY_INV)[1]
|
| 141 |
+
|
| 142 |
+
# Keep ONLY components touching image borders (likely the true background)
|
| 143 |
+
num_labels, labels = cv2.connectedComponents(black_mask)
|
| 144 |
+
h, w = gray.shape
|
| 145 |
+
border_labels = set(np.unique(np.concatenate([labels[0, :], labels[-1, :], labels[:, 0], labels[:, -1]])))
|
| 146 |
+
bg_touching = np.zeros_like(black_mask)
|
| 147 |
+
for lbl in border_labels:
|
| 148 |
+
if lbl == 0:
|
| 149 |
+
continue
|
| 150 |
+
bg_touching[labels == lbl] = 255
|
| 151 |
+
|
| 152 |
+
# Feather the background mask
|
| 153 |
+
if feather_px % 2 == 0:
|
| 154 |
+
feather_px += 1 # must be odd for GaussianBlur
|
| 155 |
+
bg_touching = cv2.GaussianBlur(bg_touching, (feather_px, feather_px), 0)
|
| 156 |
+
|
| 157 |
+
bg_touching_f = bg_touching.astype(np.float32) / 255.0 # 0..1
|
| 158 |
+
|
| 159 |
+
# Combine with the (refined) original alpha: remove black background regardless of original alpha
|
| 160 |
+
# old_alpha = mask_final # (keeping for reference)
|
| 161 |
+
refined_alpha = np.clip(mask_final * (1.0 - bg_touching_f), 0.0, 1.0)
|
| 162 |
+
|
| 163 |
# ----------------------------------------
|
| 164 |
# 6. Apply mask to final pattern
|
| 165 |
# ----------------------------------------
|
| 166 |
+
mask_stack = np.stack([refined_alpha] * 3, axis=-1)
|
| 167 |
pattern_final = pattern_folded * mask_stack
|
| 168 |
pattern_rgb = (pattern_final * 255).astype(np.uint8)
|
|
|
|
|
|
|
| 169 |
|
| 170 |
+
# old line (kept, but not used now):
|
| 171 |
+
# alpha_channel = (mask_final * 255).astype(np.uint8)
|
| 172 |
+
# NEW alpha using magic-wand cleanup:
|
| 173 |
+
alpha_channel = (refined_alpha * 255).astype(np.uint8)
|
| 174 |
+
|
| 175 |
+
pattern_rgba = np.dstack((pattern_rgb, alpha_channel))
|
| 176 |
return Image.fromarray(pattern_rgba, mode="RGBA")
|
| 177 |
|
| 178 |
|