nishanth-saka commited on
Commit
7b872ac
·
verified ·
1 Parent(s): 9e68f2f

Local Median Color Boundary

Browse files
Files changed (1) hide show
  1. app.py +46 -9
app.py CHANGED
@@ -56,16 +56,53 @@ def _process_saree_core(base_image: Image.Image, pattern_image: Image.Image):
56
  # img_pil = base_image.convert("RGB") # <-- COMMENTED: this injects black behind transparency
57
  # img_np = np.array(img_pil)
58
 
59
- # --- NEW: alpha-aware RGB (composite RGBA over white to avoid black fringe) ---
 
 
 
 
 
 
 
 
 
 
 
60
  base_rgba = base_image.convert("RGBA")
61
- _arr = np.array(base_rgba).astype(np.float32)
62
- _rgb = _arr[..., :3]
63
- _a = (_arr[..., 3:4] / 255.0)
64
- _rgb_over_white = _rgb * _a + (1.0 - _a) * 255.0
65
- _rgb_over_white = _rgb_over_white.astype(np.uint8)
66
-
67
- img_pil = Image.fromarray(_rgb_over_white, mode="RGB")
68
- img_np = _rgb_over_white
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  # --- end NEW ---
70
 
71
  # Prepare tensor
 
56
  # img_pil = base_image.convert("RGB") # <-- COMMENTED: this injects black behind transparency
57
  # img_np = np.array(img_pil)
58
 
59
+ # --- ORIGINAL (white matte) kept for reference ---
60
+ # base_rgba = base_image.convert("RGBA")
61
+ # _arr = np.array(base_rgba).astype(np.float32)
62
+ # _rgb = _arr[..., :3]
63
+ # _a = (_arr[..., 3:4] / 255.0)
64
+ # _rgb_over_white = _rgb * _a + (1.0 - _a) * 255.0
65
+ # _rgb_over_white = _rgb_over_white.astype(np.uint8)
66
+ # img_pil = Image.fromarray(_rgb_over_white, mode="RGB")
67
+ # img_np = _rgb_over_white
68
+ # --- end ORIGINAL ---
69
+
70
+ # --- NEW: alpha-aware RGB using median color along interior boundary as matte ---
71
  base_rgba = base_image.convert("RGBA")
72
+ _arr = np.array(base_rgba).astype(np.float32) # (H,W,4), RGB in 0..255, A in 0..255
73
+ _rgb = _arr[..., :3] # (H,W,3)
74
+ _alpha8 = _arr[..., 3].astype(np.uint8) # (H,W) uint8 alpha
75
+ _a = (_alpha8.astype(np.float32) / 255.0)[..., None] # (H,W,1) float alpha
76
+
77
+ # Build a foreground mask from alpha (slightly strict to avoid wispy edges)
78
+ _fg_mask = (_alpha8 > 128).astype(np.uint8) * 255 # (H,W) 0/255
79
+
80
+ # Morphological interior boundary: foreground minus a 1-iteration erosion
81
+ _k = np.ones((3, 3), np.uint8)
82
+ _eroded = cv2.erode(_fg_mask, _k, iterations=1)
83
+ _boundary = cv2.bitwise_and(_fg_mask, cv2.bitwise_not(_eroded)) # thin interior ring
84
+
85
+ # If boundary is too thin/few pixels, widen the ring via morphological gradient
86
+ if int((_boundary > 0).sum()) < 100:
87
+ _dil = cv2.dilate(_fg_mask, _k, iterations=2)
88
+ _ero = cv2.erode(_fg_mask, _k, iterations=2)
89
+ _boundary = cv2.subtract(_dil, _ero)
90
+
91
+ _idx = (_boundary > 0)
92
+ if not np.any(_idx):
93
+ # Fallback: use entire foreground if boundary not found
94
+ _idx = (_fg_mask > 0)
95
+
96
+ # Compute median color over the selected boundary pixels (in 0..255 space)
97
+ _median_color = np.median(_rgb[_idx], axis=0) if np.any(_idx) else np.array([255.0, 255.0, 255.0], dtype=np.float32)
98
+ _median_color = _median_color.reshape(1, 1, 3) # (1,1,3)
99
+
100
+ # Composite RGB over median matte (avoid introducing black/white bias)
101
+ _rgb_over_matte = _rgb * _a + (1.0 - _a) * _median_color
102
+ _rgb_over_matte = np.clip(_rgb_over_matte, 0.0, 255.0).astype(np.uint8)
103
+
104
+ img_pil = Image.fromarray(_rgb_over_matte, mode="RGB")
105
+ img_np = _rgb_over_matte
106
  # --- end NEW ---
107
 
108
  # Prepare tensor