From e15c21ede9c60dce505d15bae90ae436851703f0 Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Tue, 4 Jun 2024 07:56:46 -0400 Subject: [PATCH] facehires implement include mask in output --- modules/masking.py | 2 +- modules/processing.py | 8 ++++++-- modules/shared.py | 4 ++-- scripts/face-details.py | 10 ++++++---- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/modules/masking.py b/modules/masking.py index 729c8fc63..dc071eead 100644 --- a/modules/masking.py +++ b/modules/masking.py @@ -442,7 +442,7 @@ def run_mask(input_image: Image.Image, input_mask: Image.Image = None, return_ty return_type = return_type or opts.preview_type - shared.log.debug(f'Mask: size={input_image.width}x{input_image.height} masked={mask_size}px area={area_size/total_size:.2f} auto={opts.auto_mask} blur={opts.mask_blur} erode={opts.mask_erode} dilate={opts.mask_dilate} type={return_type} time={t1-t0:.2f}') + shared.log.debug(f'Mask: size={input_image.width}x{input_image.height} masked={mask_size}px area={area_size/total_size:.2f} auto={opts.auto_mask} blur={opts.mask_blur:.3f} erode={opts.mask_erode:.3f} dilate={opts.mask_dilate:.3f} type={return_type} time={t1-t0:.2f}') if return_type == 'None': return input_mask elif return_type == 'Opaque': diff --git a/modules/processing.py b/modules/processing.py index 211f790b8..e0570d42a 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -3,7 +3,7 @@ import json import time from contextlib import nullcontext import numpy as np -from PIL import Image +from PIL import Image, ImageOps from modules import shared, devices, errors, images, scripts, memstats, lowvram, script_callbacks, extra_networks, face_restoration, sd_hijack_freeu, sd_models, sd_vae, processing_helpers from modules.sd_hijack_hypertile import context_hypertile_vae, context_hypertile_unet from modules.processing_class import StableDiffusionProcessing, StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img, StableDiffusionProcessingControl # pylint: disable=unused-import @@ -415,7 +415,11 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed: extra_networks.deactivate(p, extra_network_data) if shared.opts.include_mask: - if getattr(p, 'image_mask', None) is not None and isinstance(p.image_mask, Image.Image): + if shared.opts.mask_apply_overlay and p.overlay_images is not None and len(p.overlay_images): + p.image_mask = create_binary_mask(p.overlay_images[0]) + p.image_mask = ImageOps.invert(p.image_mask) + output_images.append(p.image_mask) + elif getattr(p, 'image_mask', None) is not None and isinstance(p.image_mask, Image.Image): if getattr(p, 'mask_for_facehires', None) is not None: output_images.append(p.mask_for_facehires) else: diff --git a/modules/shared.py b/modules/shared.py index d71efd5df..2de3dc505 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -752,10 +752,10 @@ options_templates.update(options_section(('postprocessing', "Postprocessing"), { "facehires_iou": OptionInfo(0.5, "Max face overlap", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05}), "facehires_min_size": OptionInfo(0, "Min face size", gr.Slider, {"minimum": 0, "maximum": 1024, "step": 1}), "facehires_max_size": OptionInfo(0, "Max face size", gr.Slider, {"minimum": 0, "maximum": 1024, "step": 1}), - "facehires_padding": OptionInfo(10, "Face padding", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1}), - "face_restoration_unload": OptionInfo(False, "Move model to CPU when complete"), + "facehires_padding": OptionInfo(20, "Face padding", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1}), "facehires_strength": OptionInfo(0.0, "Face restore strength", gr.Slider, {"minimum": 0, "maximum": 1, "step": 0.01}), "code_former_weight": OptionInfo(0.2, "CodeFormer weight parameter", gr.Slider, {"minimum": 0, "maximum": 1, "step": 0.01}), + "face_restoration_unload": OptionInfo(False, "Move model to CPU when complete"), "postprocessing_sep_upscalers": OptionInfo("

Upscaling

", "", gr.HTML), "upscaler_unload": OptionInfo(False, "Unload upscaler after processing"), diff --git a/scripts/face-details.py b/scripts/face-details.py index 849461c77..f5e554f15 100644 --- a/scripts/face-details.py +++ b/scripts/face-details.py @@ -160,6 +160,7 @@ class FaceRestorerYolo(FaceRestoration): continue p.init_images = [image] p.image_mask = [face.mask] + # mask_all.append(face.mask) p.recursion = True pp = processing.process_images_inner(p) del p.recursion @@ -176,12 +177,13 @@ class FaceRestorerYolo(FaceRestoration): shared.opts.data['mask_apply_overlay'] = orig_apply_overlay np_image = np.array(image) - """ if len(mask_all) > 0 and shared.opts.include_mask: from modules.control.util import blend - mask_all = blend([np.array(m) for m in mask_all]) - mask_pil = Image.fromarray(mask_all) - """ + p.image_mask = blend([np.array(m) for m in mask_all]) + # combined = blend([np_image, p.image_mask]) + # combined = Image.fromarray(combined) + # combined.save('/tmp/face.png') + p.image_mask = Image.fromarray(p.image_mask) return np_image