Merge branch 'dev' into main

This commit is contained in:
Bingsu
2023-05-12 14:47:18 +09:00
6 changed files with 161 additions and 112 deletions

View File

@@ -1,11 +1,20 @@
# Changelog # Changelog
### 2023-05-12
- v23.5.11
- `ultralytics` 알람 제거
- 필요없는 exif 인자 더 제거함
- `use separate steps` 옵션 추가
- ui 배치를 조정함
### 2023-05-09 ### 2023-05-09
- v23.5.10 - v23.5.10
- 선택한 스크립트만 ADetailer에 적용하는 옵션 추가, 기본값 `True`. 설정 탭에서 지정가능. - 선택한 스크립트만 ADetailer에 적용하는 옵션 추가, 기본값 `True`. 설정 탭에서 지정가능.
- 기본값: `dynamic_prompting,dynamic_thresholding,wildcards,wildcard_recursive` - 기본값: `dynamic_prompting,dynamic_thresholding,wildcards,wildcard_recursive`
- `person_yolov8s-seg.pt` 모델 추가 - `person_yolov8s-seg.pt` 모델 추가
- `ultralytics`의 최소 버전을 `8.0.97`로 설정 (C:\\ 문제 해결된 버전)
### 2023-05-08 ### 2023-05-08

View File

@@ -18,7 +18,21 @@ You **DON'T** need to download any model from huggingface.
## Usage ## 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 ## 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/38RSxSO.png)
![image](https://i.imgur.com/2CYgjLx.png) ![image](https://i.imgur.com/2CYgjLx.png)
[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/F1F1L7V2N)

View File

@@ -1 +1 @@
__version__ = "23.5.10" __version__ = "23.5.11"

View File

@@ -33,6 +33,8 @@ _all_args = [
("ad_use_inpaint_width_height", "ADetailer use inpaint width/height"), ("ad_use_inpaint_width_height", "ADetailer use inpaint width/height"),
("ad_inpaint_width", "ADetailer inpaint width"), ("ad_inpaint_width", "ADetailer inpaint width"),
("ad_inpaint_height", "ADetailer inpaint height"), ("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_use_cfg_scale", "ADetailer use separate CFG scale"),
("ad_cfg_scale", "ADetailer CFG scale"), ("ad_cfg_scale", "ADetailer CFG scale"),
("ad_controlnet_model", "ADetailer ControlNet model"), ("ad_controlnet_model", "ADetailer ControlNet model"),
@@ -58,6 +60,8 @@ class ADetailerArgs(BaseModel, extra=Extra.forbid):
ad_use_inpaint_width_height: bool = False ad_use_inpaint_width_height: bool = False
ad_inpaint_width: PositiveInt = 512 ad_inpaint_width: PositiveInt = 512
ad_inpaint_height: PositiveInt = 512 ad_inpaint_height: PositiveInt = 512
ad_use_steps: bool = False
ad_steps: PositiveInt = 28
ad_use_cfg_scale: bool = False ad_use_cfg_scale: bool = False
ad_cfg_scale: NonNegativeFloat = 7.0 ad_cfg_scale: NonNegativeFloat = 7.0
ad_controlnet_model: str = "None" ad_controlnet_model: str = "None"
@@ -87,11 +91,25 @@ class ADetailerArgs(BaseModel, extra=Extra.forbid):
if not params["ADetailer negative prompt"]: if not params["ADetailer negative prompt"]:
params.pop("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 inpaint full"]:
params.pop("ADetailer inpaint padding")
if not params["ADetailer use inpaint width/height"]: if not params["ADetailer use inpaint width/height"]:
params.pop("ADetailer use inpaint width/height")
params.pop("ADetailer inpaint width") params.pop("ADetailer inpaint width")
params.pop("ADetailer inpaint height") 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"]: if not params["ADetailer use separate CFG scale"]:
params.pop("ADetailer use separate CFG scale")
params.pop("ADetailer CFG scale") params.pop("ADetailer CFG scale")
if params["ADetailer ControlNet model"] == "None": if params["ADetailer ControlNet model"] == "None":

View File

@@ -1,6 +1,5 @@
from __future__ import annotations from __future__ import annotations
import platform
from pathlib import Path from pathlib import Path
from typing import Union from typing import Union
@@ -10,8 +9,6 @@ from PIL import Image
from adetailer import PredictOutput from adetailer import PredictOutput
from adetailer.common import create_mask_from_bbox from adetailer.common import create_mask_from_bbox
checked = False
def ultralytics_predict( def ultralytics_predict(
model_path: Union[str, Path], model_path: Union[str, Path],
@@ -19,15 +16,12 @@ def ultralytics_predict(
confidence: float = 0.3, confidence: float = 0.3,
device: str = "", device: str = "",
) -> PredictOutput: ) -> PredictOutput:
if not checked:
ultralytics_check()
from ultralytics import YOLO from ultralytics import YOLO
model_path = str(model_path) model_path = str(model_path)
model = YOLO(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() bboxes = pred[0].boxes.xyxy.cpu().numpy()
if bboxes.size == 0: if bboxes.size == 0:
@@ -45,19 +39,6 @@ def ultralytics_predict(
return PredictOutput(bboxes=bboxes, masks=masks, preview=preview) 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]: def mask_to_pil(masks, shape: tuple[int, int]) -> list[Image.Image]:
""" """
Parameters Parameters

View File

@@ -7,6 +7,7 @@ from copy import copy, deepcopy
from itertools import zip_longest from itertools import zip_longest
from pathlib import Path from pathlib import Path
from textwrap import dedent from textwrap import dedent
from typing import Any
import gradio as gr import gradio as gr
import torch import torch
@@ -64,7 +65,7 @@ class ChangeTorchLoad:
torch.load = self.orig torch.load = self.orig
def gr_show(visible=True): def gr_show(visible: bool = True):
return {"visible": visible, "__type__": "update"} return {"visible": visible, "__type__": "update"}
@@ -119,25 +120,26 @@ class AfterDetailerScript(scripts.Script):
type="value", type="value",
) )
with gr.Row(elem_id="AD_toprow_prompt" + suffix(n, "_")): with gr.Group():
w[n].ad_prompt = gr.Textbox( with gr.Row(elem_id="AD_toprow_prompt" + suffix(n, "_")):
label="ad_prompt" + suffix(n), w[n].ad_prompt = gr.Textbox(
show_label=False, label="ad_prompt" + suffix(n),
lines=3, show_label=False,
placeholder="ADetailer prompt" + suffix(n), lines=3,
elem_id="AD_prompt" + suffix(n, "_"), placeholder="ADetailer prompt" + suffix(n),
) elem_id="AD_prompt" + suffix(n, "_"),
)
with gr.Row( with gr.Row(
elem_id="AD_toprow_negative_prompt" + suffix(n, "_") elem_id="AD_toprow_negative_prompt" + suffix(n, "_")
): ):
w[n].ad_negative_prompt = gr.Textbox( w[n].ad_negative_prompt = gr.Textbox(
label="ad_negative_prompt" + suffix(n), label="ad_negative_prompt" + suffix(n),
show_label=False, show_label=False,
lines=2, lines=2,
placeholder="ADetailer negative prompt" + suffix(n), placeholder="ADetailer negative prompt" + suffix(n),
elem_id="AD_negative_prompt" + suffix(n, "_"), elem_id="AD_negative_prompt" + suffix(n, "_"),
) )
with gr.Group(): with gr.Group():
with gr.Row(): with gr.Row():
@@ -196,86 +198,103 @@ class AfterDetailerScript(scripts.Script):
visible=True, visible=True,
) )
with gr.Group():
with gr.Row(): with gr.Row():
w[n].ad_inpaint_full_res = gr.Checkbox( with gr.Column(variant="compact"):
label="Inpaint at full resolution " + suffix(n), w[n].ad_inpaint_full_res = gr.Checkbox(
value=True, label="Inpaint at full resolution " + suffix(n),
visible=True, value=True,
) visible=True,
w[n].ad_inpaint_full_res_padding = gr.Slider( )
label="Inpaint at full resolution padding, pixels " w[n].ad_inpaint_full_res_padding = gr.Slider(
+ suffix(n), label="Inpaint at full resolution padding, pixels "
minimum=0, + suffix(n),
maximum=256, minimum=0,
step=4, maximum=256,
value=0, step=4,
visible=True, value=0,
) visible=True,
)
with gr.Column(variant="compact"):
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_height = gr.Slider(
label="inpaint height" + suffix(n),
minimum=64,
maximum=2048,
step=4,
value=512,
visible=True,
)
with gr.Row(): with gr.Row():
w[n].ad_use_inpaint_width_height = gr.Checkbox( with gr.Column(variant="compact"):
label="Use separate width/height" + suffix(n), w[n].ad_use_steps = gr.Checkbox(
value=False, label="Use separate steps" + suffix(n),
visible=True, value=False,
) visible=True,
)
w[n].ad_inpaint_width = gr.Slider( w[n].ad_steps = gr.Slider(
label="inpaint width" + suffix(n), label="ADetailer steps" + suffix(n),
minimum=4, minimum=1,
maximum=1024, maximum=150,
step=4, step=1,
value=512, value=28,
visible=True, visible=True,
) )
w[n].ad_inpaint_height = gr.Slider( with gr.Column(variant="compact"):
label="inpaint height" + suffix(n), w[n].ad_use_cfg_scale = gr.Checkbox(
minimum=4, label="Use separate CFG scale" + suffix(n),
maximum=1024, value=False,
step=4, visible=True,
value=512, )
visible=True,
)
with gr.Row(): w[n].ad_cfg_scale = gr.Slider(
w[n].ad_use_cfg_scale = gr.Checkbox( label="ADetailer CFG scale" + suffix(n),
label="Use separate CFG scale" + suffix(n), minimum=0.0,
value=False, maximum=30.0,
visible=True, 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() cn_inpaint_models = ["None"] + get_cn_inpaint_models()
with gr.Group(): w[n].ad_controlnet_model = gr.Dropdown(
with gr.Row(): label="ControlNet model" + suffix(n),
w[n].ad_controlnet_model = gr.Dropdown( choices=cn_inpaint_models,
label="ControlNet model" + suffix(n), value="None",
choices=cn_inpaint_models, visible=True,
value="None", type="value",
visible=True, interactive=controlnet_exists,
type="value", )
interactive=controlnet_exists,
)
with gr.Row(): w[n].ad_controlnet_weight = gr.Slider(
w[n].ad_controlnet_weight = gr.Slider( label="ControlNet weight" + suffix(n),
label="ControlNet weight" + suffix(n), minimum=0.0,
minimum=0.0, maximum=1.0,
maximum=1.0, step=0.05,
step=0.05, value=1.0,
value=1.0, visible=True,
visible=True, interactive=controlnet_exists,
interactive=controlnet_exists, )
)
# Accordion end # Accordion end
@@ -433,6 +452,11 @@ class AfterDetailerScript(scripts.Script):
return width, height 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: def get_cfg_scale(self, p, args: ADetailerArgs) -> float:
if args.ad_use_cfg_scale: if args.ad_use_cfg_scale:
return args.ad_cfg_scale return args.ad_cfg_scale
@@ -479,6 +503,7 @@ class AfterDetailerScript(scripts.Script):
prompt, negative_prompt = self.get_prompt(p, args) prompt, negative_prompt = self.get_prompt(p, args)
seed, subseed = self.get_seed(p) seed, subseed = self.get_seed(p)
width, height = self.get_width_height(p, args) width, height = self.get_width_height(p, args)
steps = self.get_steps(p, args)
cfg_scale = self.get_cfg_scale(p, args) cfg_scale = self.get_cfg_scale(p, args)
sampler_name = p.sampler_name sampler_name = p.sampler_name
@@ -509,7 +534,7 @@ class AfterDetailerScript(scripts.Script):
sampler_name=sampler_name, sampler_name=sampler_name,
batch_size=1, batch_size=1,
n_iter=1, n_iter=1,
steps=p.steps, steps=steps,
cfg_scale=cfg_scale, cfg_scale=cfg_scale,
width=width, width=width,
height=height, height=height,