|
|
import random |
|
|
import modules.scripts as scripts |
|
|
from modules import images |
|
|
from modules.processing import process_images, Processed |
|
|
from modules.processing import Processed |
|
|
from modules.shared import opts, cmd_opts, state |
|
|
|
|
|
import gradio as gr |
|
|
import huggingface_hub |
|
|
import onnxruntime as rt |
|
|
import copy |
|
|
import numpy as np |
|
|
import cv2 |
|
|
from PIL import Image as im, ImageDraw |
|
|
|
|
|
|
|
|
|
|
|
providers = ['CUDAExecutionProvider', 'CPUExecutionProvider'] |
|
|
|
|
|
|
|
|
model_path = huggingface_hub.hf_hub_download( |
|
|
"skytnt/anime-seg", "isnetis.onnx") |
|
|
rmbg_model = rt.InferenceSession(model_path, providers=providers) |
|
|
|
|
|
|
|
|
def get_mask(img, s=1024): |
|
|
|
|
|
|
|
|
img = (img / 255).astype(np.float32) |
|
|
|
|
|
dim = img.shape[2] |
|
|
|
|
|
if dim == 4: |
|
|
img = img[..., :3] |
|
|
dim = 3 |
|
|
|
|
|
h, w = h0, w0 = img.shape[:-1] |
|
|
|
|
|
|
|
|
h, w = (s, int(s * w / h)) if h > w else (int(s * h / w), s) |
|
|
|
|
|
ph, pw = s - h, s - w |
|
|
|
|
|
img_input = np.zeros([s, s, dim], dtype=np.float32) |
|
|
|
|
|
img_input[ph // 2:ph // 2 + h, pw // |
|
|
2:pw // 2 + w] = cv2.resize(img, (w, h)) |
|
|
|
|
|
img_input = np.transpose(img_input, (2, 0, 1)) |
|
|
|
|
|
img_input = img_input[np.newaxis, :] |
|
|
|
|
|
mask = rmbg_model.run(None, {'img': img_input})[0][0] |
|
|
|
|
|
mask = np.transpose(mask, (1, 2, 0)) |
|
|
|
|
|
mask = mask[ph // 2:ph // 2 + h, pw // 2:pw // 2 + w] |
|
|
|
|
|
mask = cv2.resize(mask, (w0, h0))[:, :, np.newaxis] |
|
|
return mask |
|
|
|
|
|
|
|
|
def rmbg_fn(img): |
|
|
|
|
|
mask = get_mask(img) |
|
|
|
|
|
img = (mask * img + 255 * (1 - mask)).astype(np.uint8) |
|
|
|
|
|
mask = (mask * 255).astype(np.uint8) |
|
|
|
|
|
img = np.concatenate([img, mask], axis=2, dtype=np.uint8) |
|
|
|
|
|
mask = mask.repeat(3, axis=2) |
|
|
return mask, img |
|
|
|
|
|
|
|
|
class Script(scripts.Script): |
|
|
is_txt2img = False |
|
|
|
|
|
|
|
|
def title(self): |
|
|
return "ABG Remover" |
|
|
|
|
|
def ui(self, is_img2img): |
|
|
|
|
|
with gr.Column(): |
|
|
only_save_background_free_pictures = gr.Checkbox( |
|
|
label='Only save background free pictures') |
|
|
do_not_auto_save = gr.Checkbox(label='Do not auto save') |
|
|
with gr.Row(): |
|
|
custom_background = gr.Checkbox(label='Custom Background') |
|
|
custom_background_color = gr.ColorPicker( |
|
|
label='Background Color', default='#ff0000') |
|
|
custom_background_random = gr.Checkbox( |
|
|
label='Random Custom Background') |
|
|
|
|
|
return [only_save_background_free_pictures, do_not_auto_save, custom_background, custom_background_color, custom_background_random] |
|
|
|
|
|
|
|
|
def show(self, is_img2img): |
|
|
return True |
|
|
|
|
|
|
|
|
def run(self, p, only_save_background_free_pictures, do_not_auto_save, custom_background, custom_background_color, custom_background_random): |
|
|
|
|
|
if only_save_background_free_pictures: |
|
|
p.do_not_save_samples = True |
|
|
|
|
|
|
|
|
proc = process_images(p) |
|
|
|
|
|
has_grid = False |
|
|
|
|
|
unwanted_grid_because_of_img_count = len( |
|
|
proc.images) < 2 and opts.grid_only_if_multiple |
|
|
if (opts.return_grid or opts.grid_save) and not p.do_not_save_grid and not unwanted_grid_because_of_img_count: |
|
|
has_grid = True |
|
|
|
|
|
|
|
|
for i in range(len(proc.images)): |
|
|
|
|
|
nmask, nimg = rmbg_fn(np.array(proc.images[i])) |
|
|
|
|
|
|
|
|
num_channels = nimg.shape[2] |
|
|
if num_channels > 4: |
|
|
nimg = nimg[:, :, :4] |
|
|
|
|
|
|
|
|
nimg = nimg.astype(np.uint8) |
|
|
img = im.fromarray(nimg) |
|
|
|
|
|
|
|
|
if custom_background or custom_background_random: |
|
|
|
|
|
if custom_background_random: |
|
|
custom_background_color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) |
|
|
|
|
|
|
|
|
background = im.new('RGBA', img.size, custom_background_color) |
|
|
|
|
|
|
|
|
draw = ImageDraw.Draw(background) |
|
|
draw.rectangle([(0, 0), img.size], |
|
|
fill=custom_background_color) |
|
|
|
|
|
|
|
|
img = im.alpha_composite(background, img) |
|
|
|
|
|
|
|
|
outpath = p.outpath_grids if has_grid and i == 0 else p.outpath_samples |
|
|
|
|
|
|
|
|
if not only_save_background_free_pictures: |
|
|
mask = im.fromarray(nmask) |
|
|
|
|
|
if not do_not_auto_save: |
|
|
|
|
|
images.save_image( |
|
|
mask, outpath, "mask_", proc.seed + i, proc.prompt, "png", info=proc.info, p=p) |
|
|
images.save_image( |
|
|
img, outpath, "img_", proc.seed + i, proc.prompt, "png", info=proc.info, p=p) |
|
|
|
|
|
proc.images.append(mask) |
|
|
proc.images.append(img) |
|
|
|
|
|
else: |
|
|
proc.images[i] = img |
|
|
|
|
|
|
|
|
if not do_not_auto_save: |
|
|
|
|
|
if has_grid and i == 0: |
|
|
|
|
|
images.save_image(img, p.outpath_grids, "grid", p.all_seeds[0], p.all_prompts[0], |
|
|
opts.grid_format, info=proc.info, short_filename=not opts.grid_extended_filename, p=p) |
|
|
else: |
|
|
|
|
|
images.save_image(img, outpath, "", proc.seed, |
|
|
proc.prompt, "png", info=proc.info, p=p) |
|
|
|
|
|
|
|
|
return proc |
|
|
|