From 35bd01c4ff42508dbb7a35bc36e9bd4aac905add Mon Sep 17 00:00:00 2001 From: Bingsu Date: Thu, 11 May 2023 22:07:19 +0900 Subject: [PATCH 1/9] fix: inpaint width/height min,max --- scripts/!adetailer.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/!adetailer.py b/scripts/!adetailer.py index d37f64f..672ee1a 100644 --- a/scripts/!adetailer.py +++ b/scripts/!adetailer.py @@ -221,8 +221,8 @@ class AfterDetailerScript(scripts.Script): w[n].ad_inpaint_width = gr.Slider( label="inpaint width" + suffix(n), - minimum=4, - maximum=1024, + minimum=64, + maximum=2048, step=4, value=512, visible=True, @@ -230,8 +230,8 @@ class AfterDetailerScript(scripts.Script): w[n].ad_inpaint_height = gr.Slider( label="inpaint height" + suffix(n), - minimum=4, - maximum=1024, + minimum=64, + maximum=2048, step=4, value=512, visible=True, From a610eb6fe971baa1f25f0e0d62d2e7638f4b77fb Mon Sep 17 00:00:00 2001 From: Bingsu Date: Thu, 11 May 2023 22:17:59 +0900 Subject: [PATCH 2/9] fix: remove 0 offset param, ultralytics check --- adetailer/args.py | 5 +++++ adetailer/ultralytics.py | 21 +-------------------- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/adetailer/args.py b/adetailer/args.py index 348290d..b468204 100644 --- a/adetailer/args.py +++ b/adetailer/args.py @@ -87,6 +87,11 @@ class ADetailerArgs(BaseModel, extra=Extra.forbid): if not params["ADetailer negative prompt"]: params.pop("ADetailer negative prompt") + if params["ADetailer x offset"] == 0: + params.pop("ADetailer x offset") + if params["ADetailer y offset"] == 0: + params.pop("ADetailer y offset") + if not params["ADetailer use inpaint width/height"]: params.pop("ADetailer inpaint width") params.pop("ADetailer inpaint height") diff --git a/adetailer/ultralytics.py b/adetailer/ultralytics.py index f55883c..fff133b 100644 --- a/adetailer/ultralytics.py +++ b/adetailer/ultralytics.py @@ -1,6 +1,5 @@ from __future__ import annotations -import platform from pathlib import Path from typing import Union @@ -10,8 +9,6 @@ from PIL import Image from adetailer import PredictOutput from adetailer.common import create_mask_from_bbox -checked = False - def ultralytics_predict( model_path: Union[str, Path], @@ -19,15 +16,12 @@ def ultralytics_predict( confidence: float = 0.3, device: str = "", ) -> PredictOutput: - if not checked: - ultralytics_check() - from ultralytics import YOLO model_path = str(model_path) model = YOLO(model_path) - pred = model(image, conf=confidence, show_labels=False, device=device) + pred = model(image, conf=confidence, device=device) bboxes = pred[0].boxes.xyxy.cpu().numpy() if bboxes.size == 0: @@ -45,19 +39,6 @@ def ultralytics_predict( return PredictOutput(bboxes=bboxes, masks=masks, preview=preview) -def ultralytics_check(): - global checked - - checked = True - if platform.system() != "Windows": - return - - p = str(Path.cwd().parent) - if p == "C:\\": - message = "[-] ADetailer: if you get stuck here, try moving the stable-diffusion-webui to a different directory, or try running as administrator." - print(message) - - def mask_to_pil(masks, shape: tuple[int, int]) -> list[Image.Image]: """ Parameters From 0846d668e230b441870757133b2f1fc970093092 Mon Sep 17 00:00:00 2001 From: Bingsu Date: Fri, 12 May 2023 10:19:15 +0900 Subject: [PATCH 3/9] fix: some ui --- scripts/!adetailer.py | 147 +++++++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 73 deletions(-) diff --git a/scripts/!adetailer.py b/scripts/!adetailer.py index 672ee1a..19b3c89 100644 --- a/scripts/!adetailer.py +++ b/scripts/!adetailer.py @@ -119,25 +119,26 @@ class AfterDetailerScript(scripts.Script): type="value", ) - with gr.Row(elem_id="AD_toprow_prompt" + suffix(n, "_")): - w[n].ad_prompt = gr.Textbox( - label="ad_prompt" + suffix(n), - show_label=False, - lines=3, - placeholder="ADetailer prompt" + suffix(n), - elem_id="AD_prompt" + suffix(n, "_"), - ) + with gr.Group(): + with gr.Row(elem_id="AD_toprow_prompt" + suffix(n, "_")): + w[n].ad_prompt = gr.Textbox( + label="ad_prompt" + suffix(n), + show_label=False, + lines=3, + placeholder="ADetailer prompt" + suffix(n), + elem_id="AD_prompt" + suffix(n, "_"), + ) - with gr.Row( - elem_id="AD_toprow_negative_prompt" + suffix(n, "_") - ): - w[n].ad_negative_prompt = gr.Textbox( - label="ad_negative_prompt" + suffix(n), - show_label=False, - lines=2, - placeholder="ADetailer negative prompt" + suffix(n), - elem_id="AD_negative_prompt" + suffix(n, "_"), - ) + with gr.Row( + elem_id="AD_toprow_negative_prompt" + suffix(n, "_") + ): + w[n].ad_negative_prompt = gr.Textbox( + label="ad_negative_prompt" + suffix(n), + show_label=False, + lines=2, + placeholder="ADetailer negative prompt" + suffix(n), + elem_id="AD_negative_prompt" + suffix(n, "_"), + ) with gr.Group(): with gr.Row(): @@ -196,6 +197,7 @@ class AfterDetailerScript(scripts.Script): visible=True, ) + with gr.Group(): with gr.Row(): w[n].ad_inpaint_full_res = gr.Checkbox( label="Inpaint at full resolution " + suffix(n), @@ -213,69 +215,68 @@ class AfterDetailerScript(scripts.Script): ) with gr.Row(): - w[n].ad_use_inpaint_width_height = gr.Checkbox( - label="Use separate width/height" + suffix(n), - value=False, - visible=True, - ) + with gr.Column(): + w[n].ad_use_inpaint_width_height = gr.Checkbox( + label="Use separate width/height" + suffix(n), + value=False, + visible=True, + ) - w[n].ad_inpaint_width = gr.Slider( - label="inpaint width" + suffix(n), - minimum=64, - maximum=2048, - step=4, - value=512, - visible=True, - ) + w[n].ad_inpaint_width = gr.Slider( + label="inpaint width" + suffix(n), + minimum=64, + maximum=2048, + step=4, + value=512, + visible=True, + ) - w[n].ad_inpaint_height = gr.Slider( - label="inpaint height" + suffix(n), - minimum=64, - maximum=2048, - step=4, - value=512, - visible=True, - ) + w[n].ad_inpaint_height = gr.Slider( + label="inpaint height" + suffix(n), + minimum=64, + maximum=2048, + step=4, + value=512, + visible=True, + ) - with gr.Row(): - w[n].ad_use_cfg_scale = gr.Checkbox( - label="Use separate CFG scale" + suffix(n), - value=False, - visible=True, - ) + with gr.Column(): + w[n].ad_use_cfg_scale = gr.Checkbox( + label="Use separate CFG scale" + suffix(n), + value=False, + visible=True, + ) - w[n].ad_cfg_scale = gr.Slider( - label="ADetailer CFG scale" + suffix(n), - minimum=0.0, - maximum=30.0, - step=0.5, - value=7.0, - visible=True, - ) + w[n].ad_cfg_scale = gr.Slider( + label="ADetailer CFG scale" + suffix(n), + minimum=0.0, + maximum=30.0, + step=0.5, + value=7.0, + visible=True, + ) + with gr.Group(), gr.Row(variant="panel"): cn_inpaint_models = ["None"] + get_cn_inpaint_models() - with gr.Group(): - with gr.Row(): - w[n].ad_controlnet_model = gr.Dropdown( - label="ControlNet model" + suffix(n), - choices=cn_inpaint_models, - value="None", - visible=True, - type="value", - interactive=controlnet_exists, - ) + w[n].ad_controlnet_model = gr.Dropdown( + label="ControlNet model" + suffix(n), + choices=cn_inpaint_models, + value="None", + visible=True, + type="value", + interactive=controlnet_exists, + ) - with gr.Row(): - w[n].ad_controlnet_weight = gr.Slider( - label="ControlNet weight" + suffix(n), - minimum=0.0, - maximum=1.0, - step=0.05, - value=1.0, - visible=True, - interactive=controlnet_exists, - ) + w[n].ad_controlnet_weight = gr.Slider( + label="ControlNet weight" + suffix(n), + minimum=0.0, + maximum=1.0, + step=0.05, + value=1.0, + visible=True, + interactive=controlnet_exists, + ) # Accordion end From 7ea6e4dbc722dc11913340934711cbf7f18fce82 Mon Sep 17 00:00:00 2001 From: Bingsu Date: Fri, 12 May 2023 12:08:27 +0900 Subject: [PATCH 4/9] refactor: widgets as userdict --- scripts/!adetailer.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/scripts/!adetailer.py b/scripts/!adetailer.py index 19b3c89..ca18bf8 100644 --- a/scripts/!adetailer.py +++ b/scripts/!adetailer.py @@ -3,10 +3,12 @@ from __future__ import annotations import platform import sys import traceback +from collections import UserDict from copy import copy, deepcopy from itertools import zip_longest from pathlib import Path from textwrap import dedent +from typing import Any import gradio as gr import torch @@ -50,9 +52,18 @@ print( ) -class Widgets: +class Widgets(UserDict): + def __getattribute__(self, __name: str) -> Any: + return self.__getitem__(__name) + + def __setattr__(self, __name: str, __value: Any) -> None: + self.__setitem__(__name, __value) + + def __delattr__(self, __name: str) -> None: + self.__delitem__(__name) + def tolist(self): - return [getattr(self, attr) for attr, *_ in ALL_ARGS[1:]] + return [self[attr] for attr, *_ in ALL_ARGS[1:]] class ChangeTorchLoad: @@ -64,7 +75,7 @@ class ChangeTorchLoad: torch.load = self.orig -def gr_show(visible=True): +def gr_show(visible: bool = True): return {"visible": visible, "__type__": "update"} From 781494ce1f496af5aae698932f7818e71c92b58c Mon Sep 17 00:00:00 2001 From: Bingsu Date: Fri, 12 May 2023 12:59:17 +0900 Subject: [PATCH 5/9] feat: add separate steps --- adetailer/args.py | 13 ++++++++++ scripts/!adetailer.py | 55 ++++++++++++++++++++++++++++++------------- 2 files changed, 52 insertions(+), 16 deletions(-) diff --git a/adetailer/args.py b/adetailer/args.py index b468204..f2bb64f 100644 --- a/adetailer/args.py +++ b/adetailer/args.py @@ -33,6 +33,8 @@ _all_args = [ ("ad_use_inpaint_width_height", "ADetailer use inpaint width/height"), ("ad_inpaint_width", "ADetailer inpaint width"), ("ad_inpaint_height", "ADetailer inpaint height"), + ("ad_use_steps", "ADetailer use separate steps"), + ("ad_steps", "ADetailer steps"), ("ad_use_cfg_scale", "ADetailer use separate CFG scale"), ("ad_cfg_scale", "ADetailer CFG scale"), ("ad_controlnet_model", "ADetailer ControlNet model"), @@ -58,6 +60,8 @@ class ADetailerArgs(BaseModel, extra=Extra.forbid): ad_use_inpaint_width_height: bool = False ad_inpaint_width: PositiveInt = 512 ad_inpaint_height: PositiveInt = 512 + ad_use_steps: bool = False + ad_steps: PositiveInt = 28 ad_use_cfg_scale: bool = False ad_cfg_scale: NonNegativeFloat = 7.0 ad_controlnet_model: str = "None" @@ -92,11 +96,20 @@ class ADetailerArgs(BaseModel, extra=Extra.forbid): if params["ADetailer y offset"] == 0: params.pop("ADetailer y offset") + if not params["ADetailer inpaint full"]: + params.pop("ADetailer inpaint padding") + if not params["ADetailer use inpaint width/height"]: + params.pop("ADetailer use inpaint width/height") params.pop("ADetailer inpaint width") params.pop("ADetailer inpaint height") + if not params["ADetailer use separate steps"]: + params.pop("ADetailer use separate steps") + params.pop("ADetailer steps") + if not params["ADetailer use separate CFG scale"]: + params.pop("ADetailer use separate CFG scale") params.pop("ADetailer CFG scale") if params["ADetailer ControlNet model"] == "None": diff --git a/scripts/!adetailer.py b/scripts/!adetailer.py index ca18bf8..8053719 100644 --- a/scripts/!adetailer.py +++ b/scripts/!adetailer.py @@ -210,22 +210,22 @@ class AfterDetailerScript(scripts.Script): with gr.Group(): with gr.Row(): - w[n].ad_inpaint_full_res = gr.Checkbox( - label="Inpaint at full resolution " + suffix(n), - value=True, - visible=True, - ) - w[n].ad_inpaint_full_res_padding = gr.Slider( - label="Inpaint at full resolution padding, pixels " - + suffix(n), - minimum=0, - maximum=256, - step=4, - value=0, - visible=True, - ) + with gr.Column(): + w[n].ad_inpaint_full_res = gr.Checkbox( + label="Inpaint at full resolution " + suffix(n), + value=True, + visible=True, + ) + w[n].ad_inpaint_full_res_padding = gr.Slider( + label="Inpaint at full resolution padding, pixels " + + suffix(n), + minimum=0, + maximum=256, + step=4, + value=0, + visible=True, + ) - with gr.Row(): with gr.Column(): w[n].ad_use_inpaint_width_height = gr.Checkbox( label="Use separate width/height" + suffix(n), @@ -251,6 +251,23 @@ class AfterDetailerScript(scripts.Script): visible=True, ) + with gr.Row(): + with gr.Column(): + w[n].ad_use_steps = gr.Checkbox( + label="Use separate steps" + suffix(n), + value=False, + visible=True, + ) + + w[n].ad_steps = gr.Slider( + label="ADetailer steps" + suffix(n), + minimum=1, + maximum=150, + step=1, + value=28, + visible=True, + ) + with gr.Column(): w[n].ad_use_cfg_scale = gr.Checkbox( label="Use separate CFG scale" + suffix(n), @@ -445,6 +462,11 @@ class AfterDetailerScript(scripts.Script): return width, height + def get_steps(self, p, args: ADetailerArgs) -> int: + if args.ad_use_steps: + return args.ad_steps + return p.steps + def get_cfg_scale(self, p, args: ADetailerArgs) -> float: if args.ad_use_cfg_scale: return args.ad_cfg_scale @@ -491,6 +513,7 @@ class AfterDetailerScript(scripts.Script): prompt, negative_prompt = self.get_prompt(p, args) seed, subseed = self.get_seed(p) width, height = self.get_width_height(p, args) + steps = self.get_steps(p, args) cfg_scale = self.get_cfg_scale(p, args) sampler_name = p.sampler_name @@ -521,7 +544,7 @@ class AfterDetailerScript(scripts.Script): sampler_name=sampler_name, batch_size=1, n_iter=1, - steps=p.steps, + steps=steps, cfg_scale=cfg_scale, width=width, height=height, From 53cad0553b0462624fc29a1caf8b2d0ddb281959 Mon Sep 17 00:00:00 2001 From: Bingsu Date: Fri, 12 May 2023 13:16:59 +0900 Subject: [PATCH 6/9] fix: revert widgets --- scripts/!adetailer.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/scripts/!adetailer.py b/scripts/!adetailer.py index 8053719..77b49bb 100644 --- a/scripts/!adetailer.py +++ b/scripts/!adetailer.py @@ -3,7 +3,6 @@ from __future__ import annotations import platform import sys import traceback -from collections import UserDict from copy import copy, deepcopy from itertools import zip_longest from pathlib import Path @@ -52,18 +51,9 @@ print( ) -class Widgets(UserDict): - def __getattribute__(self, __name: str) -> Any: - return self.__getitem__(__name) - - def __setattr__(self, __name: str, __value: Any) -> None: - self.__setitem__(__name, __value) - - def __delattr__(self, __name: str) -> None: - self.__delitem__(__name) - +class Widgets: def tolist(self): - return [self[attr] for attr, *_ in ALL_ARGS[1:]] + return [getattr(self, attr) for attr, *_ in ALL_ARGS[1:]] class ChangeTorchLoad: From 9942a9951948a5e21a4aa3cf07e108c4f01aed7f Mon Sep 17 00:00:00 2001 From: Bingsu Date: Fri, 12 May 2023 14:00:42 +0900 Subject: [PATCH 7/9] fix: ui column compact --- scripts/!adetailer.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/!adetailer.py b/scripts/!adetailer.py index 77b49bb..3058bf0 100644 --- a/scripts/!adetailer.py +++ b/scripts/!adetailer.py @@ -200,7 +200,7 @@ class AfterDetailerScript(scripts.Script): with gr.Group(): with gr.Row(): - with gr.Column(): + with gr.Column(variant="compact"): w[n].ad_inpaint_full_res = gr.Checkbox( label="Inpaint at full resolution " + suffix(n), value=True, @@ -216,7 +216,7 @@ class AfterDetailerScript(scripts.Script): visible=True, ) - with gr.Column(): + with gr.Column(variant="compact"): w[n].ad_use_inpaint_width_height = gr.Checkbox( label="Use separate width/height" + suffix(n), value=False, @@ -242,7 +242,7 @@ class AfterDetailerScript(scripts.Script): ) with gr.Row(): - with gr.Column(): + with gr.Column(variant="compact"): w[n].ad_use_steps = gr.Checkbox( label="Use separate steps" + suffix(n), value=False, @@ -258,7 +258,7 @@ class AfterDetailerScript(scripts.Script): visible=True, ) - with gr.Column(): + with gr.Column(variant="compact"): w[n].ad_use_cfg_scale = gr.Checkbox( label="Use separate CFG scale" + suffix(n), value=False, From 9dc816dbbdbde3febe3bcaaf4198e2b4c171d4e5 Mon Sep 17 00:00:00 2001 From: Bingsu Date: Fri, 12 May 2023 14:23:14 +0900 Subject: [PATCH 8/9] chore: v23.5.11 --- CHANGELOG.md | 9 +++++++++ adetailer/__version__.py | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff06be9..3bfde8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,20 @@ # Changelog +### 2023-05-12 + +- v23.5.11 +- `ultralytics` 알람 제거 +- 필요없는 exif 인자 더 제거함 +- `use separate steps` 옵션 추가 +- ui 배치를 조정함 + ### 2023-05-09 - v23.5.10 - 선택한 스크립트만 ADetailer에 적용하는 옵션 추가, 기본값 `True`. 설정 탭에서 지정가능. - 기본값: `dynamic_prompting,dynamic_thresholding,wildcards,wildcard_recursive` - `person_yolov8s-seg.pt` 모델 추가 +- `ultralytics`의 최소 버전을 `8.0.97`로 설정 (C:\\ 문제 해결된 버전) ### 2023-05-08 diff --git a/adetailer/__version__.py b/adetailer/__version__.py index 182fb40..d0eaf54 100644 --- a/adetailer/__version__.py +++ b/adetailer/__version__.py @@ -1 +1 @@ -__version__ = "23.5.10" +__version__ = "23.5.11" From 6ca6301fb7c7d78734265502c0f1bcb44284b1d0 Mon Sep 17 00:00:00 2001 From: Bingsu Date: Fri, 12 May 2023 14:40:22 +0900 Subject: [PATCH 9/9] docs: usage --- README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 36117f7..60aab00 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,21 @@ You **DON'T** need to download any model from huggingface. ## Usage -TO DO +It's auto detecting, masking, and inpainting tool. + +So some options correspond to options on the inpaint tab. + +![image](https://i.imgur.com/f8RFI4w.png) + +Other options: + +| Option | | | +| -------------------------------------- | -------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | +| ADetailer model | Determine what to detect. | `None` = disable | +| ADetailer prompt, negative prompt | Prompts and negative prompts to apply | If left blank, it will use the same as the input. | +| Detection model confidence threshold % | Only objects with a detection model confidence above this threshold are used for inpainting. | | +| Mask erosion (-) / dilation (+) | Enlarge or reduce the detected mask. | https://docs.opencv.org/4.7.0/db/df6/tutorial_erosion_dilatation.html | +| Mask x, y offset | Moves the mask horizontally and vertically by pixels. | | ## ControlNet Inpainting @@ -72,3 +86,5 @@ Datasets used for training the yolo models are: ![image](https://i.imgur.com/38RSxSO.png) ![image](https://i.imgur.com/2CYgjLx.png) + +[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/F1F1L7V2N)