NeuralFalcon commited on
Commit
9aab3ff
·
verified ·
1 Parent(s): 3b582a6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +245 -232
app.py CHANGED
@@ -1,232 +1,245 @@
1
- import gradio as gr
2
- import numpy as np
3
- import imageio
4
- import cv2
5
- import numpy as np
6
- from inpaint import InpaintingTester
7
- import os
8
- import shutil
9
- import re
10
- import uuid
11
-
12
- def create_mask(watermark, mask_type="white"):
13
- """
14
- Create a mask for the watermark region.
15
- mask_type: 'white' for white mask and 'black' for black mask
16
- """
17
- h, w, _ = watermark.shape
18
- if mask_type == "white":
19
- return np.ones((h, w), dtype=np.uint8) * 255 # White mask
20
- elif mask_type == "black":
21
- return np.zeros((h, w), dtype=np.uint8) # Black mask
22
- return None
23
-
24
-
25
- def inpaint_watermark(watermark, mask):
26
- """Inpaint the watermark region using the mask."""
27
- return cv2.inpaint(watermark, mask, inpaintRadius=3, flags=cv2.INPAINT_TELEA)
28
-
29
-
30
- def place_inpainted_back(image, inpainted_region, location):
31
- """Place the inpainted region back into the original image."""
32
- x_start, y_start, x_end, y_end = location
33
- image[y_start:y_end, x_start:x_end] = inpainted_region
34
- return image
35
-
36
-
37
- def extract_watermark(image, height_ratio=0.15, width_ratio=0.15, margin=0):
38
- """Extract watermark from the image using given ratios and margin."""
39
- h, w, _ = image.shape
40
- crop_h, crop_w = int(h * height_ratio), int(w * width_ratio)
41
- x_start, y_start = w - crop_w, h - crop_h
42
- watermark = image[y_start:h-margin, x_start:w-margin]
43
- location = (x_start, y_start, w-margin, h-margin)
44
- return watermark, location
45
-
46
-
47
- def load_inpainting_model():
48
- """Load the inpainting model."""
49
- save_path = "./output"
50
- # resize_to = None # Default size from config
51
- resize_to = (480,480)
52
- return InpaintingTester(save_path, resize_to)
53
-
54
-
55
- def process_image_with_model(image_path, mask_path, tester):
56
- """Process the image using the inpainting model and return the cleaned image path."""
57
- image_mask_pairs = [(image_path, mask_path)]
58
- return tester.process_multiple_images(image_mask_pairs)[0]
59
-
60
-
61
-
62
-
63
-
64
- def img_file_name(image_path):
65
- global image_folder
66
- text=os.path.basename(image_path)
67
- text=text.split(".")[0]
68
- # Remove all non-alphabetic characters and convert to lowercase
69
- text = re.sub(r'[^a-zA-Z\s]', '', text) # Retain only alphabets and spaces
70
- text = text.lower().strip() # Convert to lowercase and strip leading/trailing spaces
71
- text = text.replace(" ", "_") # Replace spaces with underscores
72
-
73
- # Truncate or handle empty text
74
- truncated_text = text[:25] if len(text) > 25 else text if len(text) > 0 else "empty"
75
-
76
- # Generate a random string for uniqueness
77
- random_string = uuid.uuid4().hex[:8].upper()
78
-
79
- # Construct the file name
80
- file_name = f"{image_folder}/{truncated_text}_{random_string}.png"
81
- return file_name
82
-
83
- def logo_remover(image_path):
84
- image = cv2.imread(image_path)
85
- image = cv2.resize(image, (1280, 1280)) # Resize image if needed
86
-
87
- # Extract watermark and location
88
- first_crop, first_location = extract_watermark(image, 0.50, 0.50, 0)
89
- watermark, location = extract_watermark(first_crop, 0.12, 0.26, 27) #height, side, margin
90
-
91
-
92
- # Create black and white masks
93
- mask1 = create_mask(first_crop, "black")
94
- mask2 = create_mask(watermark, "white")
95
- combined_mask = place_inpainted_back(mask1, mask2, location)
96
-
97
- # Save temporary files
98
- input_image = "./input/temp.png"
99
- input_mask = "./input/temp_mask.png"
100
- # temp_image = cv2.resize(first_crop, (512, 512))
101
- temp_image=first_crop
102
- cv2.imwrite(input_image, temp_image)
103
- # temp_mask = cv2.resize(combined_mask, (512, 512))
104
- temp_mask=combined_mask
105
- cv2.imwrite(input_mask, temp_mask)
106
-
107
-
108
- clean_image_path = process_image_with_model(input_image, input_mask, tester)
109
-
110
- # Check if the image was loaded correctly
111
- if clean_image_path is None:
112
- print(f"Failed to load image: {clean_image_path}")
113
- return # Or handle the error accordingly
114
- clean_image = cv2.imread(clean_image_path)
115
- clean_image = cv2.resize(clean_image, (combined_mask.shape[1], combined_mask.shape[0]))
116
- result_image = place_inpainted_back(image, clean_image, first_location)
117
- save_path=img_file_name(image_path)
118
- cv2.imwrite(save_path, result_image)
119
- return save_path
120
-
121
-
122
-
123
-
124
-
125
- # Define a function to handle the image editing and return the final result
126
- def process_and_return(im):
127
- global tester
128
- # Save the composite image (base image) and mask to files
129
- base_image_path = "base_image.png"
130
- mask_image_path = "mask_image.png"
131
-
132
- # Save the composite image (base image)
133
- imageio.imwrite(base_image_path, im["composite"])
134
-
135
- # Extract the alpha channel (mask)
136
- alpha_channel = im["layers"][0][:, :, 3]
137
-
138
- # Create the mask: white (255) where drawn, black (0) elsewhere
139
- mask = np.zeros_like(alpha_channel, dtype=np.uint8)
140
- mask[alpha_channel > 0] = 255 # Set drawn areas to white (255)
141
-
142
- # Save the mask image
143
- imageio.imwrite(mask_image_path, mask)
144
- # Process the images using the inpainting model
145
- final_result = process_image_with_model(base_image_path, mask_image_path,tester)
146
-
147
- # Return the processed image
148
- return final_result
149
-
150
- def ui_3():
151
- # Create a Gradio app
152
- with gr.Blocks() as demo:
153
- with gr.Row():
154
- # Create an ImageEditor component for uploading and editing the image
155
- im = gr.ImageEditor(
156
- type="numpy",
157
- canvas_size=(1, 1), # Use canvas_size instead of crop_size
158
- layers=True, # Allow layers in the editor
159
- transforms=["crop"], # Allow cropping
160
- format="png", # Save images in PNG format
161
- label="Base Image",
162
- show_label=True
163
- )
164
- # Create an Image component to display the processed result
165
- im2 = gr.Image(label="Processed Image", show_label=True)
166
-
167
- # Create a Button to trigger the image processing
168
- btn = gr.Button("Process Image")
169
-
170
- # Define an event listener to trigger the image processing when the button is clicked
171
- btn.click(process_and_return, inputs=im, outputs=im2) # Output processed image
172
- return demo
173
- # def handle_pil_image(image):
174
-
175
- # logo_remover(image)
176
-
177
-
178
- def ui_1():
179
- test_examples=[["./input/image.jpg"]]
180
- gradio_input=[gr.Image(label='Upload an Image',type="filepath")]
181
- gradio_Output=[gr.Image(label='Display Image')]
182
- gradio_interface = gr.Interface(fn=logo_remover, inputs=gradio_input,outputs=gradio_Output ,
183
- title="Meta Watermark Remover For Image",
184
- examples=test_examples)
185
- return gradio_interface
186
- from PIL import Image
187
- import zipfile
188
-
189
- def make_zip(image_list):
190
- zip_path = f"./temp/images/{uuid.uuid4().hex[:6]}.zip"
191
- with zipfile.ZipFile(zip_path, 'w') as zipf:
192
- for image in image_list:
193
- zipf.write(image, os.path.basename(image))
194
- return zip_path
195
-
196
- def handle_multiple_files(image_files):
197
- image_list = []
198
- if len(image_files) == 1:
199
- saved_path=logo_remover(image_files[0])
200
- return saved_path
201
- else:
202
- for image_path in image_files:
203
- saved_path=logo_remover(image_path)
204
- image_list.append(saved_path)
205
- zip_path = make_zip(image_list)
206
- return zip_path
207
-
208
-
209
-
210
- def ui_2():
211
- gradio_multiple_images = gr.Interface(
212
- handle_multiple_files,
213
- [gr.File(type='filepath', file_count='multiple',label='Upload Images')],
214
- [gr.File(label='Download File')],
215
- title='Meta Watermark Remover For Bulk Images',
216
- cache_examples=True
217
- )
218
- return gradio_multiple_images
219
-
220
- # Load and process the inpainting model
221
- tester = load_inpainting_model()
222
- image_folder="./temp/images"
223
- if not os.path.exists(image_folder):
224
- os.makedirs(image_folder)
225
-
226
- # Launch the Gradio app
227
- if __name__ == "__main__":
228
- demo2 = ui_1()
229
- demo3 = ui_2()
230
- demo1=ui_3()
231
- demo=gr.TabbedInterface([demo1,demo2,demo3], title="Meta Watermark Remover",tab_names=["Manual Remove","Meta Single Image","Meta Bulk Images"])
232
- demo.launch(show_error=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import numpy as np
3
+ import imageio
4
+ import cv2
5
+ import numpy as np
6
+ from inpaint import InpaintingTester
7
+ import os
8
+ import shutil
9
+ import re
10
+ import uuid
11
+
12
+ def create_mask(watermark, mask_type="white"):
13
+ """
14
+ Create a mask for the watermark region.
15
+ mask_type: 'white' for white mask and 'black' for black mask
16
+ """
17
+ h, w, _ = watermark.shape
18
+ if mask_type == "white":
19
+ return np.ones((h, w), dtype=np.uint8) * 255 # White mask
20
+ elif mask_type == "black":
21
+ return np.zeros((h, w), dtype=np.uint8) # Black mask
22
+ return None
23
+
24
+
25
+ def inpaint_watermark(watermark, mask):
26
+ """Inpaint the watermark region using the mask."""
27
+ return cv2.inpaint(watermark, mask, inpaintRadius=3, flags=cv2.INPAINT_TELEA)
28
+
29
+
30
+ def place_inpainted_back(image, inpainted_region, location):
31
+ """Place the inpainted region back into the original image."""
32
+ x_start, y_start, x_end, y_end = location
33
+ image[y_start:y_end, x_start:x_end] = inpainted_region
34
+ return image
35
+
36
+
37
+ def extract_watermark(image, height_ratio=0.15, width_ratio=0.15, margin=0):
38
+ """Extract watermark from the image using given ratios and margin."""
39
+ h, w, _ = image.shape
40
+ crop_h, crop_w = int(h * height_ratio), int(w * width_ratio)
41
+ x_start, y_start = w - crop_w, h - crop_h
42
+ watermark = image[y_start:h-margin, x_start:w-margin]
43
+ location = (x_start, y_start, w-margin, h-margin)
44
+ return watermark, location
45
+
46
+
47
+ def load_inpainting_model():
48
+ """Load the inpainting model."""
49
+ save_path = "./output"
50
+ # resize_to = None # Default size from config
51
+ resize_to = (480,480)
52
+ return InpaintingTester(save_path, resize_to)
53
+
54
+
55
+ def process_image_with_model(image_path, mask_path, tester):
56
+ """Process the image using the inpainting model and return the cleaned image path."""
57
+ image_mask_pairs = [(image_path, mask_path)]
58
+ return tester.process_multiple_images(image_mask_pairs)[0]
59
+
60
+
61
+
62
+
63
+
64
+ def img_file_name(image_path):
65
+ global image_folder
66
+ text=os.path.basename(image_path)
67
+ text=text.split(".")[0]
68
+ # Remove all non-alphabetic characters and convert to lowercase
69
+ text = re.sub(r'[^a-zA-Z\s]', '', text) # Retain only alphabets and spaces
70
+ text = text.lower().strip() # Convert to lowercase and strip leading/trailing spaces
71
+ text = text.replace(" ", "_") # Replace spaces with underscores
72
+
73
+ # Truncate or handle empty text
74
+ truncated_text = text[:25] if len(text) > 25 else text if len(text) > 0 else "empty"
75
+
76
+ # Generate a random string for uniqueness
77
+ random_string = uuid.uuid4().hex[:8].upper()
78
+
79
+ # Construct the file name
80
+ file_name = f"{image_folder}/{truncated_text}_{random_string}.png"
81
+ return file_name
82
+
83
+ def logo_remover(image_path):
84
+ image = cv2.imread(image_path)
85
+ image = cv2.resize(image, (1280, 1280)) # Resize image if needed
86
+
87
+ # Extract watermark and location
88
+ first_crop, first_location = extract_watermark(image, 0.50, 0.50, 0)
89
+ watermark, location = extract_watermark(first_crop, 0.12, 0.26, 27) #height, side, margin
90
+
91
+
92
+ # Create black and white masks
93
+ mask1 = create_mask(first_crop, "black")
94
+ mask2 = create_mask(watermark, "white")
95
+ combined_mask = place_inpainted_back(mask1, mask2, location)
96
+
97
+ # Save temporary files
98
+ input_image = "./input/temp.png"
99
+ input_mask = "./input/temp_mask.png"
100
+ # temp_image = cv2.resize(first_crop, (512, 512))
101
+ temp_image=first_crop
102
+ cv2.imwrite(input_image, temp_image)
103
+ # temp_mask = cv2.resize(combined_mask, (512, 512))
104
+ temp_mask=combined_mask
105
+ cv2.imwrite(input_mask, temp_mask)
106
+
107
+
108
+ clean_image_path = process_image_with_model(input_image, input_mask, tester)
109
+
110
+ # Check if the image was loaded correctly
111
+ if clean_image_path is None:
112
+ print(f"Failed to load image: {clean_image_path}")
113
+ return # Or handle the error accordingly
114
+ clean_image = cv2.imread(clean_image_path)
115
+ clean_image = cv2.resize(clean_image, (combined_mask.shape[1], combined_mask.shape[0]))
116
+ result_image = place_inpainted_back(image, clean_image, first_location)
117
+ save_path=img_file_name(image_path)
118
+ cv2.imwrite(save_path, result_image)
119
+ return save_path
120
+
121
+
122
+
123
+
124
+
125
+ # Define a function to handle the image editing and return the final result
126
+ def process_and_return(im):
127
+ global tester
128
+ # Save the composite image (base image) and mask to files
129
+ base_image_path = "base_image.png"
130
+ mask_image_path = "mask_image.png"
131
+
132
+ # Save the composite image (base image)
133
+ imageio.imwrite(base_image_path, im["composite"])
134
+
135
+ # Extract the alpha channel (mask)
136
+ alpha_channel = im["layers"][0][:, :, 3]
137
+
138
+ # Create the mask: white (255) where drawn, black (0) elsewhere
139
+ mask = np.zeros_like(alpha_channel, dtype=np.uint8)
140
+ mask[alpha_channel > 0] = 255 # Set drawn areas to white (255)
141
+
142
+ # Save the mask image
143
+ imageio.imwrite(mask_image_path, mask)
144
+ # Process the images using the inpainting model
145
+ final_result = process_image_with_model(base_image_path, mask_image_path,tester)
146
+
147
+ # Return the processed image
148
+ return final_result
149
+
150
+ def ui_3():
151
+ # Create a Gradio app
152
+ with gr.Blocks() as demo:
153
+ gr.Markdown("Manually Select the area.")
154
+ with gr.Row():
155
+ # Create an ImageEditor component for uploading and editing the image
156
+ im = gr.ImageEditor(
157
+ type="numpy",
158
+ canvas_size=(1, 1), # Use canvas_size instead of crop_size
159
+ layers=True, # Allow layers in the editor
160
+ transforms=["crop"], # Allow cropping
161
+ format="png", # Save images in PNG format
162
+ label="Base Image",
163
+ show_label=True
164
+ )
165
+ # Create an Image component to display the processed result
166
+ im2 = gr.Image(label="Processed Image", show_label=True)
167
+
168
+ # Create a Button to trigger the image processing
169
+ btn = gr.Button("Process Image")
170
+
171
+ # Define an event listener to trigger the image processing when the button is clicked
172
+ btn.click(process_and_return, inputs=im, outputs=im2) # Output processed image
173
+ return demo
174
+ # def handle_pil_image(image):
175
+
176
+ # logo_remover(image)
177
+
178
+
179
+ def ui_1():
180
+ test_examples=[["./input/image.jpg"]]
181
+ gradio_input=[gr.Image(label='Upload an Image',type="filepath")]
182
+ gradio_Output=[gr.Image(label='Display Image')]
183
+ gradio_interface = gr.Interface(fn=logo_remover, inputs=gradio_input,outputs=gradio_Output ,
184
+ title="Meta Watermark Remover For Single image",
185
+ examples=test_examples)
186
+ return gradio_interface
187
+ from PIL import Image
188
+ import zipfile
189
+
190
+ def make_zip(image_list):
191
+ zip_path = f"./temp/images/{uuid.uuid4().hex[:6]}.zip"
192
+ with zipfile.ZipFile(zip_path, 'w') as zipf:
193
+ for image in image_list:
194
+ zipf.write(image, os.path.basename(image))
195
+ return zip_path
196
+
197
+ def handle_multiple_files(image_files):
198
+ image_list = []
199
+ if len(image_files) == 1:
200
+ saved_path=logo_remover(image_files[0])
201
+ return saved_path
202
+ else:
203
+ for image_path in image_files:
204
+ saved_path=logo_remover(image_path)
205
+ image_list.append(saved_path)
206
+ zip_path = make_zip(image_list)
207
+ return zip_path
208
+
209
+
210
+
211
+ def ui_2():
212
+ gradio_multiple_images = gr.Interface(
213
+ handle_multiple_files,
214
+ [gr.File(type='filepath', file_count='multiple',label='Upload Images')],
215
+ [gr.File(label='Download File')],
216
+ title='Meta Watermark Remover For Bulk Images',
217
+ cache_examples=True
218
+ )
219
+ return gradio_multiple_images
220
+
221
+ # Load and process the inpainting model
222
+ tester = load_inpainting_model()
223
+ image_folder="./temp/images"
224
+ if not os.path.exists(image_folder):
225
+ os.makedirs(image_folder)
226
+
227
+ import click
228
+ @click.command()
229
+ @click.option("--debug", is_flag=True, default=False, help="Enable debug mode.")
230
+ @click.option("--share", is_flag=True, default=False, help="Enable sharing of the interface.")
231
+
232
+ def main(debug, share):
233
+ demo1 = ui_1()
234
+ demo2 = ui_2()
235
+ demo3=ui_3()
236
+ demo=gr.TabbedInterface([demo1,demo2,demo3], title="Meta Watermark Remover",tab_names=["Meta Single Image","Meta Bulk Images","Manual Remove"])
237
+ demo.queue().launch(debug=debug, share=share)#,server_port=9000)
238
+ #Run on local network
239
+ # laptop_ip="192.168.0.30"
240
+ # port=8080
241
+ # demo.queue().launch(debug=debug, share=share,server_name=laptop_ip,server_port=port)
242
+
243
+ if __name__ == "__main__":
244
+ main()
245
+