Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -1,67 +1,71 @@
|
|
1 |
import gradio as gr
|
2 |
import numpy as np
|
3 |
-
from PIL import Image
|
|
|
4 |
import cv2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
|
6 |
def detect_dress_and_warp(hoodie_img, design_img, warp_strength, scale):
|
7 |
if hoodie_img is None or design_img is None:
|
8 |
return None
|
9 |
|
10 |
-
# Open images
|
11 |
hoodie = Image.open(hoodie_img).convert("RGBA")
|
12 |
design = Image.open(design_img).convert("RGBA")
|
|
|
13 |
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
if
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
|
26 |
-
# Resize design to fit within the detected dress
|
27 |
new_w, new_h = int(w * scale), int(h * scale)
|
28 |
design = design.resize((new_w, new_h))
|
29 |
-
|
30 |
|
31 |
-
|
32 |
-
|
33 |
-
grad_x = cv2.Sobel(hoodie_blur, cv2.CV_32F, 1, 0, ksize=5)
|
34 |
-
grad_y = cv2.Sobel(hoodie_blur, cv2.CV_32F, 0, 1, ksize=5)
|
35 |
-
normal_map = np.dstack((grad_x, grad_y, np.ones_like(grad_x)))
|
36 |
-
normal_map /= np.linalg.norm(normal_map, axis=2, keepdims=True)
|
37 |
|
38 |
-
# Apply warping effect based on fabric folds
|
39 |
-
flow_map = normal_map[:, :, :2] * warp_strength
|
40 |
-
rows, cols = design_cv.shape[:2]
|
41 |
-
map_x, map_y = np.meshgrid(np.arange(cols), np.arange(rows))
|
42 |
-
map_x = (map_x + flow_map[:, :, 0]).astype(np.float32)
|
43 |
-
map_y = (map_y + flow_map[:, :, 1]).astype(np.float32)
|
44 |
-
warped_design = cv2.remap(design_cv, map_x, map_y, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT)
|
45 |
-
design = Image.fromarray(cv2.cvtColor(warped_design, cv2.COLOR_BGRA2RGBA))
|
46 |
-
|
47 |
-
# Calculate placement at the center of the detected dress
|
48 |
paste_x = center_x - new_w // 2
|
49 |
paste_y = center_y - new_h // 2
|
50 |
|
51 |
-
# Create a blank image with same size as hoodie
|
52 |
temp_layer = Image.new("RGBA", hoodie.size, (0, 0, 0, 0))
|
53 |
-
|
54 |
-
# Paste design onto detected dress center
|
55 |
temp_layer.paste(design, (paste_x, paste_y), design)
|
56 |
|
57 |
-
# Blend the layers
|
58 |
final_image = Image.alpha_composite(hoodie, temp_layer)
|
59 |
return final_image
|
60 |
|
61 |
def generate_mockup(hoodie, design, warp_strength=5.0, scale=1.0):
|
62 |
return detect_dress_and_warp(hoodie, design, warp_strength, scale)
|
63 |
|
64 |
-
# Gradio UI
|
65 |
demo = gr.Interface(
|
66 |
fn=generate_mockup,
|
67 |
inputs=[
|
@@ -72,7 +76,7 @@ demo = gr.Interface(
|
|
72 |
],
|
73 |
outputs=gr.Image(type="pil", label="Generated Mockup"),
|
74 |
title="Rookus Hoodie Mockup Generator",
|
75 |
-
description="Upload a hoodie mockup and your design to generate a realistic preview with automatic dress detection and
|
76 |
)
|
77 |
|
78 |
demo.launch()
|
|
|
1 |
import gradio as gr
|
2 |
import numpy as np
|
3 |
+
from PIL import Image
|
4 |
+
import torch
|
5 |
import cv2
|
6 |
+
from torchvision import transforms
|
7 |
+
from u2net import U2NET
|
8 |
+
from tps_warp import apply_tps_warp
|
9 |
+
|
10 |
+
model = U2NET()
|
11 |
+
model.load_state_dict(torch.load("u2net.pth", map_location=torch.device('cpu')))
|
12 |
+
model.eval()
|
13 |
+
|
14 |
+
def get_dress_mask(image_np):
|
15 |
+
"""Segment the dress using U^2-Net."""
|
16 |
+
transform = transforms.Compose([
|
17 |
+
transforms.ToTensor(),
|
18 |
+
transforms.Resize((320, 320))
|
19 |
+
])
|
20 |
+
|
21 |
+
image = Image.fromarray(image_np).convert("RGB")
|
22 |
+
input_tensor = transform(image).unsqueeze(0)
|
23 |
+
|
24 |
+
with torch.no_grad():
|
25 |
+
output = model(input_tensor)[0][0].squeeze().cpu().numpy()
|
26 |
+
|
27 |
+
mask = (output > 0.5).astype(np.uint8)
|
28 |
+
return mask
|
29 |
|
30 |
def detect_dress_and_warp(hoodie_img, design_img, warp_strength, scale):
|
31 |
if hoodie_img is None or design_img is None:
|
32 |
return None
|
33 |
|
|
|
34 |
hoodie = Image.open(hoodie_img).convert("RGBA")
|
35 |
design = Image.open(design_img).convert("RGBA")
|
36 |
+
hoodie_np = np.array(hoodie)
|
37 |
|
38 |
+
dress_mask = get_dress_mask(hoodie_np)
|
39 |
+
if dress_mask is None:
|
40 |
+
return hoodie
|
41 |
+
|
42 |
+
y, x = np.where(dress_mask > 0)
|
43 |
+
if len(x) == 0 or len(y) == 0:
|
44 |
+
return hoodie
|
45 |
+
|
46 |
+
x_min, x_max, y_min, y_max = x.min(), x.max(), y.min(), y.max()
|
47 |
+
center_x, center_y = (x_min + x_max) // 2, (y_min + y_max) // 2
|
48 |
+
w, h = x_max - x_min, y_max - y_min
|
49 |
|
|
|
50 |
new_w, new_h = int(w * scale), int(h * scale)
|
51 |
design = design.resize((new_w, new_h))
|
52 |
+
design_np = np.array(design)
|
53 |
|
54 |
+
warped_design = apply_tps_warp(design_np, dress_mask, warp_strength)
|
55 |
+
design = Image.fromarray(warped_design)
|
|
|
|
|
|
|
|
|
56 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
paste_x = center_x - new_w // 2
|
58 |
paste_y = center_y - new_h // 2
|
59 |
|
|
|
60 |
temp_layer = Image.new("RGBA", hoodie.size, (0, 0, 0, 0))
|
|
|
|
|
61 |
temp_layer.paste(design, (paste_x, paste_y), design)
|
62 |
|
|
|
63 |
final_image = Image.alpha_composite(hoodie, temp_layer)
|
64 |
return final_image
|
65 |
|
66 |
def generate_mockup(hoodie, design, warp_strength=5.0, scale=1.0):
|
67 |
return detect_dress_and_warp(hoodie, design, warp_strength, scale)
|
68 |
|
|
|
69 |
demo = gr.Interface(
|
70 |
fn=generate_mockup,
|
71 |
inputs=[
|
|
|
76 |
],
|
77 |
outputs=gr.Image(type="pil", label="Generated Mockup"),
|
78 |
title="Rookus Hoodie Mockup Generator",
|
79 |
+
description="Upload a hoodie mockup and your design to generate a realistic preview with automatic dress detection and warping using TPS transformation."
|
80 |
)
|
81 |
|
82 |
demo.launch()
|