gaur3009 commited on
Commit
9a5bad4
·
verified ·
1 Parent(s): 1b8657c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -43
app.py CHANGED
@@ -4,8 +4,9 @@ import cv2
4
  import numpy as np
5
  from torchvision import transforms
6
  from PIL import Image
 
7
 
8
- # Load MiDaS depth estimation model from torch.hub
9
  midas_model = torch.hub.load("intel-isl/MiDaS", "MiDaS_small")
10
  midas_model.eval()
11
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
@@ -13,74 +14,59 @@ midas_model.to(device)
13
  midas_transform = torch.hub.load("intel-isl/MiDaS", "transforms").default_transform
14
 
15
  def estimate_depth(image):
16
- """Estimate depth map using MiDaS v3."""
17
- image = image.convert("RGB") # Ensure it's in RGB format
18
-
19
- # Convert PIL image to a NumPy array and normalize it
20
- img_np = np.array(image, dtype=np.float32) / 255.0 # Normalize to [0, 1]
21
-
22
- # Convert NumPy array to a Torch tensor
23
- img_tensor = torch.tensor(img_np).permute(2, 0, 1).unsqueeze(0).to(device)
24
-
25
- # Ensure tensor shape is [1, 3, H, W]
26
- if img_tensor.dim() == 5: # If an extra batch dimension is present
27
- img_tensor = img_tensor.squeeze(1)
28
-
29
  with torch.no_grad():
30
  depth = midas_model(img_tensor).squeeze().cpu().numpy()
31
-
32
  depth = cv2.resize(depth, (image.size[0], image.size[1]))
33
  depth = (depth - depth.min()) / (depth.max() - depth.min()) * 255
34
  return depth.astype(np.uint8)
35
 
36
- def apply_tps_warping(design, depth):
37
- """Apply Thin Plate Spline (TPS) warping based on depth."""
 
 
 
 
 
 
38
  h, w = depth.shape
39
  grid_x, grid_y = np.meshgrid(np.arange(w), np.arange(h))
40
- displacement_x = cv2.Sobel(depth, cv2.CV_32F, 1, 0, ksize=5)
41
- displacement_y = cv2.Sobel(depth, cv2.CV_32F, 0, 1, ksize=5)
42
- displacement_x = cv2.normalize(displacement_x, None, -5, 5, cv2.NORM_MINMAX)
43
- displacement_y = cv2.normalize(displacement_y, None, -5, 5, cv2.NORM_MINMAX)
44
-
45
- map_x = np.clip(grid_x + displacement_x, 0, w - 1).astype(np.float32)
46
- map_y = np.clip(grid_y + displacement_y, 0, h - 1).astype(np.float32)
47
-
48
- warped_design = cv2.remap(design, map_x, map_y, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT)
49
- return warped_design
 
 
 
 
50
 
51
  def blend_design(cloth_img, design_img):
52
- """Blend design onto clothing naturally with fold adaptation using TPS warping."""
53
  cloth_img = cloth_img.convert("RGB")
54
  design_img = design_img.convert("RGBA")
55
  cloth_np = np.array(cloth_img)
56
  design_np = np.array(design_img)
57
-
58
- # Resize design
59
  h, w, _ = cloth_np.shape
60
  dh, dw, _ = design_np.shape
61
  scale_factor = min(w / dw, h / dh) * 0.4
62
  new_w, new_h = int(dw * scale_factor), int(dh * scale_factor)
63
  design_np = cv2.resize(design_np, (new_w, new_h), interpolation=cv2.INTER_AREA)
64
-
65
- # Extract alpha channel
66
  alpha_channel = design_np[:, :, 3] / 255.0
67
  design_np = design_np[:, :, :3]
68
-
69
- # Create placement area
70
  x_offset = (w - new_w) // 2
71
  y_offset = int(h * 0.35)
72
  design_canvas = np.zeros_like(cloth_np)
73
  design_canvas[y_offset:y_offset+new_h, x_offset:x_offset+new_w] = design_np
74
-
75
- # Estimate depth and apply TPS warping
76
  depth_map = estimate_depth(cloth_img)
77
- warped_design = apply_tps_warping(design_canvas, depth_map)
78
-
79
- # Ensure alpha is applied correctly
80
- mask = np.zeros_like(cloth_np, dtype=np.float32)
81
- mask[y_offset:y_offset+new_h, x_offset:x_offset+new_w] = np.expand_dims(alpha_channel, axis=-1)
82
- cloth_np = (cloth_np * (1 - mask) + warped_design * mask).astype(np.uint8)
83
-
84
  return Image.fromarray(cloth_np)
85
 
86
  def main(cloth, design):
 
4
  import numpy as np
5
  from torchvision import transforms
6
  from PIL import Image
7
+ from scipy.interpolate import Rbf
8
 
9
+ # Load MiDaS depth estimation model
10
  midas_model = torch.hub.load("intel-isl/MiDaS", "MiDaS_small")
11
  midas_model.eval()
12
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
 
14
  midas_transform = torch.hub.load("intel-isl/MiDaS", "transforms").default_transform
15
 
16
  def estimate_depth(image):
17
+ image = image.convert("RGB")
18
+ img_tensor = midas_transform(image).to(device)
 
 
 
 
 
 
 
 
 
 
 
19
  with torch.no_grad():
20
  depth = midas_model(img_tensor).squeeze().cpu().numpy()
 
21
  depth = cv2.resize(depth, (image.size[0], image.size[1]))
22
  depth = (depth - depth.min()) / (depth.max() - depth.min()) * 255
23
  return depth.astype(np.uint8)
24
 
25
+ def compute_optical_flow(depth):
26
+ depth_blurred = cv2.GaussianBlur(depth, (5, 5), 0)
27
+ flow = cv2.calcOpticalFlowFarneback(depth_blurred, depth, None, 0.5, 3, 15, 3, 5, 1.2, 0)
28
+ displacement_x = cv2.normalize(flow[..., 0], None, -5, 5, cv2.NORM_MINMAX)
29
+ displacement_y = cv2.normalize(flow[..., 1], None, -5, 5, cv2.NORM_MINMAX)
30
+ return displacement_x, displacement_y
31
+
32
+ def apply_tps_interpolation(design, depth):
33
  h, w = depth.shape
34
  grid_x, grid_y = np.meshgrid(np.arange(w), np.arange(h))
35
+ edges = cv2.Canny(depth.astype(np.uint8), 50, 150)
36
+ points = np.column_stack(np.where(edges > 0))
37
+ tps_x = Rbf(points[:, 1], points[:, 0], grid_x[points[:, 0], points[:, 1]], function="thin_plate")
38
+ tps_y = Rbf(points[:, 1], points[:, 0], grid_y[points[:, 0], points[:, 1]], function="thin_plate")
39
+ map_x = tps_x(grid_x, grid_y).astype(np.float32)
40
+ map_y = tps_y(grid_x, grid_y).astype(np.float32)
41
+ return cv2.remap(design, map_x, map_y, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT)
42
+
43
+ def compute_adaptive_alpha(depth):
44
+ grad_x = cv2.Sobel(depth, cv2.CV_32F, 1, 0, ksize=3)
45
+ grad_y = cv2.Sobel(depth, cv2.CV_32F, 0, 1, ksize=3)
46
+ grad_magnitude = np.sqrt(grad_x**2 + grad_y**2)
47
+ alpha = cv2.normalize(grad_magnitude, None, 0, 1, cv2.NORM_MINMAX)
48
+ return alpha
49
 
50
  def blend_design(cloth_img, design_img):
 
51
  cloth_img = cloth_img.convert("RGB")
52
  design_img = design_img.convert("RGBA")
53
  cloth_np = np.array(cloth_img)
54
  design_np = np.array(design_img)
 
 
55
  h, w, _ = cloth_np.shape
56
  dh, dw, _ = design_np.shape
57
  scale_factor = min(w / dw, h / dh) * 0.4
58
  new_w, new_h = int(dw * scale_factor), int(dh * scale_factor)
59
  design_np = cv2.resize(design_np, (new_w, new_h), interpolation=cv2.INTER_AREA)
 
 
60
  alpha_channel = design_np[:, :, 3] / 255.0
61
  design_np = design_np[:, :, :3]
 
 
62
  x_offset = (w - new_w) // 2
63
  y_offset = int(h * 0.35)
64
  design_canvas = np.zeros_like(cloth_np)
65
  design_canvas[y_offset:y_offset+new_h, x_offset:x_offset+new_w] = design_np
 
 
66
  depth_map = estimate_depth(cloth_img)
67
+ warped_design = apply_tps_interpolation(design_canvas, depth_map)
68
+ adaptive_alpha = compute_adaptive_alpha(depth_map)
69
+ cloth_np = (cloth_np * (1 - adaptive_alpha) + warped_design * adaptive_alpha).astype(np.uint8)
 
 
 
 
70
  return Image.fromarray(cloth_np)
71
 
72
  def main(cloth, design):