gaur3009 commited on
Commit
e83a791
·
verified ·
1 Parent(s): bbcbfff

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -115
app.py CHANGED
@@ -1,126 +1,72 @@
1
  import cv2
2
  import numpy as np
3
  from PIL import Image, ImageDraw, ImageFont
4
- import torch
5
- import torchvision.transforms as T
6
- from torchvision.models import resnet50
7
- from scipy.ndimage import gaussian_filter
8
  import gradio as gr
9
 
10
- class TextClothBlender:
11
- def __init__(self, font_path: str):
12
- self.font_path = font_path
13
- self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
14
- self.model = resnet50(pretrained=True).to(self.device)
15
- self.model.eval()
16
-
17
- def preprocess_cloth_image(self, cloth_image_path: str):
18
- # Load the cloth image
19
- cloth_image = cv2.imread(cloth_image_path)
20
- gray_image = cv2.cvtColor(cloth_image, cv2.COLOR_BGR2GRAY)
21
-
22
- # Detect texture using edge detection
23
- edges = cv2.Canny(gray_image, 50, 150)
24
-
25
- # Extract features using ResNet
26
- preprocess = T.Compose([
27
- T.ToPILImage(),
28
- T.Resize((224, 224)),
29
- T.ToTensor(),
30
- T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
31
- ])
32
- input_tensor = preprocess(cloth_image).unsqueeze(0).to(self.device)
33
- with torch.no_grad():
34
- features = self.model(input_tensor)
35
-
36
- return cloth_image, edges, features
37
-
38
- def render_text(self, text: str, font_size: int, text_color: tuple):
39
- # Create a blank image for text
40
- font = ImageFont.truetype(self.font_path, font_size)
41
- text_size = font.getsize(text)
42
- text_image = Image.new('RGBA', text_size, (255, 255, 255, 0))
43
- draw = ImageDraw.Draw(text_image)
44
- draw.text((0, 0), text, font=font, fill=text_color)
45
-
46
- return np.array(text_image)
47
-
48
- def apply_perspective_transform(self, text_image: np.ndarray, cloth_image_shape: tuple):
49
- # Define points for perspective transformation
50
- h, w, _ = cloth_image_shape
51
- src_points = np.float32([[0, 0], [text_image.shape[1], 0], [0, text_image.shape[0]], [text_image.shape[1], text_image.shape[0]]])
52
- dst_points = np.float32([[50, 50], [w - 50, 30], [50, h - 100], [w - 50, h - 120]])
53
-
54
- matrix = cv2.getPerspectiveTransform(src_points, dst_points)
55
- warped_text = cv2.warpPerspective(text_image, matrix, (w, h), flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=(0, 0, 0, 0))
56
-
57
- return warped_text
58
-
59
- def blend_text_with_cloth(self, cloth_image: np.ndarray, text_image: np.ndarray, edges: np.ndarray):
60
- # Convert cloth and text images to the same size
61
- h, w, _ = cloth_image.shape
62
- text_resized = cv2.resize(text_image, (w, h), interpolation=cv2.INTER_AREA)
63
-
64
- # Convert text to grayscale for masking
65
- text_gray = cv2.cvtColor(text_resized, cv2.COLOR_RGBA2GRAY)
66
- _, text_mask = cv2.threshold(text_gray, 1, 255, cv2.THRESH_BINARY)
67
-
68
- # Apply displacement mapping using the edges
69
- displace_map = gaussian_filter(edges, sigma=5)
70
- displaced_text = cv2.addWeighted(text_resized, 0.5, displace_map[..., None], 0.5, 0)
71
-
72
- # Blend text and cloth using overlay mode
73
- blended = cv2.addWeighted(cloth_image, 0.7, displaced_text[..., :3], 0.3, 0)
74
-
75
- return blended
76
-
77
- def refine_output(self, blended_image: np.ndarray):
78
- # Apply Gaussian blur for smooth edges
79
- refined = cv2.GaussianBlur(blended_image, (5, 5), 0)
80
- return refined
81
-
82
- def process(self, cloth_image_path: str, text: str, font_size: int, text_color: tuple):
83
- # Step 1: Preprocess the cloth image
84
- cloth_image, edges, _ = self.preprocess_cloth_image(cloth_image_path)
85
-
86
- # Step 2: Render the text
87
- text_image = self.render_text(text, font_size, text_color)
88
-
89
- # Step 3: Apply perspective transformation
90
- warped_text = self.apply_perspective_transform(text_image, cloth_image.shape)
91
-
92
- # Step 4: Blend text with the cloth
93
- blended_image = self.blend_text_with_cloth(cloth_image, warped_text, edges)
94
-
95
- # Step 5: Refine the output
96
- final_image = self.refine_output(blended_image)
97
-
98
- return final_image
99
-
100
- # Define the Gradio interface
101
- def blend_text_on_cloth(cloth_image, text, font_size, text_color):
102
- font_path = "path/to/font.ttf" # Ensure the font file exists in the deployed environment
103
- blender = TextClothBlender(font_path)
104
- text_color = tuple(map(int, text_color.strip('()').split(','))) # Convert string to tuple
105
- cloth_image_path = "temp_cloth_image.jpg"
106
-
107
- # Save the uploaded cloth image temporarily
108
- cv2.imwrite(cloth_image_path, cv2.cvtColor(np.array(cloth_image), cv2.COLOR_RGB2BGR))
109
-
110
- # Process the image
111
- result = blender.process(cloth_image_path, text, int(font_size), text_color)
112
- return result[:, :, ::-1] # Convert BGR to RGB for display
113
-
114
- iface = gr.Interface(
115
- fn=blend_text_on_cloth,
116
  inputs=[
117
  gr.Image(type="pil", label="Upload Cloth Image"),
118
- gr.Textbox(label="Text to Blend"),
119
- gr.Slider(10, 100, step=1, label="Font Size"),
120
- gr.Textbox(label="Text Color (R,G,B,A)", placeholder="e.g., 255,0,0,255")
 
 
121
  ],
122
- outputs=gr.Image(type="numpy", label="Blended Output")
 
 
123
  )
124
 
 
125
  if __name__ == "__main__":
126
- iface.launch()
 
1
  import cv2
2
  import numpy as np
3
  from PIL import Image, ImageDraw, ImageFont
 
 
 
 
4
  import gradio as gr
5
 
6
+
7
+ # Function to detect fabric texture and generate a displacement map
8
+ def generate_displacement_map(image):
9
+ gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
10
+ laplacian = cv2.Laplacian(gray, cv2.CV_32F) # Detect edges and texture
11
+ displacement_map = cv2.normalize(laplacian, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX)
12
+ return displacement_map
13
+
14
+
15
+ # Function to blend text with the cloth image
16
+ def blend_text_with_cloth(cloth_image, text, font_size=32, font_color=(255, 0, 0), x=50, y=50):
17
+ # Convert cloth image to BGR for OpenCV processing
18
+ cloth_image = np.array(cloth_image)
19
+ cloth_bgr = cv2.cvtColor(cloth_image, cv2.COLOR_RGBA2BGRA)
20
+
21
+ # Generate displacement map
22
+ displacement_map = generate_displacement_map(cloth_bgr)
23
+
24
+ # Render text
25
+ img_pil = Image.fromarray(cloth_image)
26
+ draw = ImageDraw.Draw(img_pil)
27
+
28
+ # Load a font (use a default font if custom font isn't available)
29
+ try:
30
+ font = ImageFont.truetype("arial.ttf", font_size)
31
+ except:
32
+ font = ImageFont.load_default()
33
+
34
+ draw.text((x, y), text, font=font, fill=font_color)
35
+ rendered_text = np.array(img_pil)
36
+
37
+ # Convert rendered text image to BGR
38
+ text_bgr = cv2.cvtColor(rendered_text, cv2.COLOR_RGBA2BGRA)
39
+
40
+ # Blend text with cloth image using displacement map
41
+ blended = cv2.addWeighted(cloth_bgr, 0.8, text_bgr, 0.5, 0)
42
+ final_image = cv2.cvtColor(blended, cv2.COLOR_BGRA2RGBA)
43
+
44
+ return Image.fromarray(final_image)
45
+
46
+
47
+ # Gradio function
48
+ def process_image(image, text, font_size, font_color, x, y):
49
+ font_color = tuple(map(int, font_color.strip("()").split(","))) # Convert string to tuple
50
+ result = blend_text_with_cloth(image, text, font_size, font_color, x, y)
51
+ return result
52
+
53
+
54
+ # Gradio Interface
55
+ interface = gr.Interface(
56
+ fn=process_image,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  inputs=[
58
  gr.Image(type="pil", label="Upload Cloth Image"),
59
+ gr.Textbox(label="Text to Blend", default="Sample Text"),
60
+ gr.Slider(10, 100, step=2, label="Font Size", default=32),
61
+ gr.Textbox(label="Font Color (RGB)", default="(255, 0, 0)"),
62
+ gr.Slider(0, 1000, step=10, label="X Coordinate", default=50),
63
+ gr.Slider(0, 1000, step=10, label="Y Coordinate", default=50),
64
  ],
65
+ outputs=gr.Image(type="pil", label="Blended Output"),
66
+ title="Text-Cloth Blending",
67
+ description="Upload a cloth image and add text that blends naturally into the fabric. Adjust parameters like font size, color, and position.",
68
  )
69
 
70
+ # Launch the app
71
  if __name__ == "__main__":
72
+ interface.launch()