Blends / app.py
gaur3009's picture
Update app.py
cc5f70a verified
raw
history blame
3.42 kB
import gradio as gr
import torch
import cv2
import numpy as np
from torchvision import transforms
from PIL import Image
from transformers import DPTForDepthEstimation, DPTFeatureExtractor, MidasForDepthEstimation, MidasImageProcessor
# Load depth estimation model (MiDaS v3 for better accuracy)
model_name = "Intel/midas-v3" # Upgraded model
processor = MidasImageProcessor.from_pretrained(model_name)
depth_model = MidasForDepthEstimation.from_pretrained(model_name)
depth_model.eval()
def estimate_depth(image):
"""Estimate depth map from image using MiDaS v3."""
image = image.convert("RGB")
inputs = processor(images=image, return_tensors="pt")
with torch.no_grad():
outputs = depth_model(**inputs)
depth = outputs.predicted_depth.squeeze().cpu().numpy()
depth = cv2.resize(depth, (image.width, image.height))
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, -10, 10, cv2.NORM_MINMAX)
displacement_y = cv2.normalize(displacement_y, None, -10, 10, 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_CUBIC, 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)
# Blend design onto cloth
for c in range(3):
cloth_np[:, :, c] = (cloth_np[:, :, c] * (1 - alpha_channel) + warped_design[:, :, c] * alpha_channel)
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)