Spaces:
Paused
Paused
Updated Core Process
Browse files
app.py
CHANGED
|
@@ -53,8 +53,20 @@ def depth_to_normal(depth):
|
|
| 53 |
# CORE PROCESSING FUNCTION
|
| 54 |
# ===============================
|
| 55 |
def _process_saree_core(base_image: Image.Image, pattern_image: Image.Image):
|
| 56 |
-
img_pil = base_image.convert("RGB")
|
| 57 |
-
img_np = np.array(img_pil)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
|
| 59 |
# Prepare tensor
|
| 60 |
img_resized = img_pil.resize((384, 384))
|
|
@@ -129,7 +141,6 @@ def _process_saree_core(base_image: Image.Image, pattern_image: Image.Image):
|
|
| 129 |
mask_binary = (mask_alpha > k/100).astype(np.uint8) * 255 # slightly stricter threshold
|
| 130 |
mask_eroded = cv2.erode(mask_binary, kernel, iterations=3) # balanced erosion
|
| 131 |
|
| 132 |
-
|
| 133 |
# 2. Feather edges (blur)
|
| 134 |
mask_blurred = cv2.GaussianBlur(mask_eroded, (15, 15), sigmaX=3, sigmaY=3)
|
| 135 |
|
|
@@ -138,13 +149,36 @@ def _process_saree_core(base_image: Image.Image, pattern_image: Image.Image):
|
|
| 138 |
|
| 139 |
# Final RGBA
|
| 140 |
mask_stack = np.stack([mask_blurred] * 3, axis=-1)
|
| 141 |
-
|
| 142 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
alpha_channel = (mask_blurred * 255).astype(np.uint8)
|
| 144 |
pattern_rgba = np.dstack((pattern_rgb, alpha_channel))
|
| 145 |
|
| 146 |
return Image.fromarray(pattern_rgba, mode="RGBA")
|
| 147 |
|
|
|
|
| 148 |
# ===============================
|
| 149 |
# WRAPPER: ACCEPT BYTES OR BASE64
|
| 150 |
# ===============================
|
|
|
|
| 53 |
# CORE PROCESSING FUNCTION
|
| 54 |
# ===============================
|
| 55 |
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
|
| 72 |
img_resized = img_pil.resize((384, 384))
|
|
|
|
| 141 |
mask_binary = (mask_alpha > k/100).astype(np.uint8) * 255 # slightly stricter threshold
|
| 142 |
mask_eroded = cv2.erode(mask_binary, kernel, iterations=3) # balanced erosion
|
| 143 |
|
|
|
|
| 144 |
# 2. Feather edges (blur)
|
| 145 |
mask_blurred = cv2.GaussianBlur(mask_eroded, (15, 15), sigmaX=3, sigmaY=3)
|
| 146 |
|
|
|
|
| 149 |
|
| 150 |
# Final RGBA
|
| 151 |
mask_stack = np.stack([mask_blurred] * 3, axis=-1)
|
| 152 |
+
|
| 153 |
+
# pattern_final = pattern_folded * mask_stack
|
| 154 |
+
# pattern_rgb = (pattern_final * 255).astype(np.uint8)
|
| 155 |
+
# alpha_channel = (mask_blurred * 255).astype(np.uint8)
|
| 156 |
+
# pattern_rgba = np.dstack((pattern_rgb, alpha_channel))
|
| 157 |
+
# return Image.fromarray(pattern_rgba, mode="RGBA")
|
| 158 |
+
|
| 159 |
+
# --- NEW: keep premultiplied math for filtering, then un-premultiply before saving ---
|
| 160 |
+
pattern_final = pattern_folded * mask_stack # premultiplied RGB (color * alpha)
|
| 161 |
+
|
| 162 |
+
# Optional tiny bleed to reduce edge fringing further (safe defaults). Comment out if not needed.
|
| 163 |
+
# _kernel_bleed = np.ones((3,3), np.uint8)
|
| 164 |
+
# _premul_u8 = (pattern_final * 255).astype(np.uint8)
|
| 165 |
+
# _premul_bleed = cv2.dilate(_premul_u8, _kernel_bleed, iterations=1).astype(np.float32) / 255.0
|
| 166 |
+
# _edge = (mask_blurred > 0) & (mask_blurred <= 0.02)
|
| 167 |
+
# pattern_final[_edge] = _premul_bleed[_edge]
|
| 168 |
+
|
| 169 |
+
# Premultiplied → Straight alpha
|
| 170 |
+
eps = 1e-6
|
| 171 |
+
_alpha = np.clip(mask_blurred, eps, 1.0)
|
| 172 |
+
_alpha3 = _alpha[..., None]
|
| 173 |
+
rgb_straight = np.clip(pattern_final / _alpha3, 0.0, 1.0)
|
| 174 |
+
|
| 175 |
+
pattern_rgb = (rgb_straight * 255).astype(np.uint8)
|
| 176 |
alpha_channel = (mask_blurred * 255).astype(np.uint8)
|
| 177 |
pattern_rgba = np.dstack((pattern_rgb, alpha_channel))
|
| 178 |
|
| 179 |
return Image.fromarray(pattern_rgba, mode="RGBA")
|
| 180 |
|
| 181 |
+
|
| 182 |
# ===============================
|
| 183 |
# WRAPPER: ACCEPT BYTES OR BASE64
|
| 184 |
# ===============================
|