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
### 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

View File

@@ -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)

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_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"
@@ -87,11 +91,25 @@ 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 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":

View File

@@ -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

View File

@@ -7,6 +7,7 @@ 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
@@ -64,7 +65,7 @@ class ChangeTorchLoad:
torch.load = self.orig
def gr_show(visible=True):
def gr_show(visible: bool = True):
return {"visible": visible, "__type__": "update"}
@@ -119,25 +120,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,86 +198,103 @@ 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),
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(variant="compact"):
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(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():
w[n].ad_use_inpaint_width_height = gr.Checkbox(
label="Use separate width/height" + suffix(n),
value=False,
visible=True,
)
with gr.Column(variant="compact"):
w[n].ad_use_steps = gr.Checkbox(
label="Use separate steps" + suffix(n),
value=False,
visible=True,
)
w[n].ad_inpaint_width = gr.Slider(
label="inpaint width" + suffix(n),
minimum=4,
maximum=1024,
step=4,
value=512,
visible=True,
)
w[n].ad_steps = gr.Slider(
label="ADetailer steps" + suffix(n),
minimum=1,
maximum=150,
step=1,
value=28,
visible=True,
)
w[n].ad_inpaint_height = gr.Slider(
label="inpaint height" + suffix(n),
minimum=4,
maximum=1024,
step=4,
value=512,
visible=True,
)
with gr.Column(variant="compact"):
w[n].ad_use_cfg_scale = gr.Checkbox(
label="Use separate CFG scale" + suffix(n),
value=False,
visible=True,
)
with gr.Row():
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
@@ -433,6 +452,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
@@ -479,6 +503,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
@@ -509,7 +534,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,