Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
@@ -1,100 +1,86 @@
|
|
1 |
-
import os
|
2 |
import cv2
|
3 |
import numpy as np
|
4 |
-
from PIL import Image, ImageDraw, ImageFont
|
5 |
import gradio as gr
|
6 |
-
import
|
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 |
def apply_displacement_map(text_img, clothing_img, strength=20):
|
|
|
33 |
gray = cv2.cvtColor(clothing_img, cv2.COLOR_BGR2GRAY)
|
34 |
grad_x = cv2.Sobel(gray, cv2.CV_32F, 1, 0, ksize=5)
|
35 |
grad_y = cv2.Sobel(gray, cv2.CV_32F, 0, 1, ksize=5)
|
|
|
36 |
grad_x = cv2.normalize(grad_x, None, 0, 1, cv2.NORM_MINMAX)
|
37 |
grad_y = cv2.normalize(grad_y, None, 0, 1, cv2.NORM_MINMAX)
|
|
|
38 |
displacement_map = np.zeros_like(clothing_img, dtype=np.float32)
|
39 |
displacement_map[:, :, 0] = grad_x * strength
|
40 |
displacement_map[:, :, 1] = grad_y * strength
|
41 |
-
|
|
|
|
|
|
|
|
|
|
|
42 |
return text_warped
|
43 |
|
44 |
-
def
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
return text_overlay, None
|
66 |
-
|
67 |
-
def process_image(image, text, font_size, color, font_path, placement_x, placement_y):
|
68 |
-
try:
|
69 |
-
mask = segment_clothing(image)
|
70 |
-
if mask.sum() == 0:
|
71 |
-
return "No clothing detected. Try another image."
|
72 |
-
manual_coords = (placement_x, placement_y)
|
73 |
-
text_overlay, error = overlay_text(image, text, font_path, font_size, color, mask, manual_coords)
|
74 |
-
if error:
|
75 |
-
return error
|
76 |
-
text_img = np.array(text_overlay.convert("RGB"))
|
77 |
-
text_warped = apply_displacement_map(text_img, image)
|
78 |
-
blended_image = blend_images(text_warped, image)
|
79 |
-
return Image.fromarray(blended_image)
|
80 |
-
except Exception as e:
|
81 |
-
return f"Error: {str(e)}"
|
82 |
-
|
83 |
-
# Gradio Interface
|
84 |
-
font_options = ["/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", "/path/to/another/font.ttf"]
|
85 |
-
|
86 |
-
gr.Interface(
|
87 |
-
fn=process_image,
|
88 |
inputs=[
|
89 |
-
gr.Image(type="
|
90 |
-
gr.Textbox(label="Enter Text"),
|
91 |
-
gr.
|
92 |
-
gr.
|
93 |
-
gr.
|
94 |
-
gr.Number(label="Text Placement X", value=0),
|
95 |
-
gr.Number(label="Text Placement Y", value=0),
|
96 |
],
|
97 |
-
outputs=gr.Image(type="pil", label="Final
|
98 |
-
title="
|
99 |
-
description="Upload a clothing image
|
100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import cv2
|
2 |
import numpy as np
|
|
|
3 |
import gradio as gr
|
4 |
+
from PIL import Image, ImageDraw, ImageFont
|
5 |
+
import io
|
6 |
+
|
7 |
+
def generate_text_image(text, style, width, height):
|
8 |
+
"""Generate an image of the input text with the selected style."""
|
9 |
+
font_path = {
|
10 |
+
"Bold": "arialbd.ttf",
|
11 |
+
"Italic": "ariali.ttf",
|
12 |
+
"Graffiti": "graffiti.ttf", # Provide custom font if needed
|
13 |
+
"Calligraphy": "calligraphy.ttf" # Provide custom font if needed
|
14 |
+
}
|
15 |
+
|
16 |
+
img = Image.new("RGBA", (width, height), (255, 255, 255, 0))
|
17 |
+
draw = ImageDraw.Draw(img)
|
18 |
+
|
19 |
+
try:
|
20 |
+
font = ImageFont.truetype(font_path[style], size=80)
|
21 |
+
except:
|
22 |
+
font = ImageFont.load_default()
|
23 |
+
|
24 |
+
text_width, text_height = draw.textsize(text, font=font)
|
25 |
+
position = ((width - text_width) // 2, (height - text_height) // 2)
|
26 |
+
|
27 |
+
draw.text(position, text, font=font, fill=(0, 0, 0, 255))
|
28 |
+
|
29 |
+
return img
|
30 |
|
31 |
def apply_displacement_map(text_img, clothing_img, strength=20):
|
32 |
+
"""Apply displacement map to blend text onto clothing."""
|
33 |
gray = cv2.cvtColor(clothing_img, cv2.COLOR_BGR2GRAY)
|
34 |
grad_x = cv2.Sobel(gray, cv2.CV_32F, 1, 0, ksize=5)
|
35 |
grad_y = cv2.Sobel(gray, cv2.CV_32F, 0, 1, ksize=5)
|
36 |
+
|
37 |
grad_x = cv2.normalize(grad_x, None, 0, 1, cv2.NORM_MINMAX)
|
38 |
grad_y = cv2.normalize(grad_y, None, 0, 1, cv2.NORM_MINMAX)
|
39 |
+
|
40 |
displacement_map = np.zeros_like(clothing_img, dtype=np.float32)
|
41 |
displacement_map[:, :, 0] = grad_x * strength
|
42 |
displacement_map[:, :, 1] = grad_y * strength
|
43 |
+
|
44 |
+
text_warped = cv2.remap(text_img,
|
45 |
+
displacement_map[:, :, 0].astype(np.float32),
|
46 |
+
displacement_map[:, :, 1].astype(np.float32),
|
47 |
+
interpolation=cv2.INTER_LINEAR)
|
48 |
+
|
49 |
return text_warped
|
50 |
|
51 |
+
def overlay_text_on_clothing(clothing_image, text_input, style, strength=20, alpha=0.7):
|
52 |
+
"""Blend generated text onto the clothing image."""
|
53 |
+
clothing_img = cv2.imdecode(np.frombuffer(clothing_image, np.uint8), cv2.IMREAD_COLOR)
|
54 |
+
|
55 |
+
# Generate text image dynamically
|
56 |
+
text_img_pil = generate_text_image(text_input, style, clothing_img.shape[1], clothing_img.shape[0])
|
57 |
+
text_img = cv2.cvtColor(np.array(text_img_pil), cv2.COLOR_RGBA2BGRA)
|
58 |
+
|
59 |
+
alpha_channel = text_img[:, :, 3] / 255.0
|
60 |
+
text_img = text_img[:, :, :3]
|
61 |
+
|
62 |
+
text_warped = apply_displacement_map(text_img, clothing_img, strength)
|
63 |
+
|
64 |
+
for c in range(3):
|
65 |
+
clothing_img[:, :, c] = (1 - alpha_channel) * clothing_img[:, :, c] + alpha_channel * text_warped[:, :, c]
|
66 |
+
|
67 |
+
_, buffer = cv2.imencode('.jpg', clothing_img)
|
68 |
+
return buffer.tobytes()
|
69 |
+
|
70 |
+
interface = gr.Interface(
|
71 |
+
fn=overlay_text_on_clothing,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
inputs=[
|
73 |
+
gr.Image(type="binary", label="Upload Clothing Image", tool="editor"),
|
74 |
+
gr.Textbox(label="Enter Text for Design"),
|
75 |
+
gr.Radio(["Bold", "Italic", "Graffiti", "Calligraphy"], label="Select Style", value="Bold"),
|
76 |
+
gr.Slider(10, 50, step=5, default=20, label="Displacement Strength"),
|
77 |
+
gr.Slider(0.1, 1.0, step=0.1, default=0.7, label="Alpha Blending")
|
|
|
|
|
78 |
],
|
79 |
+
outputs=gr.Image(type="pil", label="Final Design"),
|
80 |
+
title="AI-Powered Clothing Text Overlay",
|
81 |
+
description="Upload a clothing image, enter a text design, and select a style to blend them onto clothing with displacement mapping.",
|
82 |
+
allow_flagging="never"
|
83 |
+
)
|
84 |
+
|
85 |
+
if __name__ == "__main__":
|
86 |
+
interface.launch()
|