Spaces:
Sleeping
Sleeping
Inpainting Lines
Browse files
app.py
CHANGED
|
@@ -135,7 +135,7 @@ def _process_saree_core(base_image: Image.Image, pattern_image: Image.Image):
|
|
| 135 |
l_clahe = clahe.apply(l_channel)
|
| 136 |
shading_map = l_clahe / 255.0
|
| 137 |
|
| 138 |
-
|
| 139 |
# [PATCHED] TILE PATTERN (soft crossfade) + BLEND
|
| 140 |
# Replace the block from "# Tile pattern" through
|
| 141 |
# "pattern_folded = np.clip(pattern_folded, 0, 1)"
|
|
@@ -302,6 +302,45 @@ def _process_saree_core(base_image: Image.Image, pattern_image: Image.Image):
|
|
| 302 |
# END NEW: SEAM-FIX UPSTREAM
|
| 303 |
# ================================
|
| 304 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
# Premultiplied → Straight alpha
|
| 306 |
eps = 1e-6
|
| 307 |
# _alpha = np.clip(mask_blurred, eps, 1.0)
|
|
|
|
| 135 |
l_clahe = clahe.apply(l_channel)
|
| 136 |
shading_map = l_clahe / 255.0
|
| 137 |
|
| 138 |
+
# ==========================================================
|
| 139 |
# [PATCHED] TILE PATTERN (soft crossfade) + BLEND
|
| 140 |
# Replace the block from "# Tile pattern" through
|
| 141 |
# "pattern_folded = np.clip(pattern_folded, 0, 1)"
|
|
|
|
| 302 |
# END NEW: SEAM-FIX UPSTREAM
|
| 303 |
# ================================
|
| 304 |
|
| 305 |
+
# ================================
|
| 306 |
+
# POST-PROCESS: SEAM / BLACK-LINE FILL
|
| 307 |
+
# (place this right before: "Premultiplied → Straight alpha")
|
| 308 |
+
# ================================
|
| 309 |
+
|
| 310 |
+
# Build a temporary straight-RGB for detection (do NOT export this)
|
| 311 |
+
_alpha_tmp = np.clip(mask_expanded, eps, 1.0) # [H,W]
|
| 312 |
+
_alpha_tmp3 = _alpha_tmp[..., None] # [H,W,1]
|
| 313 |
+
straight_tmp = np.clip(pattern_final / _alpha_tmp3, 0.0, 1.0) # [H,W,3], float
|
| 314 |
+
|
| 315 |
+
# Convert to 8-bit for OpenCV ops
|
| 316 |
+
straight_u8 = (straight_tmp * 255).astype(np.uint8)
|
| 317 |
+
gray8 = cv2.cvtColor(straight_u8, cv2.COLOR_RGB2GRAY)
|
| 318 |
+
|
| 319 |
+
# Local median to find narrow dark troughs (seams)
|
| 320 |
+
med8 = cv2.medianBlur(gray8, 5)
|
| 321 |
+
|
| 322 |
+
# Heuristics: dark + locally darker than neighbors + inside garment
|
| 323 |
+
dark_thr = int(0.22 * 255) # tune: 0.18..0.28
|
| 324 |
+
delta_thr = int(0.08 * 255) # tune: 0.06..0.10
|
| 325 |
+
dark = gray8 < dark_thr
|
| 326 |
+
contrast = (med8.astype(np.int16) - gray8.astype(np.int16)) > delta_thr
|
| 327 |
+
inside = (mask_expanded > 0.06) # avoid true background
|
| 328 |
+
|
| 329 |
+
seam_mask = (dark & contrast & inside).astype(np.uint8) * 255
|
| 330 |
+
|
| 331 |
+
# Keep seams thin (remove blobs); nudge toward single‑pixel cores
|
| 332 |
+
k3 = np.ones((3, 3), np.uint8)
|
| 333 |
+
seam_mask = cv2.morphologyEx(seam_mask, cv2.MORPH_OPEN, k3, iterations=1)
|
| 334 |
+
seam_mask = cv2.erode(seam_mask, np.ones((2, 2), np.uint8), iterations=1)
|
| 335 |
+
|
| 336 |
+
# Inpaint on straight space (Telea = good for thin scratches)
|
| 337 |
+
inpaint_radius = 3 # try 2..4
|
| 338 |
+
inpainted_u8 = cv2.inpaint(straight_u8, seam_mask, inpaint_radius, cv2.INPAINT_TELEA)
|
| 339 |
+
inpainted = inpainted_u8.astype(np.float32) / 255.0
|
| 340 |
+
|
| 341 |
+
# Re-premultiply and replace
|
| 342 |
+
|
| 343 |
+
|
| 344 |
# Premultiplied → Straight alpha
|
| 345 |
eps = 1e-6
|
| 346 |
# _alpha = np.clip(mask_blurred, eps, 1.0)
|