mirror of
https://github.com/Bing-su/adetailer.git
synced 2026-05-01 03:31:21 +00:00
Merge branch 'dev' into main
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|||||||
18
README.md
18
README.md
@@ -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.
|
||||||
|
|
||||||
|

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

|

|
||||||

|

|
||||||
|
|
||||||
|
[](https://ko-fi.com/F1F1L7V2N)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
__version__ = "23.5.10"
|
__version__ = "23.5.11"
|
||||||
|
|||||||
@@ -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":
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user