Spaces:
Sleeping
Sleeping
Upload 2 files
Browse files
app.py
CHANGED
|
@@ -16,50 +16,14 @@ torch.set_num_threads(4)
|
|
| 16 |
sam_vit_pipeline = None
|
| 17 |
|
| 18 |
|
| 19 |
-
# ββ Suavizado de bordes βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 20 |
-
def _smooth_mask(mask_raw, img_h: int, img_w: int) -> np.ndarray:
|
| 21 |
-
"""
|
| 22 |
-
Limpia una mΓ‘scara SAM para obtener bordes mΓ‘s rectos y sin rasgados:
|
| 23 |
-
1. Closing β rellena huecos y suaviza concavidades
|
| 24 |
-
2. Opening β elimina picos y ruido en los bordes
|
| 25 |
-
3. approxPolyDP β convierte el contorno en segmentos rectos
|
| 26 |
-
"""
|
| 27 |
-
mask_u8 = (np.array(mask_raw) > 0).astype(np.uint8) * 255
|
| 28 |
-
|
| 29 |
-
# Kernel adaptado al tamaΓ±o de la imagen
|
| 30 |
-
k = max(5, min(21, (img_h + img_w) // 200) | 1) # siempre impar
|
| 31 |
-
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (k, k))
|
| 32 |
-
|
| 33 |
-
mask_u8 = cv2.morphologyEx(mask_u8, cv2.MORPH_CLOSE, kernel, iterations=2)
|
| 34 |
-
mask_u8 = cv2.morphologyEx(mask_u8, cv2.MORPH_OPEN, kernel, iterations=1)
|
| 35 |
-
|
| 36 |
-
# Aproximar contorno para bordes rectos
|
| 37 |
-
contours, _ = cv2.findContours(mask_u8, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
| 38 |
-
if contours:
|
| 39 |
-
clean = np.zeros_like(mask_u8)
|
| 40 |
-
# Procesar cada contorno (puede haber varios fragmentos)
|
| 41 |
-
for cnt in contours:
|
| 42 |
-
if cv2.contourArea(cnt) < 200:
|
| 43 |
-
continue
|
| 44 |
-
peri = cv2.arcLength(cnt, True)
|
| 45 |
-
# eps 0.008: buen balance entre recto y fiel a la forma real
|
| 46 |
-
approx = cv2.approxPolyDP(cnt, 0.008 * peri, True)
|
| 47 |
-
cv2.fillPoly(clean, [approx], 255)
|
| 48 |
-
mask_u8 = clean
|
| 49 |
-
|
| 50 |
-
return mask_u8 > 0
|
| 51 |
-
|
| 52 |
-
|
| 53 |
# ββ Renderizado βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 54 |
def _render_masks(imagen_rgb: Image.Image, masks: list) -> Image.Image:
|
| 55 |
img_arr = np.array(imagen_rgb).copy()
|
| 56 |
-
h, w = img_arr.shape[:2]
|
| 57 |
overlay = img_arr.copy()
|
| 58 |
for i, mask in enumerate(masks):
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
overlay[smooth] = color
|
| 63 |
blended = cv2.addWeighted(img_arr, 0.5, overlay, 0.5, 0)
|
| 64 |
return Image.fromarray(blended)
|
| 65 |
|
|
@@ -131,7 +95,7 @@ def segment_for_backend(image_np: np.ndarray):
|
|
| 131 |
resultado = resultado[0]
|
| 132 |
|
| 133 |
all_masks_raw = resultado.get("masks", [])
|
| 134 |
-
masks_bool = [
|
| 135 |
|
| 136 |
# Label map: cada pΓxel contiene el Γndice de la mΓ‘scara (1-based)
|
| 137 |
label_map = np.zeros((h, w), dtype=np.uint8)
|
|
|
|
| 16 |
sam_vit_pipeline = None
|
| 17 |
|
| 18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
# ββ Renderizado βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 20 |
def _render_masks(imagen_rgb: Image.Image, masks: list) -> Image.Image:
|
| 21 |
img_arr = np.array(imagen_rgb).copy()
|
|
|
|
| 22 |
overlay = img_arr.copy()
|
| 23 |
for i, mask in enumerate(masks):
|
| 24 |
+
h = hashlib.md5(str(i).encode()).hexdigest()[:6]
|
| 25 |
+
color = (int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16))
|
| 26 |
+
overlay[np.array(mask) > 0] = color
|
|
|
|
| 27 |
blended = cv2.addWeighted(img_arr, 0.5, overlay, 0.5, 0)
|
| 28 |
return Image.fromarray(blended)
|
| 29 |
|
|
|
|
| 95 |
resultado = resultado[0]
|
| 96 |
|
| 97 |
all_masks_raw = resultado.get("masks", [])
|
| 98 |
+
masks_bool = [np.array(m).astype(bool) for m in all_masks_raw]
|
| 99 |
|
| 100 |
# Label map: cada pΓxel contiene el Γndice de la mΓ‘scara (1-based)
|
| 101 |
label_map = np.zeros((h, w), dtype=np.uint8)
|