From a365f7f1d768693056b4332b3e07664f718a4c41 Mon Sep 17 00:00:00 2001 From: Bingsu Date: Tue, 9 May 2023 14:45:29 +0900 Subject: [PATCH 1/6] fix: pre-commit order --- .pre-commit-config.yaml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 902ce42..d718f9b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,14 +12,13 @@ repos: - id: isort args: [--profile=black] - - repo: https://github.com/psf/black - rev: 23.3.0 - hooks: - - id: black - - repo: https://github.com/charliermarsh/ruff-pre-commit - # Ruff version. rev: "v0.0.265" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] + + - repo: https://github.com/psf/black + rev: 23.3.0 + hooks: + - id: black From 6095dbc41be9c390ecec511af1cce618f9bd470a Mon Sep 17 00:00:00 2001 From: Bingsu Date: Tue, 9 May 2023 15:53:01 +0900 Subject: [PATCH 2/6] feat: apply only selected scripts --- adetailer/__version__.py | 2 +- scripts/!adetailer.py | 59 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/adetailer/__version__.py b/adetailer/__version__.py index 8d20f28..64175fb 100644 --- a/adetailer/__version__.py +++ b/adetailer/__version__.py @@ -1 +1 @@ -__version__ = "23.5.9" +__version__ = "23.5.10.dev0" diff --git a/scripts/!adetailer.py b/scripts/!adetailer.py index fbacb8b..bbd4519 100644 --- a/scripts/!adetailer.py +++ b/scripts/!adetailer.py @@ -448,6 +448,32 @@ class AfterDetailerScript(scripts.Script): params_txt = Path(data_path, "params.txt") params_txt.write_text(infotext, encoding="utf-8") + def script_filter(self, p, args: ADetailerArgs): + script_runner = copy(p.scripts) + + ad_only_seleted_scripts = opts.data.get("ad_only_seleted_scripts", True) + if not ad_only_seleted_scripts: + return script_runner + + ad_script_names = opts.data.get("ad_script_names", "") + script_names_set = { + name + for script_name in ad_script_names.split(",") + for name in (script_name, script_name.strip()) + } + if args.ad_controlnet_model != "None": + script_names_set.add("controlnet") + + filtered_alwayson = [] + for script_object in script_runner.alwayson_scripts: + filepath = script_object.filename + filename = Path(filepath).stem + if filename in script_names_set: + filtered_alwayson.append(script_object) + + script_runner.alwayson_scripts = filtered_alwayson + return script_runner + def get_i2i_p(self, p, args: ADetailerArgs, image): prompt, negative_prompt = self.get_prompt(p, args) seed, subseed = self.get_seed(p) @@ -492,7 +518,7 @@ class AfterDetailerScript(scripts.Script): do_not_save_grid=True, ) - i2i.scripts = copy(p.scripts) + i2i.scripts = self.script_filter(p, args) i2i.script_args = deepcopy(p.script_args) i2i._disable_adetailer = True @@ -631,10 +657,10 @@ def on_ui_settings(): shared.opts.add_option( "ad_max_models", shared.OptionInfo( - 2, - "Max models", - gr.Slider, - {"minimum": 1, "maximum": 5, "step": 1}, + default=2, + label="Max models", + component=gr.Slider, + component_args={"minimum": 1, "maximum": 5, "step": 1}, section=section, ), ) @@ -649,5 +675,28 @@ def on_ui_settings(): shared.OptionInfo(False, "Save images before ADetailer", section=section), ) + shared.opts.add_option( + "ad_only_seleted_scripts", + shared.OptionInfo( + True, "Apply only selected scripts to ADetailer", section=section + ), + ) + + textbox_args = { + "placeholder": "comma-separated list of script names", + "interactive": True, + } + + shared.opts.add_option( + "ad_script_names", + shared.OptionInfo( + default="dynamic_prompting,dynamic_thresholding,wildcards,wildcard_recursive", + label="Script names to apply to ADetailer (separated by comma)", + component=gr.Textbox, + component_args=textbox_args, + section=section, + ), + ) + script_callbacks.on_ui_settings(on_ui_settings) From 4b3e5f7e96291c5bc5eb0ce29da3e6c536f8d346 Mon Sep 17 00:00:00 2001 From: Bingsu Date: Tue, 9 May 2023 16:53:59 +0900 Subject: [PATCH 3/6] fix: misc --- adetailer/common.py | 8 ++++---- adetailer/mediapipe.py | 2 +- adetailer/ultralytics.py | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/adetailer/common.py b/adetailer/common.py index f12b682..fe91b3f 100644 --- a/adetailer/common.py +++ b/adetailer/common.py @@ -51,16 +51,16 @@ def get_models(model_dir: Union[str, Path]) -> OrderedDict[str, Optional[str]]: def create_mask_from_bbox( - image: Image.Image, bboxes: list[list[float]] + bboxes: list[list[float]], shape: tuple[int, int] ) -> list[Image.Image]: """ Parameters ---------- - image: Image.Image - The image to create the mask from bboxes: list[list[float]] list of [x1, y1, x2, y2] bounding boxes + shape: tuple[int, int] + shape of the image (width, height) Returns ------- @@ -70,7 +70,7 @@ def create_mask_from_bbox( """ masks = [] for bbox in bboxes: - mask = Image.new("L", image.size, 0) + mask = Image.new("L", shape, 0) mask_draw = ImageDraw.Draw(mask) mask_draw.rectangle(bbox, fill=255) masks.append(mask) diff --git a/adetailer/mediapipe.py b/adetailer/mediapipe.py index 2e1ea43..7a3e775 100644 --- a/adetailer/mediapipe.py +++ b/adetailer/mediapipe.py @@ -45,7 +45,7 @@ def mediapipe_predict( bboxes.append([x1, y1, x2, y2]) - masks = create_mask_from_bbox(image, bboxes) + masks = create_mask_from_bbox(bboxes, image.size) preview = Image.fromarray(preview_array) return PredictOutput(bboxes=bboxes, masks=masks, preview=preview) diff --git a/adetailer/ultralytics.py b/adetailer/ultralytics.py index 90bc68f..8d378f1 100644 --- a/adetailer/ultralytics.py +++ b/adetailer/ultralytics.py @@ -33,7 +33,7 @@ def ultralytics_predict( bboxes = bboxes.tolist() if pred[0].masks is None: - masks = create_mask_from_bbox(image, bboxes) + masks = create_mask_from_bbox(bboxes, image.size) else: masks = mask_to_pil(pred[0].masks.data, image.size) preview = pred[0].plot() @@ -56,17 +56,17 @@ def ultralytics_check(): print(message) -def mask_to_pil(masks, orig_shape: tuple[int, int]) -> list[Image.Image]: +def mask_to_pil(masks, shape: tuple[int, int]) -> list[Image.Image]: """ Parameters ---------- masks: torch.Tensor, dtype=torch.float32, shape=(N, H, W). The device can be CUDA, but `to_pil_image` takes care of that. - orig_shape: tuple[int, int] + shape: tuple[int, int] (width, height) of the original image """ from torchvision.transforms.functional import to_pil_image n = masks.shape[0] - return [to_pil_image(masks[i], mode="L").resize(orig_shape) for i in range(n)] + return [to_pil_image(masks[i], mode="L").resize(shape) for i in range(n)] From 52ce9a721f60e9a653bcd42875bdc09d53686f61 Mon Sep 17 00:00:00 2001 From: Bingsu Date: Tue, 9 May 2023 16:59:45 +0900 Subject: [PATCH 4/6] feat: add person_yolov8s-seg.pt model --- README.md | 1 + adetailer/common.py | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 3b40d8a..36117f7 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ On the ControlNet tab, select a ControlNet inpaint model and set the model weigh | mediapipe_face_short | realistic face | - | - | | hand_yolov8n.pt | 2D / realistic hand | 0.767 | 0.505 | | person_yolov8n-seg.pt | 2D / realistic person | 0.782 (bbox)
0.761 (mask) | 0.555 (bbox)
0.460 (mask) | +| person_yolov8s-seg.pt | 2D / realistic person | 0.824 (bbox)
0.809 (mask) | 0.605 (bbox)
0.508 (mask) | The yolo models can be found on huggingface [Bingsu/adetailer](https://huggingface.co/Bingsu/adetailer). diff --git a/adetailer/common.py b/adetailer/common.py index fe91b3f..5b03da5 100644 --- a/adetailer/common.py +++ b/adetailer/common.py @@ -39,6 +39,7 @@ def get_models(model_dir: Union[str, Path]) -> OrderedDict[str, Optional[str]]: "mediapipe_face_short": None, "hand_yolov8n.pt": hf_hub_download(repo_id, "hand_yolov8n.pt"), "person_yolov8n-seg.pt": hf_hub_download(repo_id, "person_yolov8n-seg.pt"), + "person_yolov8s-seg.pt": hf_hub_download(repo_id, "person_yolov8s-seg.pt"), } ) From 157549d2ff8775b7ec02509b5dd5e56a3bea1159 Mon Sep 17 00:00:00 2001 From: Bingsu Date: Tue, 9 May 2023 17:04:32 +0900 Subject: [PATCH 5/6] chore: v23.5.10 --- CHANGELOG.md | 7 +++++++ adetailer/__version__.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ec9dd8..ff06be9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +### 2023-05-09 + +- v23.5.10 +- 선택한 스크립트만 ADetailer에 적용하는 옵션 추가, 기본값 `True`. 설정 탭에서 지정가능. + - 기본값: `dynamic_prompting,dynamic_thresholding,wildcards,wildcard_recursive` +- `person_yolov8s-seg.pt` 모델 추가 + ### 2023-05-08 - v23.5.9 diff --git a/adetailer/__version__.py b/adetailer/__version__.py index 64175fb..182fb40 100644 --- a/adetailer/__version__.py +++ b/adetailer/__version__.py @@ -1 +1 @@ -__version__ = "23.5.10.dev0" +__version__ = "23.5.10" From 0d5dfa665ae4da35bd3fcd9363a57af001c6e2e1 Mon Sep 17 00:00:00 2001 From: Bingsu Date: Tue, 9 May 2023 17:06:03 +0900 Subject: [PATCH 6/6] fix: ad_script_names default --- scripts/!adetailer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/!adetailer.py b/scripts/!adetailer.py index bbd4519..d37f64f 100644 --- a/scripts/!adetailer.py +++ b/scripts/!adetailer.py @@ -455,7 +455,8 @@ class AfterDetailerScript(scripts.Script): if not ad_only_seleted_scripts: return script_runner - ad_script_names = opts.data.get("ad_script_names", "") + default = "dynamic_prompting,dynamic_thresholding,wildcards,wildcard_recursive" + ad_script_names = opts.data.get("ad_script_names", default) script_names_set = { name for script_name in ad_script_names.split(",")