Spaces:
Sleeping
Sleeping
Updated _process_saree_core
Browse files
app.py
CHANGED
|
@@ -184,38 +184,62 @@ def _process_saree_core(base_image: Image.Image, pattern_image: Image.Image):
|
|
| 184 |
# 3. Normalize
|
| 185 |
mask_blurred = mask_blurred.astype(np.float32) / 255.0
|
| 186 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
# Final RGBA
|
| 188 |
-
mask_stack = np.stack([mask_blurred] * 3, axis=-1)
|
| 189 |
-
|
| 190 |
# pattern_final = pattern_folded * mask_stack
|
| 191 |
-
#
|
| 192 |
-
|
| 193 |
-
#
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
#
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
#
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
|
|
|
|
|
|
|
|
|
| 205 |
|
| 206 |
# Premultiplied → Straight alpha
|
| 207 |
eps = 1e-6
|
| 208 |
-
_alpha = np.clip(mask_blurred, eps, 1.0)
|
|
|
|
|
|
|
|
|
|
| 209 |
_alpha3 = _alpha[..., None]
|
| 210 |
rgb_straight = np.clip(pattern_final / _alpha3, 0.0, 1.0)
|
| 211 |
|
| 212 |
pattern_rgb = (rgb_straight * 255).astype(np.uint8)
|
| 213 |
-
alpha_channel = (
|
| 214 |
pattern_rgba = np.dstack((pattern_rgb, alpha_channel))
|
| 215 |
|
| 216 |
return Image.fromarray(pattern_rgba, mode="RGBA")
|
| 217 |
|
| 218 |
|
|
|
|
| 219 |
# ===============================
|
| 220 |
# WRAPPER: ACCEPT BYTES OR BASE64
|
| 221 |
# ===============================
|
|
|
|
| 184 |
# 3. Normalize
|
| 185 |
mask_blurred = mask_blurred.astype(np.float32) / 255.0
|
| 186 |
|
| 187 |
+
# ================================
|
| 188 |
+
# NEW: SEAM-FIX UPSTREAM (3 steps)
|
| 189 |
+
# ================================
|
| 190 |
+
# (A) MASK EXPANSION / OVERLAP: expand slightly to ensure overlap across seams
|
| 191 |
+
overlap_iters = 2 # <-- tune: 1..3 (px-ish with 5x5 kernel)
|
| 192 |
+
# mask_expanded = cv2.dilate(mask_eroded, kernel, iterations=overlap_iters) # old idea
|
| 193 |
+
# --- Better: expand the FLOAT feathered mask to preserve soft edge continuity ---
|
| 194 |
+
_mask_float = (mask_blurred * 255).astype(np.uint8)
|
| 195 |
+
_mask_expanded_u8 = cv2.dilate(_mask_float, kernel, iterations=overlap_iters)
|
| 196 |
+
mask_expanded = _mask_expanded_u8.astype(np.float32) / 255.0 # [0..1]
|
| 197 |
+
|
| 198 |
+
# (B) FEATHER AGAIN after expansion (very light) for a smooth transition band
|
| 199 |
+
mask_expanded = cv2.GaussianBlur((mask_expanded * 255).astype(np.uint8), (7, 7), sigmaX=1.5, sigmaY=1.5)
|
| 200 |
+
mask_expanded = mask_expanded.astype(np.float32) / 255.0
|
| 201 |
+
|
| 202 |
+
# (C) BLEED-COLOR FILLING in premultiplied space for near-edge pixels
|
| 203 |
+
# - Create a thin edge band where alpha is small (e.g., up to 8%)
|
| 204 |
+
edge_upper = 0.08
|
| 205 |
# Final RGBA
|
| 206 |
+
# mask_stack = np.stack([mask_blurred] * 3, axis=-1)
|
|
|
|
| 207 |
# pattern_final = pattern_folded * mask_stack
|
| 208 |
+
# --- Replace above with expanded mask for overlap ---
|
| 209 |
+
mask_stack = np.stack([mask_expanded] * 3, axis=-1)
|
| 210 |
+
pattern_final = pattern_folded * mask_stack # premultiplied RGB (color * alpha) with overlap
|
| 211 |
+
|
| 212 |
+
# - Dilate premultiplied RGB slightly so edge pixels borrow nearby garment color
|
| 213 |
+
bleed_iters = 2 # <-- tune: 1..3
|
| 214 |
+
_kernel_bleed = np.ones((3, 3), np.uint8)
|
| 215 |
+
_premul_u8 = (pattern_final * 255).astype(np.uint8)
|
| 216 |
+
_premul_bleed = cv2.dilate(_premul_u8, _kernel_bleed, iterations=bleed_iters).astype(np.float32) / 255.0
|
| 217 |
+
|
| 218 |
+
# - Replace only in the very thin edge band (alpha between 0 and edge_upper)
|
| 219 |
+
edge_band = (mask_expanded > 0.0) & (mask_expanded <= edge_upper)
|
| 220 |
+
if np.any(edge_band):
|
| 221 |
+
pattern_final[edge_band] = _premul_bleed[edge_band]
|
| 222 |
+
# ================================
|
| 223 |
+
# END NEW: SEAM-FIX UPSTREAM
|
| 224 |
+
# ================================
|
| 225 |
|
| 226 |
# Premultiplied → Straight alpha
|
| 227 |
eps = 1e-6
|
| 228 |
+
# _alpha = np.clip(mask_blurred, eps, 1.0)
|
| 229 |
+
# --- Use the expanded mask for export, with a small alpha floor to hide hairlines ---
|
| 230 |
+
alpha_floor = 0.02 # 2% floor; increase to 0.03 if a faint line persists
|
| 231 |
+
_alpha = np.clip(mask_expanded, max(alpha_floor, eps), 1.0)
|
| 232 |
_alpha3 = _alpha[..., None]
|
| 233 |
rgb_straight = np.clip(pattern_final / _alpha3, 0.0, 1.0)
|
| 234 |
|
| 235 |
pattern_rgb = (rgb_straight * 255).astype(np.uint8)
|
| 236 |
+
alpha_channel = (_alpha * 255).astype(np.uint8)
|
| 237 |
pattern_rgba = np.dstack((pattern_rgb, alpha_channel))
|
| 238 |
|
| 239 |
return Image.fromarray(pattern_rgba, mode="RGBA")
|
| 240 |
|
| 241 |
|
| 242 |
+
|
| 243 |
# ===============================
|
| 244 |
# WRAPPER: ACCEPT BYTES OR BASE64
|
| 245 |
# ===============================
|