Jagrut Thakare commited on
Commit
66167c6
·
1 Parent(s): 83c3ff4
Files changed (2) hide show
  1. app.py +96 -0
  2. requirements.txt +2 -0
app.py ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ import gradio as gr
4
+
5
+ def find_bounding_box(mask):
6
+ """Find the bounding box around the largest contour in the mask."""
7
+ mask = mask.astype(np.uint8)
8
+ _, binary_mask = cv2.threshold(mask, 1, 255, cv2.THRESH_BINARY)
9
+
10
+ contours, _ = cv2.findContours(binary_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
11
+ if contours:
12
+ x, y, w, h = cv2.boundingRect(np.vstack(contours))
13
+ return x, y, w, h
14
+ return None
15
+
16
+ def overlay_logo_on_image(original_img, mask, logo):
17
+ """Overlay a scaled logo while maintaining aspect ratio and centering it in the bounding box."""
18
+ bbox = find_bounding_box(mask)
19
+ if bbox is None:
20
+ print("No bounding box found. Returning original image.")
21
+ return original_img
22
+
23
+ x, y, w, h = bbox
24
+ print(f"Bounding box found at: x={x}, y={y}, w={w}, h={h}")
25
+
26
+ # Get original logo dimensions
27
+ logo_h, logo_w = logo.shape[:2]
28
+
29
+ # Compute the scaling factor while maintaining aspect ratio
30
+ scale = min(w / logo_w, h / logo_h)
31
+ new_w, new_h = int(logo_w * scale), int(logo_h * scale)
32
+
33
+ # Resize the logo while maintaining aspect ratio
34
+ logo_resized = cv2.resize(logo, (new_w, new_h), interpolation=cv2.INTER_AREA)
35
+
36
+ # Ensure logo_resized has 4 channels (RGBA)
37
+ if logo_resized.shape[2] == 3:
38
+ logo_resized = cv2.cvtColor(logo_resized, cv2.COLOR_RGB2RGBA)
39
+
40
+ # Create a blank transparent canvas (RGBA)
41
+ logo_canvas = np.zeros((h, w, 4), dtype=np.uint8)
42
+
43
+ # Compute centering offsets
44
+ x_offset = (w - new_w) // 2
45
+ y_offset = (h - new_h) // 2
46
+
47
+ # Place the resized logo at the center of the bounding box
48
+ logo_canvas[y_offset:y_offset + new_h, x_offset:x_offset + new_w] = logo_resized
49
+
50
+ # Convert original image to 4-channel if necessary
51
+ if original_img.shape[2] == 3:
52
+ original_img = cv2.cvtColor(original_img, cv2.COLOR_RGB2RGBA)
53
+
54
+ # Blend the logo into the image using alpha blending
55
+ alpha = logo_canvas[:, :, 3] / 255.0
56
+ for c in range(3):
57
+ original_img[y:y+h, x:x+w, c] = (
58
+ (1 - alpha) * original_img[y:y+h, x:x+w, c] + alpha * logo_canvas[:, :, c]
59
+ )
60
+
61
+ return original_img
62
+
63
+ def process_images(original_img, mask, logo, progress=gr.Progress()):
64
+ """Process images: overlay logo using uploaded mask."""
65
+ original_img = cv2.cvtColor(np.array(original_img), cv2.COLOR_RGB2BGR)
66
+ mask = np.array(mask)
67
+ logo = cv2.cvtColor(np.array(logo), cv2.COLOR_RGB2BGR)
68
+
69
+
70
+ if len(mask.shape) == 3:
71
+ mask = cv2.cvtColor(mask, cv2.COLOR_RGB2GRAY)
72
+
73
+ mask = (mask > 0).astype(np.uint8) * 255 # Ensure binary mask
74
+
75
+ print(f"Mask shape: {mask.shape}, unique values: {np.unique(mask)}")
76
+
77
+ result_img = overlay_logo_on_image(original_img, mask, logo)
78
+ result_img = cv2.cvtColor(result_img, cv2.COLOR_BGRA2RGBA) if result_img.shape[2] == 4 else cv2.cvtColor(result_img, cv2.COLOR_BGR2RGB)
79
+
80
+ return result_img
81
+
82
+ with gr.Blocks() as demo :
83
+ gr.Markdown("## Inpaint Logo on Uploaded Mask")
84
+ with gr.Row() :
85
+ with gr.Column() :
86
+ with gr.Row():
87
+ original_img = gr.Image(label="Upload Original Image", type="numpy")
88
+ with gr.Row():
89
+ mask = gr.Image(label="Upload Mask (Binary)", type="numpy")
90
+ logo = gr.Image(label="Upload Logo", type="numpy")
91
+ btn = gr.Button("Submit")
92
+ with gr.Column() :
93
+ output = gr.Image(label="Output Image", format="png")
94
+ btn.click(fn=process_images, inputs=[original_img, mask, logo], outputs=output)
95
+
96
+ demo.launch(share=True, debug=True)
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ opencv-python
2
+ numpy