mirror of
https://github.com/vladmandic/automatic
synced 2026-09-18 16:54:33 +02:00
xyz grid multi-resolution
This commit is contained in:
@@ -19,6 +19,9 @@
|
||||
- allow passing **processing args** directly:
|
||||
params are set directly on main processing object and can be known or new params
|
||||
example: `steps=10, steps=20; test=unknown`
|
||||
- enable working with different resolutions
|
||||
now you can adjust width/height in the grid just as any other param
|
||||
- renamed options to include section name and adjusted cost of each option
|
||||
- **interrogate**
|
||||
- add additional blip models: *blip-base, blip-large, blip-t5-xl, blip-t5-xxl, opt-2.7b, opt-6.7b*
|
||||
- change default params for better memory utilization
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import piexif
|
||||
import piexif.helper
|
||||
from PIL import Image, PngImagePlugin, ExifTags
|
||||
from modules import sd_samplers, shared, script_callbacks, errors, paths
|
||||
from modules.images_grid import image_grid, split_grid, combine_grid, check_grid_size, get_font, draw_grid_annotations, draw_prompt_matrix # pylint: disable=unused-import
|
||||
from modules.images_grid import image_grid, split_grid, combine_grid, check_grid_size, get_font, draw_grid_annotations, draw_prompt_matrix, GridAnnotation # pylint: disable=unused-import
|
||||
from modules.images_resize import resize_image # pylint: disable=unused-import
|
||||
from modules.images_namegen import FilenameGenerator
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ from PIL import Image, ImageFont, ImageDraw
|
||||
from modules import shared, script_callbacks
|
||||
|
||||
|
||||
Grid = namedtuple("Grid", ["tiles", "tile_w", "tile_h", "image_w", "image_h", "overlap"])
|
||||
|
||||
|
||||
def check_grid_size(imgs):
|
||||
mp = 0
|
||||
for img in imgs:
|
||||
@@ -34,16 +37,13 @@ def image_grid(imgs, batch_size=1, rows=None):
|
||||
imgs = [i for i in imgs if i is not None] if imgs is not None else []
|
||||
if len(imgs) == 0:
|
||||
return None
|
||||
w, h = imgs[0].size
|
||||
w, h = max(i.width for i in imgs), max(i.height for i in imgs)
|
||||
grid = Image.new('RGB', size=(params.cols * w, params.rows * h), color=shared.opts.grid_background)
|
||||
for i, img in enumerate(params.imgs):
|
||||
grid.paste(img, box=(i % params.cols * w, i // params.cols * h))
|
||||
return grid
|
||||
|
||||
|
||||
Grid = namedtuple("Grid", ["tiles", "tile_w", "tile_h", "image_w", "image_h", "overlap"])
|
||||
|
||||
|
||||
def split_grid(image, tile_w=512, tile_h=512, overlap=64):
|
||||
w = image.width
|
||||
h = image.height
|
||||
@@ -136,10 +136,10 @@ def draw_grid_annotations(im, width, height, hor_texts, ver_texts, margin=0, tit
|
||||
font = get_font(fontsize)
|
||||
color_inactive = (127, 127, 127)
|
||||
pad_left = 0 if sum([sum([len(line.text) for line in lines]) for lines in ver_texts]) == 0 else width * 3 // 4
|
||||
cols = im.width // width
|
||||
rows = im.height // height
|
||||
assert cols == len(hor_texts), f'bad number of horizontal texts: {len(hor_texts)}; must be {cols}'
|
||||
assert rows == len(ver_texts), f'bad number of vertical texts: {len(ver_texts)}; must be {rows}'
|
||||
cols = len(hor_texts)
|
||||
rows = len(ver_texts)
|
||||
# assert cols == len(hor_texts), f'bad number of horizontal texts: {len(hor_texts)}; must be {cols}'
|
||||
# assert rows == len(hor_texts), f'bad number of vertical texts: {len(ver_texts)}; must be {rows}'
|
||||
calc_img = Image.new("RGB", (1, 1), shared.opts.grid_background)
|
||||
calc_d = ImageDraw.Draw(calc_img)
|
||||
title_texts = [title] if title else [[GridAnnotation()]]
|
||||
|
||||
+33
-31
@@ -80,27 +80,30 @@ class SharedSettingsStackHelper(object):
|
||||
|
||||
axis_options = [
|
||||
AxisOption("Nothing", str, do_nothing, fmt=format_nothing),
|
||||
AxisOption("Prompt S/R", str, apply_prompt, fmt=format_value),
|
||||
AxisOption("Model", str, apply_checkpoint, fmt=format_value, cost=1.0, choices=lambda: sorted(sd_models.checkpoints_list)),
|
||||
AxisOption("UNET", str, apply_unet, cost=0.9, choices=lambda: ['None'] + list(sd_unet.unet_dict)),
|
||||
AxisOption("VAE", str, apply_vae, cost=0.7, choices=lambda: ['None'] + list(sd_vae.vae_dict)),
|
||||
AxisOption("LoRA", str, apply_lora, cost=0.5, choices=list_lora),
|
||||
AxisOption("LoRA strength", float, apply_setting('extra_networks_default_multiplier')),
|
||||
AxisOption("Text encoder", str, apply_te, cost=0.7, choices=shared_items.sd_te_items),
|
||||
AxisOption("Styles", str, apply_styles, choices=lambda: [s.name for s in shared.prompt_styles.styles.values()]),
|
||||
AxisOption("Seed", int, apply_field("seed")),
|
||||
AxisOption("Steps", int, apply_field("steps")),
|
||||
AxisOption("CFG scale", float, apply_field("cfg_scale")),
|
||||
AxisOption("Guidance end", float, apply_field("cfg_end")),
|
||||
AxisOption("Variation seed", int, apply_field("subseed")),
|
||||
AxisOption("Variation strength", float, apply_field("subseed_strength")),
|
||||
AxisOption("Clip skip", float, apply_clip_skip),
|
||||
AxisOption("Denoising strength", float, apply_field("denoising_strength")),
|
||||
AxisOption("Prompt order", str_permutations, apply_order, fmt=format_value_join_list),
|
||||
AxisOption("Model dictionary", str, apply_dict, fmt=format_value, cost=1.0, choices=lambda: ['None'] + list(sd_models.checkpoints_list)),
|
||||
AxisOption("Model args", str, apply_task_args),
|
||||
AxisOption("Processing args", str, apply_processing),
|
||||
AxisOptionImg2Img("Image mask weight", float, apply_field("inpainting_mask_weight")),
|
||||
AxisOption("[Model] Model", str, apply_checkpoint, cost=1.0, fmt=format_value, choices=lambda: sorted(sd_models.checkpoints_list)),
|
||||
AxisOption("[Model] UNET", str, apply_unet, cost=0.8, choices=lambda: ['None'] + list(sd_unet.unet_dict)),
|
||||
AxisOption("[Model] VAE", str, apply_vae, cost=0.6, choices=lambda: ['None'] + list(sd_vae.vae_dict)),
|
||||
AxisOption("[Model] Refiner", str, apply_refiner, cost=0.8, fmt=format_value, choices=lambda: ['None'] + sorted(sd_models.checkpoints_list)),
|
||||
AxisOption("[Model] Text encoder", str, apply_te, cost=0.7, choices=shared_items.sd_te_items),
|
||||
AxisOption("[Model] Dictionary", str, apply_dict, fmt=format_value, cost=0.9, choices=lambda: ['None'] + list(sd_models.checkpoints_list)),
|
||||
AxisOption("[Prompt] Search & replace", str, apply_prompt, fmt=format_value),
|
||||
AxisOption("[Prompt] Prompt order", str_permutations, apply_order, fmt=format_value_join_list),
|
||||
AxisOption("[Network] LoRA", str, apply_lora, cost=0.5, choices=list_lora),
|
||||
AxisOption("[Network] LoRA strength", float, apply_setting('extra_networks_default_multiplier')),
|
||||
AxisOption("[Network] Styles", str, apply_styles, choices=lambda: [s.name for s in shared.prompt_styles.styles.values()]),
|
||||
AxisOption("[Param] Width", int, apply_field("width")),
|
||||
AxisOption("[Param] Height", int, apply_field("height")),
|
||||
AxisOption("[Param] Seed", int, apply_field("seed")),
|
||||
AxisOption("[Param] Steps", int, apply_field("steps")),
|
||||
AxisOption("[Param] CFG scale", float, apply_field("cfg_scale")),
|
||||
AxisOption("[Param] Guidance end", float, apply_field("cfg_end")),
|
||||
AxisOption("[Param] Variation seed", int, apply_field("subseed")),
|
||||
AxisOption("[Param] Variation strength", float, apply_field("subseed_strength")),
|
||||
AxisOption("[Param] Clip skip", float, apply_clip_skip),
|
||||
AxisOption("[Param] Denoising strength", float, apply_field("denoising_strength")),
|
||||
AxisOptionImg2Img("[Param] Mask weight", float, apply_field("inpainting_mask_weight")),
|
||||
AxisOption("[Process] Model args", str, apply_task_args),
|
||||
AxisOption("[Process] Processing args", str, apply_processing),
|
||||
AxisOptionTxt2Img("[Sampler] Name", str, apply_sampler, fmt=format_value, confirm=confirm_samplers, choices=lambda: [x.name for x in sd_samplers.samplers]),
|
||||
AxisOptionImg2Img("[Sampler] Name", str, apply_sampler, fmt=format_value, confirm=confirm_samplers, choices=lambda: [x.name for x in sd_samplers.samplers_for_img2img]),
|
||||
AxisOption("[Sampler] Timestep spacing", str, apply_setting("schedulers_timestep_spacing"), choices=lambda: ['default', 'linspace', 'leading', 'trailing']),
|
||||
@@ -113,16 +116,15 @@ axis_options = [
|
||||
AxisOption("[Sampler] Shift", float, apply_setting("schedulers_shift")),
|
||||
AxisOption("[Sampler] ETA", float, apply_setting("scheduler_eta")),
|
||||
AxisOption("[Sampler] Solver order", int, apply_setting("schedulers_solver_order")),
|
||||
AxisOption("[Second pass] Upscaler", str, apply_field("hr_upscaler"), choices=lambda: [*shared.latent_upscale_modes, *[x.name for x in shared.sd_upscalers]]),
|
||||
AxisOption("[Second pass] Sampler", str, apply_hr_sampler_name, fmt=format_value, confirm=confirm_samplers, choices=lambda: [x.name for x in sd_samplers.samplers]),
|
||||
AxisOption("[Second pass] Denoising strength", float, apply_field("denoising_strength")),
|
||||
AxisOption("[Second pass] Hires steps", int, apply_field("hr_second_pass_steps")),
|
||||
AxisOption("[Second pass] CFG scale", float, apply_field("image_cfg_scale")),
|
||||
AxisOption("[Second pass] Guidance rescale", float, apply_field("diffusers_guidance_rescale")),
|
||||
AxisOption("[Refiner] Model", str, apply_refiner, fmt=format_value, cost=1.0, choices=lambda: ['None'] + sorted(sd_models.checkpoints_list)),
|
||||
AxisOption("[Refiner] Refiner start", float, apply_field("refiner_start")),
|
||||
AxisOption("[Refiner] Refiner steps", float, apply_field("refiner_steps")),
|
||||
AxisOption("[Postprocess] Upscaler", str, apply_upscaler, choices=lambda: [x.name for x in shared.sd_upscalers][1:]),
|
||||
AxisOption("[Refine] Upscaler", str, apply_field("hr_upscaler"), cost=0.3, choices=lambda: [*shared.latent_upscale_modes, *[x.name for x in shared.sd_upscalers]]),
|
||||
AxisOption("[Refine] Sampler", str, apply_hr_sampler_name, fmt=format_value, confirm=confirm_samplers, choices=lambda: [x.name for x in sd_samplers.samplers]),
|
||||
AxisOption("[Refine] Denoising strength", float, apply_field("denoising_strength")),
|
||||
AxisOption("[Refine] Hires steps", int, apply_field("hr_second_pass_steps")),
|
||||
AxisOption("[Refine] CFG scale", float, apply_field("image_cfg_scale")),
|
||||
AxisOption("[Refine] Guidance rescale", float, apply_field("diffusers_guidance_rescale")),
|
||||
AxisOption("[Refine] Refiner start", float, apply_field("refiner_start")),
|
||||
AxisOption("[Refine] Refiner steps", float, apply_field("refiner_steps")),
|
||||
AxisOption("[Postprocess] Upscaler", str, apply_upscaler, cost=0.4, choices=lambda: [x.name for x in shared.sd_upscalers][1:]),
|
||||
AxisOption("[Postprocess] Context", str, apply_context, choices=lambda: ["Add with forward", "Remove with forward", "Add with backward", "Remove with backward"]),
|
||||
AxisOption("[Postprocess] Face restore", str, apply_face_restore, fmt=format_value),
|
||||
AxisOption("[HDR] Mode", int, apply_field("hdr_mode")),
|
||||
|
||||
@@ -85,21 +85,24 @@ def draw_xyz_grid(p, xs, ys, zs, x_labels, y_labels, z_labels, cell, draw_legend
|
||||
for i in range(z_count):
|
||||
start_index = (i * len(xs) * len(ys)) + i
|
||||
end_index = start_index + len(xs) * len(ys)
|
||||
w, h = max(i.width for i in processed_result.images[start_index:end_index]), max(i.height for i in processed_result.images[start_index:end_index])
|
||||
print('HERE', w, h, z_count)
|
||||
if (not no_grid or include_sub_grids) and images.check_grid_size(processed_result.images[start_index:end_index]):
|
||||
grid = images.image_grid(processed_result.images[start_index:end_index], rows=len(ys))
|
||||
if draw_legend:
|
||||
grid = images.draw_grid_annotations(grid, processed_result.images[start_index].size[0], processed_result.images[start_index].size[1], hor_texts, ver_texts, margin_size, title=title_texts[i])
|
||||
grid = images.draw_grid_annotations(grid, w, h, hor_texts, ver_texts, margin_size, title=title_texts[i])
|
||||
processed_result.images.insert(i, grid)
|
||||
processed_result.all_prompts.insert(i, processed_result.all_prompts[start_index])
|
||||
processed_result.all_seeds.insert(i, processed_result.all_seeds[start_index])
|
||||
processed_result.infotexts.insert(i, processed_result.infotexts[start_index])
|
||||
sub_grid_size = processed_result.images[0].size
|
||||
"""
|
||||
if not no_grid and images.check_grid_size(processed_result.images[:z_count]):
|
||||
z_grid = images.image_grid(processed_result.images[:z_count], rows=1)
|
||||
if draw_legend:
|
||||
z_grid = images.draw_grid_annotations(z_grid, sub_grid_size[0], sub_grid_size[1], [[images.GridAnnotation()] for _ in z_labels], [[images.GridAnnotation()]])
|
||||
z_grid = images.draw_grid_annotations(z_grid, w, h, [[images.GridAnnotation()] for _ in z_labels], [[images.GridAnnotation()]])
|
||||
processed_result.images.insert(0, z_grid)
|
||||
#processed_result.all_prompts.insert(0, processed_result.all_prompts[0])
|
||||
#processed_result.all_seeds.insert(0, processed_result.all_seeds[0])
|
||||
processed_result.infotexts.insert(0, processed_result.infotexts[0])
|
||||
processed_result.all_prompts.insert(0, processed_result.all_prompts[0])
|
||||
processed_result.all_seeds.insert(0, processed_result.all_seeds[0])
|
||||
processed_result.infotexts.insert(0, processed_result.infotexts[0])
|
||||
"""
|
||||
return processed_result
|
||||
|
||||
Reference in New Issue
Block a user