File size: 3,621 Bytes
00b93d3
 
 
 
 
 
 
7ba5ba4
 
 
 
 
 
00b93d3
 
7ba5ba4
3327a73
 
 
 
 
 
 
00b93d3
3327a73
 
 
00b93d3
9b06638
00b93d3
cc5f70a
 
 
 
 
 
7888c29
 
 
cc5f70a
 
7888c29
 
cc5f70a
 
9144506
cc5f70a
2201b09
7bda381
00b93d3
 
9144506
cc5f70a
b938ae3
9144506
cc5f70a
9144506
7bda381
9144506
cc5f70a
7d41451
 
109a86d
cc5f70a
9144506
cc5f70a
 
 
9144506
cc5f70a
b938ae3
cc5f70a
109a86d
7888c29
 
 
 
deceec0
cc5f70a
00b93d3
 
9144506
00b93d3
 
 
 
 
 
b938ae3
00b93d3
 
 
7ba5ba4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import gradio as gr
import torch
import cv2
import numpy as np
from torchvision import transforms
from PIL import Image

# Load MiDaS depth estimation model from torch.hub
midas_model = torch.hub.load("intel-isl/MiDaS", "MiDaS_small")
midas_model.eval()
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
midas_model.to(device)
midas_transform = torch.hub.load("intel-isl/MiDaS", "transforms").default_transform

def estimate_depth(image):
    """Estimate depth map using MiDaS v3."""
    image = image.convert("RGB")  # Ensure it's in RGB format
    img_tensor = midas_transform(image).unsqueeze(0).to(device)

    # Ensure tensor shape is [1, 3, H, W]
    if img_tensor.dim() == 5:  # If an extra batch dimension is present
        img_tensor = img_tensor.squeeze(1)

    with torch.no_grad():
        depth = midas_model(img_tensor).squeeze().cpu().numpy()
    
    depth = cv2.resize(depth, (image.size[0], image.size[1]))
    depth = (depth - depth.min()) / (depth.max() - depth.min()) * 255
    return depth.astype(np.uint8)

def apply_tps_warping(design, depth):
    """Apply Thin Plate Spline (TPS) warping based on depth."""
    h, w = depth.shape
    grid_x, grid_y = np.meshgrid(np.arange(w), np.arange(h))
    displacement_x = cv2.Sobel(depth, cv2.CV_32F, 1, 0, ksize=5)
    displacement_y = cv2.Sobel(depth, cv2.CV_32F, 0, 1, ksize=5)
    displacement_x = cv2.normalize(displacement_x, None, -5, 5, cv2.NORM_MINMAX)
    displacement_y = cv2.normalize(displacement_y, None, -5, 5, cv2.NORM_MINMAX)
    
    map_x = np.clip(grid_x + displacement_x, 0, w - 1).astype(np.float32)
    map_y = np.clip(grid_y + displacement_y, 0, h - 1).astype(np.float32)
    
    warped_design = cv2.remap(design, map_x, map_y, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT)
    return warped_design

def blend_design(cloth_img, design_img):
    """Blend design onto clothing naturally with fold adaptation using TPS warping."""
    cloth_img = cloth_img.convert("RGB")
    design_img = design_img.convert("RGBA")
    cloth_np = np.array(cloth_img)
    design_np = np.array(design_img)
    
    # Resize design
    h, w, _ = cloth_np.shape
    dh, dw, _ = design_np.shape
    scale_factor = min(w / dw, h / dh) * 0.4  
    new_w, new_h = int(dw * scale_factor), int(dh * scale_factor)
    design_np = cv2.resize(design_np, (new_w, new_h), interpolation=cv2.INTER_AREA)
    
    # Extract alpha channel
    alpha_channel = design_np[:, :, 3] / 255.0
    design_np = design_np[:, :, :3]
    
    # Create placement area
    x_offset = (w - new_w) // 2
    y_offset = int(h * 0.35)
    design_canvas = np.zeros_like(cloth_np)
    design_canvas[y_offset:y_offset+new_h, x_offset:x_offset+new_w] = design_np
    
    # Estimate depth and apply TPS warping
    depth_map = estimate_depth(cloth_img)
    warped_design = apply_tps_warping(design_canvas, depth_map)
    
    # Ensure alpha is applied correctly
    mask = np.zeros_like(cloth_np, dtype=np.float32)
    mask[y_offset:y_offset+new_h, x_offset:x_offset+new_w] = np.expand_dims(alpha_channel, axis=-1)
    cloth_np = (cloth_np * (1 - mask) + warped_design * mask).astype(np.uint8)
    
    return Image.fromarray(cloth_np)

def main(cloth, design):
    return blend_design(cloth, design)

iface = gr.Interface(
    fn=main,
    inputs=[gr.Image(type="pil"), gr.Image(type="pil")],
    outputs=gr.Image(type="pil"),
    title="AI Cloth Design Warping",
    description="Upload a clothing image and a design to blend it naturally, ensuring it stays centered and follows fabric folds."
)

if __name__ == "__main__":
    iface.launch(share=True)