From 36578d61c2a3cd09f0c5af57c1cd767bafd92d0e Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Tue, 23 Jan 2024 08:37:30 -0500 Subject: [PATCH] fix mask invert --- extensions-builtin/sd-extension-chainner | 2 +- extensions-builtin/sd-extension-system-info | 2 +- extensions-builtin/sd-webui-controlnet | 2 +- modules/lora | 2 +- modules/masking.py | 25 ++++++++++++--------- modules/processing.py | 10 ++++++++- modules/ui_img2img.py | 2 +- requirements.txt | 4 ++-- 8 files changed, 31 insertions(+), 18 deletions(-) diff --git a/extensions-builtin/sd-extension-chainner b/extensions-builtin/sd-extension-chainner index da3232b3f..425d9cd15 160000 --- a/extensions-builtin/sd-extension-chainner +++ b/extensions-builtin/sd-extension-chainner @@ -1 +1 @@ -Subproject commit da3232b3fdaddf37a602348d4f1f5dee60652975 +Subproject commit 425d9cd15e5e0696550e63263c5a1c6843073db9 diff --git a/extensions-builtin/sd-extension-system-info b/extensions-builtin/sd-extension-system-info index ab3bd1641..72d871b45 160000 --- a/extensions-builtin/sd-extension-system-info +++ b/extensions-builtin/sd-extension-system-info @@ -1 +1 @@ -Subproject commit ab3bd1641a26451831ae37992c6d0f3fb9886dc2 +Subproject commit 72d871b4567c228c30c8eb2cd26db653065f6fc7 diff --git a/extensions-builtin/sd-webui-controlnet b/extensions-builtin/sd-webui-controlnet index 25e41dc63..e94985892 160000 --- a/extensions-builtin/sd-webui-controlnet +++ b/extensions-builtin/sd-webui-controlnet @@ -1 +1 @@ -Subproject commit 25e41dc63b19f5882dedd5ea67d587951e390caf +Subproject commit e9498589245eba09b531b01b082ee44b7dfa136f diff --git a/modules/lora b/modules/lora index d2a99a19d..d5ab97b69 160000 --- a/modules/lora +++ b/modules/lora @@ -1 +1 @@ -Subproject commit d2a99a19d45e06cb0506a0d263349f53193df451 +Subproject commit d5ab97b69b4822d0ef3ae7ca5cf8d37a92384305 diff --git a/modules/masking.py b/modules/masking.py index 3c14c0acb..6226abe6c 100644 --- a/modules/masking.py +++ b/modules/masking.py @@ -148,6 +148,7 @@ opts = SimpleNamespace(**{ 'weight_original': 0.5, 'weight_mask': 0.5, 'kernel_iterations': 1, + 'invert': False }) @@ -312,7 +313,7 @@ def get_mask(input_image: gr.Image, input_mask: gr.Image): return output_mask -def run_mask(input_image: gr.Image, input_mask: gr.Image = None, return_type: str = None, mask_blur: int = None, mask_padding: int = None, segment_enable=True): +def run_mask(input_image: gr.Image, input_mask: gr.Image = None, return_type: str = None, mask_blur: int = None, mask_padding: int = None, segment_enable=True, invert=False): if input_image is None: return input_mask if isinstance(input_image, list): @@ -369,6 +370,8 @@ def run_mask(input_image: gr.Image, input_mask: gr.Image = None, return_type: st debug(f'Segment blur={opts.mask_blur} x={sigmax} y={sigmay} mask={mask.shape}') except Exception as e: shared.log.error(f'Segment blur: {e}') + if invert or opts.invert: + mask = np.invert(mask) mask_size = np.count_nonzero(mask) total_size = np.prod(mask.shape) @@ -434,15 +437,16 @@ def create_segment_ui(): def update_opts(*args): opts.seg_live = args[0] opts.mask_only = args[1] - opts.mask_blur = args[2] - opts.mask_erode = args[3] - opts.mask_dilate = args[4] - opts.auto_mask = args[5] - opts.seg_score_thresh = args[6] - opts.seg_iou_thresh = args[7] - opts.seg_nms_thresh = args[8] - opts.preview_type = args[9] - opts.seg_colormap = args[10] + opts.invert = args[2] + opts.mask_blur = args[3] + opts.mask_erode = args[4] + opts.mask_dilate = args[5] + opts.auto_mask = args[6] + opts.seg_score_thresh = args[7] + opts.seg_iou_thresh = args[8] + opts.seg_nms_thresh = args[9] + opts.preview_type = args[10] + opts.seg_colormap = args[11] global btn_mask, btn_lama # pylint: disable=global-statement with gr.Accordion(open=False, label="Mask", elem_id="control_mask", elem_classes=["small-accordion"]): @@ -453,6 +457,7 @@ def create_segment_ui(): btn_lama = ui_components.ToolButton(value=ui_symbols.image, visible=True) with gr.Row(): controls.append(gr.Checkbox(label="Inpaint masked only", value=False)) + controls.append(gr.Checkbox(label="Invert mask", value=False)) with gr.Row(): controls.append(gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Blur', value=0.01, elem_id="control_mask_blur")) controls.append(gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Erode', value=0.01, elem_id="control_mask_erode")) diff --git a/modules/processing.py b/modules/processing.py index 6dc17a74f..6a15e85cd 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -1301,7 +1301,15 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing): self.image_mask = Image.fromarray(np_mask) else: if hasattr(self, 'init_images'): - self.image_mask = modules.masking.run_mask(input_image=self.init_images, input_mask=self.image_mask, return_type='Grayscale', mask_blur=self.mask_blur, mask_padding=self.inpaint_full_res_padding, segment_enable=False) + self.image_mask = modules.masking.run_mask( + input_image=self.init_images, + input_mask=self.image_mask, + return_type='Grayscale', + mask_blur=self.mask_blur, + mask_padding=self.inpaint_full_res_padding, + segment_enable=False, + invert=self.inpainting_mask_invert, + ) if self.inpaint_full_res: # mask only inpaint self.mask_for_overlay = self.image_mask mask = self.image_mask.convert('L') diff --git a/modules/ui_img2img.py b/modules/ui_img2img.py index 331b63263..eabbf778f 100644 --- a/modules/ui_img2img.py +++ b/modules/ui_img2img.py @@ -139,7 +139,7 @@ def create_ui(): inpaint_full_res_padding = gr.Slider(label='Padding', minimum=0, maximum=256, step=4, value=32, elem_id="img2img_inpaint_full_res_padding") mask_alpha = gr.Slider(label="Alpha", minimum=0.0, maximum=1.0, step=0.05, value=1.0, elem_id="img2img_mask_alpha") with gr.Row(): - inpainting_mask_invert = gr.Radio(label='Mode', choices=['masked', 'inverse'], value='masked', type="index", elem_id="img2img_mask_mode") + inpainting_mask_invert = gr.Radio(label='Mode', choices=['masked', 'invert'], value='masked', type="index", elem_id="img2img_mask_mode") inpaint_full_res = gr.Radio(label="Inpaint area", choices=["full", "masked"], type="index", value="full", elem_id="img2img_inpaint_full_res") inpainting_fill = gr.Radio(label='Masked content', choices=['fill', 'original', 'noise', 'nothing'], value='original', type="index", elem_id="img2img_inpainting_fill", visible=shared.backend == shared.Backend.ORIGINAL) diff --git a/requirements.txt b/requirements.txt index 82e394c51..fcd04499e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -48,7 +48,7 @@ orjson httpx==0.24.1 compel==2.0.2 torchsde==0.2.6 - clip-interrogator==0.6.0 +clip-interrogator==0.6.0 antlr4-python3-runtime==4.9.3 requests==2.31.0 tqdm==4.66.1 @@ -68,7 +68,7 @@ tokenizers==0.15.0 transformers==4.36.2 tomesd==0.1.3 urllib3==1.26.18 -Pillow==10.1.0 +Pillow==10.2.0 timm==0.9.12 pydantic==1.10.13 typing-extensions==4.9.0