Commit c9430e53 authored by AUTOMATIC's avatar AUTOMATIC

loopback moved to scripts, added support for multiple batches, changed to...

loopback moved to scripts, added support for multiple batches, changed to honor save grids and how grids in web setting
parent c253d6bd
......@@ -11,10 +11,9 @@ from modules.ui import plaintext_to_html
import modules.images as images
import modules.scripts
def img2img(prompt: str, negative_prompt: str, prompt_style: str, init_img, init_img_with_mask, init_mask, mask_mode, steps: int, sampler_index: int, mask_blur: int, inpainting_fill: int, restore_faces: bool, tiling: bool, mode: int, n_iter: int, batch_size: int, cfg_scale: float, denoising_strength: float, denoising_strength_change_factor: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, height: int, width: int, resize_mode: int, upscaler_index: str, upscale_overlap: int, inpaint_full_res: bool, inpainting_mask_invert: int, *args):
def img2img(prompt: str, negative_prompt: str, prompt_style: str, init_img, init_img_with_mask, init_mask, mask_mode, steps: int, sampler_index: int, mask_blur: int, inpainting_fill: int, restore_faces: bool, tiling: bool, mode: int, n_iter: int, batch_size: int, cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, height: int, width: int, resize_mode: int, upscaler_index: str, upscale_overlap: int, inpaint_full_res: bool, inpainting_mask_invert: int, *args):
is_inpaint = mode == 1
is_loopback = mode == 2
is_upscale = mode == 3
is_upscale = mode == 2
if is_inpaint:
if mask_mode == 0:
......@@ -61,46 +60,10 @@ def img2img(prompt: str, negative_prompt: str, prompt_style: str, init_img, init
denoising_strength=denoising_strength,
inpaint_full_res=inpaint_full_res,
inpainting_mask_invert=inpainting_mask_invert,
extra_generation_params={
"Denoising strength change factor": (denoising_strength_change_factor if is_loopback else None)
}
)
print(f"\nimg2img: {prompt}", file=shared.progress_print_out)
if is_loopback:
output_images, info = None, None
history = []
initial_seed = None
initial_info = None
state.job_count = n_iter
for i in range(n_iter):
p.n_iter = 1
p.batch_size = 1
p.do_not_save_grid = True
state.job = f"Batch {i + 1} out of {n_iter}"
processed = process_images(p)
if initial_seed is None:
initial_seed = processed.seed
initial_info = processed.info
init_img = processed.images[0]
p.init_images = [init_img]
p.seed = processed.seed + 1
p.denoising_strength = min(max(p.denoising_strength * denoising_strength_change_factor, 0.1), 1)
history.append(processed.images[0])
grid = images.image_grid(history, batch_size, rows=1)
images.save_image(grid, p.outpath_grids, "grid", initial_seed, prompt, opts.grid_format, info=info, short_filename=not opts.grid_extended_filename, grid=True, p=p)
processed = Processed(p, history, initial_seed, initial_info)
elif is_upscale:
if is_upscale:
initial_info = None
processing.fix_seed(p)
......
......@@ -387,7 +387,7 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo):
with gr.Row().style(equal_height=False):
with gr.Column(variant='panel'):
with gr.Group():
switch_mode = gr.Radio(label='Mode', elem_id="img2img_mode", choices=['Redraw whole image', 'Inpaint a part of image', 'Loopback', 'SD upscale'], value='Redraw whole image', type="index", show_label=False)
switch_mode = gr.Radio(label='Mode', elem_id="img2img_mode", choices=['Redraw whole image', 'Inpaint a part of image', 'SD upscale'], value='Redraw whole image', type="index", show_label=False)
init_img = gr.Image(label="Image for img2img", source="upload", interactive=True, type="pil")
init_img_with_mask = gr.Image(label="Image for inpainting with mask", elem_id="img2maskimg", source="upload", interactive=True, type="pil", tool="sketch", visible=False, image_mode="RGBA")
init_mask = gr.Image(label="Mask", source="upload", interactive=True, type="pil", visible=False)
......@@ -421,7 +421,6 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo):
with gr.Group():
cfg_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='CFG Scale', value=7.0)
denoising_strength = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Denoising strength', value=0.75)
denoising_strength_change_factor = gr.Slider(minimum=0.9, maximum=1.1, step=0.01, label='Denoising strength change factor', value=1, visible=False)
with gr.Group():
width = gr.Slider(minimum=64, maximum=2048, step=64, label="Width", value=512)
......@@ -455,8 +454,7 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo):
def apply_mode(mode, uploadmask):
is_classic = mode == 0
is_inpaint = mode == 1
is_loopback = mode == 2
is_upscale = mode == 3
is_upscale = mode == 2
return {
init_img: gr_show(not is_inpaint or (is_inpaint and uploadmask == 1)),
......@@ -466,12 +464,10 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo):
mask_mode: gr_show(is_inpaint),
mask_blur: gr_show(is_inpaint),
inpainting_fill: gr_show(is_inpaint),
batch_size: gr_show(not is_loopback),
sd_upscale_upscaler_name: gr_show(is_upscale),
sd_upscale_overlap: gr_show(is_upscale),
inpaint_full_res: gr_show(is_inpaint),
inpainting_mask_invert: gr_show(is_inpaint),
denoising_strength_change_factor: gr_show(is_loopback),
img2img_interrogate: gr_show(not is_inpaint),
}
......@@ -486,12 +482,10 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo):
mask_mode,
mask_blur,
inpainting_fill,
batch_size,
sd_upscale_upscaler_name,
sd_upscale_overlap,
inpaint_full_res,
inpainting_mask_invert,
denoising_strength_change_factor,
img2img_interrogate,
]
)
......@@ -532,7 +526,6 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo):
batch_size,
cfg_scale,
denoising_strength,
denoising_strength_change_factor,
seed,
subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w,
height,
......
......@@ -13,7 +13,6 @@ titles = {
"Seed": "A value that determines the output of random number generator - if you create an image with same parameters and seed as another image, you'll get the same result",
"Inpaint a part of image": "Draw a mask over an image, and the script will regenerate the masked area with content according to prompt",
"Loopback": "Process an image, use it as an input, repeat. Batch count determins number of iterations.",
"SD upscale": "Upscale image normally, split result into tiles, improve each tile using img2img, merge whole image back",
"Just resize": "Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio.",
......@@ -58,6 +57,9 @@ titles = {
"Images filename pattern": "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_spaces], [width], [height], [sampler], [seed], [model_hash], [prompt_words], [date]; leave empty for default.",
"Directory name pattern": "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_spaces], [width], [height], [sampler], [seed], [model_hash], [prompt_words], [date]; leave empty for default.",
"Loopback": "Process an image, use it as an input, repeat.",
"Loops": "How many times to repeat processing an image and using it as input for the next iteration",
}
function gradioApp(){
......
import numpy as np
from tqdm import trange
import modules.scripts as scripts
import gradio as gr
from modules import processing, shared, sd_samplers, images
from modules.processing import Processed
from modules.sd_samplers import samplers
from modules.shared import opts, cmd_opts, state
class Script(scripts.Script):
def title(self):
return "Loopback"
def show(self, is_img2img):
return is_img2img
def ui(self, is_img2img):
loops = gr.Slider(minimum=1, maximum=32, step=1, label='Loops', value=4)
denoising_strength_change_factor = gr.Slider(minimum=0.9, maximum=1.1, step=0.01, label='Denoising strength change factor', value=1)
return [loops, denoising_strength_change_factor]
def run(self, p, loops, denoising_strength_change_factor):
processing.fix_seed(p)
batch_count = p.n_iter
p.extra_generation_params = {
"Denoising strength change factor": denoising_strength_change_factor,
}
p.batch_size = 1
p.n_iter = 1
output_images, info = None, None
initial_seed = None
initial_info = None
grids = []
all_images = []
state.job_count = loops * batch_count
for n in range(batch_count):
history = []
for i in range(loops):
p.n_iter = 1
p.batch_size = 1
p.do_not_save_grid = True
state.job = f"Iteration {i + 1}/{loops}, batch {n + 1}/{batch_count}"
processed = processing.process_images(p)
if initial_seed is None:
initial_seed = processed.seed
initial_info = processed.info
init_img = processed.images[0]
p.init_images = [init_img]
p.seed = processed.seed + 1
p.denoising_strength = min(max(p.denoising_strength * denoising_strength_change_factor, 0.1), 1)
history.append(processed.images[0])
grid = images.image_grid(history, rows=1)
if opts.grid_save:
images.save_image(grid, p.outpath_grids, "grid", initial_seed, p.prompt, opts.grid_format, info=info, short_filename=not opts.grid_extended_filename, grid=True, p=p)
grids.append(grid)
all_images += history
if opts.return_grid:
all_images = grids + all_images
processed = Processed(p, all_images, initial_seed, initial_info)
return processed
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment