|
import gradio as gr |
|
import numpy as np |
|
import imageio |
|
import cv2 |
|
import numpy as np |
|
from inpaint import InpaintingTester |
|
import os |
|
import shutil |
|
import re |
|
import uuid |
|
|
|
def create_mask(watermark, mask_type="white"): |
|
""" |
|
Create a mask for the watermark region. |
|
mask_type: 'white' for white mask and 'black' for black mask |
|
""" |
|
h, w, _ = watermark.shape |
|
if mask_type == "white": |
|
return np.ones((h, w), dtype=np.uint8) * 255 |
|
elif mask_type == "black": |
|
return np.zeros((h, w), dtype=np.uint8) |
|
return None |
|
|
|
|
|
def inpaint_watermark(watermark, mask): |
|
"""Inpaint the watermark region using the mask.""" |
|
return cv2.inpaint(watermark, mask, inpaintRadius=3, flags=cv2.INPAINT_TELEA) |
|
|
|
|
|
def place_inpainted_back(image, inpainted_region, location): |
|
"""Place the inpainted region back into the original image.""" |
|
x_start, y_start, x_end, y_end = location |
|
image[y_start:y_end, x_start:x_end] = inpainted_region |
|
return image |
|
|
|
|
|
def extract_watermark(image, height_ratio=0.15, width_ratio=0.15, margin=0): |
|
"""Extract watermark from the image using given ratios and margin.""" |
|
h, w, _ = image.shape |
|
crop_h, crop_w = int(h * height_ratio), int(w * width_ratio) |
|
x_start, y_start = w - crop_w, h - crop_h |
|
watermark = image[y_start:h-margin, x_start:w-margin] |
|
location = (x_start, y_start, w-margin, h-margin) |
|
return watermark, location |
|
|
|
|
|
def load_inpainting_model(): |
|
"""Load the inpainting model.""" |
|
save_path = "./output" |
|
|
|
resize_to = (480,480) |
|
return InpaintingTester(save_path, resize_to) |
|
|
|
|
|
def process_image_with_model(image_path, mask_path, tester): |
|
"""Process the image using the inpainting model and return the cleaned image path.""" |
|
image_mask_pairs = [(image_path, mask_path)] |
|
return tester.process_multiple_images(image_mask_pairs)[0] |
|
|
|
|
|
|
|
|
|
|
|
def img_file_name(image_path): |
|
global image_folder |
|
text=os.path.basename(image_path) |
|
text=text.split(".")[0] |
|
|
|
text = re.sub(r'[^a-zA-Z\s]', '', text) |
|
text = text.lower().strip() |
|
text = text.replace(" ", "_") |
|
|
|
|
|
truncated_text = text[:25] if len(text) > 25 else text if len(text) > 0 else "empty" |
|
|
|
|
|
random_string = uuid.uuid4().hex[:8].upper() |
|
|
|
|
|
file_name = f"{image_folder}/{truncated_text}_{random_string}.png" |
|
return file_name |
|
|
|
def logo_remover(image_path): |
|
image = cv2.imread(image_path) |
|
image = cv2.resize(image, (1280, 1280)) |
|
|
|
|
|
first_crop, first_location = extract_watermark(image, 0.50, 0.50, 0) |
|
watermark, location = extract_watermark(first_crop, 0.12, 0.26, 27) |
|
|
|
|
|
|
|
mask1 = create_mask(first_crop, "black") |
|
mask2 = create_mask(watermark, "white") |
|
combined_mask = place_inpainted_back(mask1, mask2, location) |
|
|
|
|
|
input_image = "./input/temp.png" |
|
input_mask = "./input/temp_mask.png" |
|
|
|
temp_image=first_crop |
|
cv2.imwrite(input_image, temp_image) |
|
|
|
temp_mask=combined_mask |
|
cv2.imwrite(input_mask, temp_mask) |
|
|
|
|
|
clean_image_path = process_image_with_model(input_image, input_mask, tester) |
|
|
|
|
|
if clean_image_path is None: |
|
print(f"Failed to load image: {clean_image_path}") |
|
return |
|
clean_image = cv2.imread(clean_image_path) |
|
clean_image = cv2.resize(clean_image, (combined_mask.shape[1], combined_mask.shape[0])) |
|
result_image = place_inpainted_back(image, clean_image, first_location) |
|
save_path=img_file_name(image_path) |
|
cv2.imwrite(save_path, result_image) |
|
return save_path |
|
|
|
|
|
|
|
|
|
|
|
|
|
def process_and_return(im): |
|
global tester |
|
|
|
base_image_path = "base_image.png" |
|
mask_image_path = "mask_image.png" |
|
|
|
|
|
imageio.imwrite(base_image_path, im["composite"]) |
|
|
|
|
|
alpha_channel = im["layers"][0][:, :, 3] |
|
|
|
|
|
mask = np.zeros_like(alpha_channel, dtype=np.uint8) |
|
mask[alpha_channel > 0] = 255 |
|
|
|
|
|
imageio.imwrite(mask_image_path, mask) |
|
|
|
final_result = process_image_with_model(base_image_path, mask_image_path,tester) |
|
|
|
|
|
return final_result |
|
|
|
def ui_3(): |
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown("Manually Select the area.") |
|
with gr.Row(): |
|
|
|
im = gr.ImageEditor( |
|
type="numpy", |
|
canvas_size=(1, 1), |
|
layers=True, |
|
transforms=["crop"], |
|
format="png", |
|
label="Base Image", |
|
show_label=True |
|
) |
|
|
|
im2 = gr.Image(label="Processed Image", show_label=True) |
|
|
|
|
|
btn = gr.Button("Process Image") |
|
|
|
|
|
btn.click(process_and_return, inputs=im, outputs=im2) |
|
return demo |
|
|
|
|
|
|
|
|
|
|
|
def ui_1(): |
|
test_examples=[["./input/cat.jpg","./input/shark.jpg","./input/elephant.jpg"]] |
|
gradio_input=[gr.Image(label='Upload an Image',type="filepath")] |
|
gradio_Output=[gr.Image(label='Display Image')] |
|
gradio_interface = gr.Interface(fn=logo_remover, inputs=gradio_input,outputs=gradio_Output , |
|
title="Meta Watermark Remover For Single image", |
|
examples=test_examples) |
|
return gradio_interface |
|
from PIL import Image |
|
import zipfile |
|
|
|
def make_zip(image_list): |
|
zip_path = f"./temp/images/{uuid.uuid4().hex[:6]}.zip" |
|
with zipfile.ZipFile(zip_path, 'w') as zipf: |
|
for image in image_list: |
|
zipf.write(image, os.path.basename(image)) |
|
return zip_path |
|
|
|
def handle_multiple_files(image_files): |
|
image_list = [] |
|
if len(image_files) == 1: |
|
saved_path=logo_remover(image_files[0]) |
|
return saved_path |
|
else: |
|
for image_path in image_files: |
|
saved_path=logo_remover(image_path) |
|
image_list.append(saved_path) |
|
zip_path = make_zip(image_list) |
|
return zip_path |
|
|
|
|
|
|
|
def ui_2(): |
|
gradio_multiple_images = gr.Interface( |
|
handle_multiple_files, |
|
[gr.File(type='filepath', file_count='multiple',label='Upload Images')], |
|
[gr.File(label='Download File')], |
|
title='Meta Watermark Remover For Bulk Images', |
|
cache_examples=True |
|
) |
|
return gradio_multiple_images |
|
|
|
|
|
tester = load_inpainting_model() |
|
image_folder="./temp/images" |
|
if not os.path.exists(image_folder): |
|
os.makedirs(image_folder) |
|
|
|
import click |
|
@click.command() |
|
@click.option("--debug", is_flag=True, default=False, help="Enable debug mode.") |
|
@click.option("--share", is_flag=True, default=False, help="Enable sharing of the interface.") |
|
|
|
def main(debug, share): |
|
demo1 = ui_1() |
|
demo2 = ui_2() |
|
demo3=ui_3() |
|
demo=gr.TabbedInterface([demo1,demo2,demo3], title="Meta Watermark Remover",tab_names=["Meta Single Image","Meta Bulk Images","Manual Remove"]) |
|
demo.queue().launch(debug=debug, share=share) |
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
main() |
|
|
|
|