From e1c44267ea239d0903202c41f9e75c864e31227f Mon Sep 17 00:00:00 2001 From: ArthurHeitmann <37270165+ArthurHeitmann@users.noreply.github.com> Date: Mon, 22 May 2023 21:56:26 +0200 Subject: Fix for #10643 (pixel noise in webui inpainting canvas breaking inpainting, so that it behaves like plain img2img) --- modules/img2img.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'modules/img2img.py') diff --git a/modules/img2img.py b/modules/img2img.py index d704bf90..4c12c2c5 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -92,7 +92,8 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s elif mode == 2: # inpaint image, mask = init_img_with_mask["image"], init_img_with_mask["mask"] alpha_mask = ImageOps.invert(image.split()[-1]).convert('L').point(lambda x: 255 if x > 0 else 0, mode='1') - mask = ImageChops.lighter(alpha_mask, mask.convert('L')).convert('L') + mask = mask.convert('L').point(lambda x: 255 if x > 128 else 0, mode='1') + mask = ImageChops.lighter(alpha_mask, mask).convert('L') image = image.convert("RGB") elif mode == 3: # inpaint sketch image = inpaint_color_sketch -- cgit v1.2.1 From c8e67b67320f5d090b758303e675c1e5586575a5 Mon Sep 17 00:00:00 2001 From: Artem Kotov Date: Mon, 29 May 2023 20:39:24 +0400 Subject: improve filename matching for mask we should not rely that mask filename will be of the same extension as the image filename so better pattern matching is added --- modules/img2img.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'modules/img2img.py') diff --git a/modules/img2img.py b/modules/img2img.py index d704bf90..bc79ea1f 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -1,4 +1,5 @@ import os +from pathlib import Path import numpy as np from PIL import Image, ImageOps, ImageFilter, ImageEnhance, ImageChops, UnidentifiedImageError @@ -53,7 +54,11 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args): if is_inpaint_batch: # try to find corresponding mask for an image using simple filename matching - mask_image_path = os.path.join(inpaint_mask_dir, os.path.basename(image)) + path = Path(os.path.join(inpaint_mask_dir, os.path.basename(image))) + mask_image_path = list(path.parent.glob(f"**/{path.stem}*")) + if len(mask_image_path) > 0: + mask_image_path = str(mask_image_path[0]) + # if not found use first one ("same mask for all images" use-case) if mask_image_path not in inpaint_masks: mask_image_path = inpaint_masks[0] -- cgit v1.2.1 From 6c610a8a951ea8141024dbb659c2528bf24225ec Mon Sep 17 00:00:00 2001 From: Artem Kotov Date: Mon, 29 May 2023 20:47:20 +0400 Subject: add scale_by to batch processing --- modules/img2img.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'modules/img2img.py') diff --git a/modules/img2img.py b/modules/img2img.py index bc79ea1f..5d6ad520 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -14,7 +14,7 @@ from modules.ui import plaintext_to_html import modules.scripts -def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args): +def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args, to_scale=False, scale_by=1.0): processing.fix_seed(p) images = shared.listfiles(input_dir) @@ -50,6 +50,11 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args): continue # Use the EXIF orientation of photos taken by smartphones. img = ImageOps.exif_transpose(img) + + if to_scale: + p.width = int(img.width * scale_by) + p.height = int(img.height * scale_by) + p.init_images = [img] * p.batch_size if is_inpaint_batch: @@ -119,7 +124,7 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s if image is not None: image = ImageOps.exif_transpose(image) - if selected_scale_tab == 1: + if selected_scale_tab == 1 and not is_batch: assert image, "Can't scale by because no image is selected" width = int(image.width * scale_by) @@ -174,7 +179,7 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s if is_batch: assert not shared.cmd_opts.hide_ui_dir_config, "Launched with --hide-ui-dir-config, batch img2img disabled" - process_batch(p, img2img_batch_input_dir, img2img_batch_output_dir, img2img_batch_inpaint_mask_dir, args) + process_batch(p, img2img_batch_input_dir, img2img_batch_output_dir, img2img_batch_inpaint_mask_dir, args, to_scale=selected_scale_tab == 1, scale_by=scale_by) processed = Processed(p, [], p.seed, "") else: -- cgit v1.2.1 From 23314a6e27a24fc8bf98717ddc180aec06674abd Mon Sep 17 00:00:00 2001 From: Artem Kotov Date: Mon, 29 May 2023 21:38:49 +0400 Subject: ruffed --- modules/img2img.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'modules/img2img.py') diff --git a/modules/img2img.py b/modules/img2img.py index 5d6ad520..a29add3a 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -50,11 +50,11 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args, to_scale=Fal continue # Use the EXIF orientation of photos taken by smartphones. img = ImageOps.exif_transpose(img) - + if to_scale: p.width = int(img.width * scale_by) p.height = int(img.height * scale_by) - + p.init_images = [img] * p.batch_size if is_inpaint_batch: @@ -63,7 +63,7 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args, to_scale=Fal mask_image_path = list(path.parent.glob(f"**/{path.stem}*")) if len(mask_image_path) > 0: mask_image_path = str(mask_image_path[0]) - + # if not found use first one ("same mask for all images" use-case) if mask_image_path not in inpaint_masks: mask_image_path = inpaint_masks[0] -- cgit v1.2.1 From 49f4b4be67fa97306f99a461dc76de901d7499d2 Mon Sep 17 00:00:00 2001 From: Artem Kotov Date: Thu, 1 Jun 2023 11:29:56 +0400 Subject: add subdir support for images, masks and output; search mask only in subdir --- modules/img2img.py | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'modules/img2img.py') diff --git a/modules/img2img.py b/modules/img2img.py index a29add3a..abf7960f 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -17,11 +17,12 @@ import modules.scripts def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args, to_scale=False, scale_by=1.0): processing.fix_seed(p) - images = shared.listfiles(input_dir) + allowed_extensions = [ext for ext, f in Image.registered_extensions().items() if f in Image.OPEN] + images = list(shared.walk_files(input_dir, allowed_extensions=allowed_extensions)) is_inpaint_batch = False if inpaint_mask_dir: - inpaint_masks = shared.listfiles(inpaint_mask_dir) + inpaint_masks = list(shared.walk_files(inpaint_mask_dir, allowed_extensions=allowed_extensions)) is_inpaint_batch = len(inpaint_masks) > 0 if is_inpaint_batch: print(f"\nInpaint batch is enabled. {len(inpaint_masks)} masks found.") @@ -57,16 +58,28 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args, to_scale=Fal p.init_images = [img] * p.batch_size + image_path = Path(image) + if image_path.parent == Path(input_dir): + image_subpath = "" + else: + image_subpath = str(image_path.parent).replace(f"{input_dir}/", "") + if is_inpaint_batch: # try to find corresponding mask for an image using simple filename matching - path = Path(os.path.join(inpaint_mask_dir, os.path.basename(image))) - mask_image_path = list(path.parent.glob(f"**/{path.stem}*")) - if len(mask_image_path) > 0: - mask_image_path = str(mask_image_path[0]) - - # if not found use first one ("same mask for all images" use-case) - if mask_image_path not in inpaint_masks: + if len(inpaint_masks) == 1: mask_image_path = inpaint_masks[0] + else: + # try to find corresponding mask for an image using simple filename matching + mask_image_dir = Path(inpaint_mask_dir).joinpath(image_subpath) + masks_found = list(mask_image_dir.glob(f"{image_path.stem}.*")) + + if len(masks_found) == 0: + raise ValueError(f"Mask is not found for {image_path} in {mask_image_dir}") + + # it should contain only 1 matching mask + # otherwise user has many masks with the same name but different extensions + mask_image_path = masks_found[0] + mask_image = Image.open(mask_image_path) p.image_mask = mask_image @@ -75,17 +88,17 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args, to_scale=Fal proc = process_images(p) for n, processed_image in enumerate(proc.images): - filename = os.path.basename(image) + filename = image_path.name if n > 0: left, right = os.path.splitext(filename) filename = f"{left}-{n}{right}" if not save_normally: - os.makedirs(output_dir, exist_ok=True) + os.makedirs(os.path.join(output_dir, image_subpath), exist_ok=True) if processed_image.mode == 'RGBA': processed_image = processed_image.convert("RGB") - processed_image.save(os.path.join(output_dir, filename)) + processed_image.save(os.path.join(output_dir, image_subpath, filename)) def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_styles, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_index: int, mask_blur: int, mask_alpha: float, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, selected_scale_tab: int, height: int, width: int, scale_by: float, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, *args): -- cgit v1.2.1 From ba110bf09302ec6aed10a69016d96912e39c7c05 Mon Sep 17 00:00:00 2001 From: Artem Kotov Date: Thu, 1 Jun 2023 15:44:55 +0400 Subject: fallback to original file retrieving; skip img if mask not found usage of `shared.walk_files` breaks controlnet extension images are processed in different order which leads to unmatched img file used for img2img and img file used for controlnet (if no folder is specified for control net or the same as img2img input dir used for it) --- modules/img2img.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'modules/img2img.py') diff --git a/modules/img2img.py b/modules/img2img.py index abf7960f..3af6dac8 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -17,12 +17,11 @@ import modules.scripts def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args, to_scale=False, scale_by=1.0): processing.fix_seed(p) - allowed_extensions = [ext for ext, f in Image.registered_extensions().items() if f in Image.OPEN] - images = list(shared.walk_files(input_dir, allowed_extensions=allowed_extensions)) + images = shared.listfiles(input_dir) is_inpaint_batch = False if inpaint_mask_dir: - inpaint_masks = list(shared.walk_files(inpaint_mask_dir, allowed_extensions=allowed_extensions)) + inpaint_masks = shared.listfiles(inpaint_mask_dir) is_inpaint_batch = len(inpaint_masks) > 0 if is_inpaint_batch: print(f"\nInpaint batch is enabled. {len(inpaint_masks)} masks found.") @@ -59,22 +58,18 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args, to_scale=Fal p.init_images = [img] * p.batch_size image_path = Path(image) - if image_path.parent == Path(input_dir): - image_subpath = "" - else: - image_subpath = str(image_path.parent).replace(f"{input_dir}/", "") - if is_inpaint_batch: # try to find corresponding mask for an image using simple filename matching if len(inpaint_masks) == 1: mask_image_path = inpaint_masks[0] else: # try to find corresponding mask for an image using simple filename matching - mask_image_dir = Path(inpaint_mask_dir).joinpath(image_subpath) + mask_image_dir = Path(inpaint_mask_dir) masks_found = list(mask_image_dir.glob(f"{image_path.stem}.*")) if len(masks_found) == 0: - raise ValueError(f"Mask is not found for {image_path} in {mask_image_dir}") + print(f"Warning: mask is not found for {image_path} in {mask_image_dir}. Skipping it.") + continue # it should contain only 1 matching mask # otherwise user has many masks with the same name but different extensions @@ -95,10 +90,10 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args, to_scale=Fal filename = f"{left}-{n}{right}" if not save_normally: - os.makedirs(os.path.join(output_dir, image_subpath), exist_ok=True) + os.makedirs(output_dir, exist_ok=True) if processed_image.mode == 'RGBA': processed_image = processed_image.convert("RGB") - processed_image.save(os.path.join(output_dir, image_subpath, filename)) + processed_image.save(os.path.join(output_dir, filename)) def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_styles, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_index: int, mask_blur: int, mask_alpha: float, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, selected_scale_tab: int, height: int, width: int, scale_by: float, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, *args): -- cgit v1.2.1 From 51864790fd72386fbbbb015d24a43ce501ecaa4b Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Fri, 2 Jun 2023 14:58:10 +0300 Subject: Simplify a bunch of `len(x) > 0`/`len(x) == 0` style expressions --- modules/img2img.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'modules/img2img.py') diff --git a/modules/img2img.py b/modules/img2img.py index 4c12c2c5..35c4facc 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -21,8 +21,7 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args): is_inpaint_batch = False if inpaint_mask_dir: inpaint_masks = shared.listfiles(inpaint_mask_dir) - is_inpaint_batch = len(inpaint_masks) > 0 - if is_inpaint_batch: + is_inpaint_batch = bool(inpaint_masks) print(f"\nInpaint batch is enabled. {len(inpaint_masks)} masks found.") print(f"Will process {len(images)} images, creating {p.n_iter * p.batch_size} new images for each.") -- cgit v1.2.1 From 18acc0b30d9184702a772287ed8197385e0aed98 Mon Sep 17 00:00:00 2001 From: AUTOMATIC <16777216c@gmail.com> Date: Mon, 5 Jun 2023 11:08:57 +0300 Subject: revert the message to how it was --- modules/img2img.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'modules/img2img.py') diff --git a/modules/img2img.py b/modules/img2img.py index 3981b783..2c497020 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -23,7 +23,9 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args, to_scale=Fal if inpaint_mask_dir: inpaint_masks = shared.listfiles(inpaint_mask_dir) is_inpaint_batch = bool(inpaint_masks) - print(f"\nInpaint batch is enabled. {len(inpaint_masks)} masks found.") + + if is_inpaint_batch: + print(f"\nInpaint batch is enabled. {len(inpaint_masks)} masks found.") print(f"Will process {len(images)} images, creating {p.n_iter * p.batch_size} new images for each.") -- cgit v1.2.1