An extension for stable-diffusion-webui to remove any object.
import launch

# TODO: add pip dependency if need extra module only on extension

if not launch.is_installed("litelama"):    
    launch.run_pip("install litelama==0.1.7")
    
install.py
novitalabs/sd-webui-cleaner
from fastapi import FastAPI, Body

from modules.api.models import *
from modules.api import api
import gradio as gr

from scripts import lama
from modules.shared import opts,OptionInfo



def cleanup_api(_: gr.Blocks, app: FastAPI):

    @app.post("/cleanup")
    def clean_up(
        input_image: str = Body("", title='cleanup input image'),
        mask: str = Body("", title='clean up mask')
    ):

        _image = api.decode_base64_to_image(input_image)
        _mask = api.decode_base64_to_image(mask)
        
        _output = lama.clean_object(_image,_mask)
        
        if len(_output) > 0:
            return {"code": 0, "message":"ok", "image":  api.encode_pil_to_base64(_output[0]).decode("utf-8")}
        else:
            return {"code": -1, "message":"Image generation failed"}


try:
    import modules.script_callbacks as script_callbacks

    script_callbacks.on_app_started(cleanup_api)
except:
    pass

scripts/api.py
novitalabs/sd-webui-cleaner
import modules.scripts as scripts
import gradio as gr

from modules.shared import opts,OptionInfo

from modules import script_callbacks
from modules.ui_components import ToolButton, ResizeHandleRow
import modules.generation_parameters_copypaste as parameters_copypaste
from modules.ui_common import save_files

from scripts import lama


def on_ui_settings():
    section = ('cleaner', "Cleaner")
    opts.add_option("cleaner_use_gpu", OptionInfo(True, "Is Use GPU", gr.Checkbox, {"interactive": True}, section=section))

def on_ui_tabs():
    

        
    with gr.Blocks() as object_cleaner_tab:

        for tab_name in ["Clean up", "Clean up upload"]:

            with gr.Tab(tab_name) as clean_up_tab, ResizeHandleRow(equal_height=False):

                init_img_with_mask = None
                clean_up_init_img = None
                clean_up_init_mask = None

                if tab_name == "Clean up":
                    init_img_with_mask = gr.Image(label="Image for clean up with mask", show_label=False, elem_id="img2maskimg", source="upload",
                                                  interactive=True, type="pil", tool="sketch", image_mode="RGBA", height=650, brush_color=opts.img2img_inpaint_mask_brush_color)
                else:
                    with gr.Column(elem_id=f"cleanup_image_mask"):
                        clean_up_init_img = gr.Image(label="Image for cleanup", show_label=False, source="upload",
                                                     interactive=True, type="pil", elem_id="img_inpaint_base", height=325)
                        clean_up_init_mask = gr.Image(
                            label="Mask", source="upload", interactive=True, type="pil", image_mode="RGBA", elem_id="img_inpaint_mask", height=325)

                with gr.Row():

                    with gr.Column(elem_id=f"cleanup_gallery_container"):

                        clean_button = gr.Button("Clean Up", height=100)
                        result_gallery = gr.Gallery(
                            label='Output', show_label=False, elem_id=f"cleanup_gallery", preview=True, height=512)

                        with gr.Row(elem_id=f"image_buttons", elem_classes="image-buttons"):

                            buttons = {
                                'img2img': ToolButton('🖼️', elem_id=f'_send_to_img2img', tooltip="Send image and generation parameters to img2img tab."),
                                'inpaint': ToolButton('🎨️', elem_id=f'_send_to_inpaint', tooltip="Send image and generation parameters to img2img inpaint tab."),
                                'extras': ToolButton('📐', elem_id=f'_send_to_extras', tooltip="Send image and generation parameters to extras tab.")
                            }

                            for paste_tabname, paste_button in buttons.items():
                                parameters_copypaste.register_paste_params_button(parameters_copypaste.ParamBinding(
                                    paste_button=paste_button, tabname=paste_tabname, source_tabname=None, source_image_component=result_gallery,
                                    paste_field_names=[]
                                ))
                        

                        if tab_name == "Clean up":
                            clean_button.click(
                                fn=lama.clean_object_init_img_with_mask,
                                inputs=[init_img_with_mask],
                                outputs=[
                                    result_gallery
                                ],
                            )
                        else:

                            clean_button.click(
                                fn=lama.clean_object,
                                inputs=[clean_up_init_img, clean_up_init_mask],
                                outputs=[
                                    result_gallery
                                ],
                            )

    return (object_cleaner_tab, "Cleaner", "cleaner_tab"),


script_callbacks.on_ui_tabs(on_ui_tabs)
script_callbacks.on_ui_settings(on_ui_settings)


scripts/clean_up_tab.py
novitalabs/sd-webui-cleaner
from litelama import LiteLama
from litelama.model import download_file
import os
import gradio as gr
from fastapi import FastAPI, Body
from modules.shared import opts


EXTENSION_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MODEL_PATH = os.path.join(EXTENSION_PATH, "models")


def clean_object_init_img_with_mask(init_img_with_mask):
    return clean_object(init_img_with_mask['image'],init_img_with_mask['mask'])


def clean_object(image,mask):
    
    Lama = LiteLama2()
    
    init_image = image
    mask_image = mask

    init_image = init_image.convert("RGB")
    mask_image = mask_image.convert("RGB")

    device_used = opts.data.get("cleaner_use_gpu",True)

    device = "cuda:0"
    if not device_used:
        device = "cpu"

    result = None
    try:
        Lama.to(device)
        result = Lama.predict(init_image, mask_image)
    except:
        pass
    finally:
        Lama.to("cpu")
    
    return [result]


class LiteLama2(LiteLama):
    
    _instance = None
    
    def __new__(cls, *args, **kw):
        if cls._instance is None:
            cls._instance = object.__new__(cls, *args, **kw)
        return cls._instance
        
    def __init__(self, checkpoint_path=None, config_path=None):
        self._checkpoint_path = checkpoint_path
        self._config_path = config_path
        self._model = None
        
        if self._checkpoint_path is None:
            
            checkpoint_path = os.path.join(MODEL_PATH, "big-lama.safetensors")
            if  os.path.exists(checkpoint_path) and os.path.isfile(checkpoint_path):
                pass
            else:
                download_file("https://huggingface.co/anyisalin/big-lama/resolve/main/big-lama.safetensors", checkpoint_path)
                
            self._checkpoint_path = checkpoint_path
        
        self.load(location="cpu")

scripts/lama.py
novitalabs/sd-webui-cleaner