import os import sys # os.chdir("../") import gradio as gr import numpy as np from pathlib import Path from matplotlib import pyplot as plt import torch import tempfile from lama_inpaint import inpaint_img_with_lama, build_lama_model, inpaint_img_with_builded_lama from PIL import Image #sys.path.insert(0, str(Path(__file__).resolve().parent / "third_party" / "segment-anything")) import argparse import os import matplotlib.pyplot as plt from pylab import imshow, imsave import detectron2 from detectron2.utils.logger import setup_logger setup_logger() import numpy as np import cv2 import torch from detectron2 import model_zoo from detectron2.engine import DefaultPredictor from detectron2.config import get_cfg from detectron2.utils.visualizer import Visualizer, ColorMode from detectron2.data import MetadataCatalog coco_metadata = MetadataCatalog.get("coco_2017_val") # import PointRend project from detectron2_repo.projects.PointRend import point_rend title = "# PeopleRemover" description = """ In this space, you can remove the amount of people you want from a picture. ⚠️ This is just a demo version! """ def setup_args(parser): parser.add_argument( "--lama_config", type=str, default="./third_party/lama/configs/prediction/default.yaml", help="The path to the config file of lama model. " "Default: the config of big-lama", ) parser.add_argument( "--lama_ckpt", type=str, default="pretrained_models/big-lama", help="The path to the lama checkpoint.", ) def get_mask(img, num_people_keep, dilate_kernel_size): cfg = get_cfg() # Add PointRend-specific config point_rend.add_pointrend_config(cfg) # Load a config from file cfg.merge_from_file("detectron2_repo/projects/PointRend/configs/InstanceSegmentation/pointrend_rcnn_X_101_32x8d_FPN_3x_coco.yaml") cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5 # set threshold for this model # Set when using CPU cfg.MODEL.DEVICE='cpu' # Use a model from PointRend model zoo: https://github.com/facebookresearch/detectron2/tree/master/projects/PointRend#pretrained-models cfg.MODEL.WEIGHTS = "detectron2://PointRend/InstanceSegmentation/pointrend_rcnn_X_101_32x8d_FPN_3x_coco/28119989/model_final_ba17b9.pkl" predictor = DefaultPredictor(cfg) outputs = predictor(img) # Select 'people' instances people_instances = outputs["instances"][outputs["instances"].pred_classes == 0] # Eliminate the instances of the people we want to keep eliminate_instances = people_instances[num_people_keep:] # Generate mask blank_mask = np.ones((img.shape[0],img.shape[1]), dtype=np.uint8) * 255 full_mask = np.zeros((img.shape[0],img.shape[1]), dtype=np.uint8) * 255 for instance_mask in eliminate_instances.pred_masks: full_mask = full_mask + blank_mask*instance_mask.to("cpu").numpy() full_mask = full_mask.reshape((img.shape[0],img.shape[1],1)) mask = full_mask.astype(np.uint8) # Dilation kernel = np.ones((dilate_kernel_size, dilate_kernel_size), np.uint8) mask_dilation = cv2.dilate(mask, kernel, iterations=2) return mask_dilation def get_inpainted_img(img, mask): lama_config = args.lama_config device = "cuda" if torch.cuda.is_available() else "cpu" img_inpainted = inpaint_img_with_builded_lama( model['lama'], img, mask, lama_config, device=device) return img_inpainted def remove_people(img, num_people_keep, dilate_kernel_size): print('Obtaining mask...') mask = get_mask(img, num_people_keep, dilate_kernel_size) print('Mask obtained') print('Inpainting with LAMA...') out = get_inpainted_img(img, mask) print('Image Inpainted!') return out # get args parser = argparse.ArgumentParser() setup_args(parser) args = parser.parse_args(sys.argv[1:]) # build models model = {} # build the lama model lama_config = args.lama_config lama_ckpt = args.lama_ckpt device = "cuda" if torch.cuda.is_available() else "cpu" model['lama'] = build_lama_model(lama_config, lama_ckpt, device=device) with gr.Blocks() as demo: gr.Markdown(title) gr.Markdown(description) features = gr.State(None) with gr.Row(): with gr.Column(scale=1): img = gr.Image(height=300)# value="Input Image" .style(height="200px") num_people_keep = gr.Number(label="Number of people to keep", minimum=0, maximum=100) dilate_kernel_size = gr.Slider(label="Dilate Kernel Size", minimum=0, maximum=30, step=1, value=5) lama = gr.Button(value="Remove people", variant="primary", size="sm")#.style(full_width=True, size="sm") clear_button_image = gr.Button(value="Reset", variant="secondary", size="sm")#.style(full_width=True, size="sm") with gr.Column(scale=1): img_out = gr.Image(interactive=False,show_download_button=True)# value="Image with People Removed", type="numpy", .style(height="200px") #mask = gr.outputs.Image(type="numpy", label="Segmentation Mask")#.style(height="200px") lama.click( remove_people, [img, num_people_keep, dilate_kernel_size], [img_out] ) def reset(*args): return [None for _ in args] clear_button_image.click( reset, [img, features, img_out], [img, features, img_out] ) gr.Examples( examples=[[os.path.join(os.getcwd(), "examples/002.jpg"), 2, 15], [os.path.join(os.getcwd(), "examples/013.jpg"), 1, 15], [os.path.join(os.getcwd(), "examples/014.jpg"), 1, 15], [os.path.join(os.getcwd(), "examples/015.jpg"), 1, 25], [os.path.join(os.getcwd(), "examples/002.jpg"), 0, 15]], inputs=[img, num_people_keep, dilate_kernel_size], outputs=img_out, fn=remove_people, cache_examples=True, ) if __name__ == "__main__": demo.launch()