mirror of
https://github.com/Bing-su/adetailer.git
synced 2026-04-22 07:18:55 +00:00
Merge branch 'dev' into main
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
rev: v4.5.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
args: [--markdown-linebreak-ext=md]
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## 2023-10-15
|
||||
|
||||
- v23.10.1
|
||||
- xyz grid에 prompt S/R 추가
|
||||
- img2img에서 steps가 1일때 에러가 발생하는 샘플러의 처리를 위해 샘플러 이름도 변경하게 수정
|
||||
|
||||
## 2023-10-07
|
||||
|
||||
- v23.10.0
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "23.10.0"
|
||||
__version__ = "23.10.1"
|
||||
|
||||
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
from functools import partial
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
@@ -67,23 +68,6 @@ def mediapipe_face_detection(
|
||||
return PredictOutput(bboxes=bboxes, masks=masks, preview=preview)
|
||||
|
||||
|
||||
def get_convexhull(points: np.ndarray) -> list[tuple[int, int]]:
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
points: An ndarray of shape (n, 2) containing the 2D points.
|
||||
|
||||
Returns
|
||||
-------
|
||||
list[tuple[int, int]]: Input for the draw.polygon function
|
||||
"""
|
||||
from scipy.spatial import ConvexHull
|
||||
|
||||
hull = ConvexHull(points)
|
||||
vertices = hull.vertices
|
||||
return list(zip(points[vertices, 0], points[vertices, 1]))
|
||||
|
||||
|
||||
def mediapipe_face_mesh(image: Image.Image, confidence: float = 0.3) -> PredictOutput:
|
||||
import mediapipe as mp
|
||||
|
||||
@@ -114,8 +98,8 @@ def mediapipe_face_mesh(image: Image.Image, confidence: float = 0.3) -> PredictO
|
||||
connection_drawing_spec=drawing_styles.get_default_face_mesh_tesselation_style(),
|
||||
)
|
||||
|
||||
points = np.array([(land.x * w, land.y * h) for land in landmarks.landmark])
|
||||
outline = get_convexhull(points)
|
||||
points = np.intp([(land.x * w, land.y * h) for land in landmarks.landmark])
|
||||
outline = cv2.convexHull(points).reshape(-1).tolist()
|
||||
|
||||
mask = Image.new("L", image.size, "black")
|
||||
draw = ImageDraw.Draw(mask)
|
||||
@@ -152,11 +136,11 @@ def mediapipe_face_mesh_eyes_only(
|
||||
masks = []
|
||||
|
||||
for landmarks in pred.multi_face_landmarks:
|
||||
points = np.array([(land.x * w, land.y * h) for land in landmarks.landmark])
|
||||
points = np.intp([(land.x * w, land.y * h) for land in landmarks.landmark])
|
||||
left_eyes = points[left_idx]
|
||||
right_eyes = points[right_idx]
|
||||
left_outline = get_convexhull(left_eyes)
|
||||
right_outline = get_convexhull(right_eyes)
|
||||
left_outline = cv2.convexHull(left_eyes).reshape(-1).tolist()
|
||||
right_outline = cv2.convexHull(right_eyes).reshape(-1).tolist()
|
||||
|
||||
mask = Image.new("L", image.size, "black")
|
||||
draw = ImageDraw.Draw(mask)
|
||||
|
||||
@@ -217,7 +217,7 @@ def detection(w: Widgets, n: int, is_img2img: bool):
|
||||
)
|
||||
w.ad_mask_k_largest = gr.Slider(
|
||||
label="Mask only the top k largest (0 to disable)" + suffix(n),
|
||||
minumum=0,
|
||||
minimum=0,
|
||||
maximum=10,
|
||||
step=1,
|
||||
value=0,
|
||||
|
||||
@@ -44,8 +44,8 @@ def run_pip(*args):
|
||||
def install():
|
||||
deps = [
|
||||
# requirements
|
||||
("ultralytics", "8.0.194", None),
|
||||
("mediapipe", "0.10.5", None),
|
||||
("ultralytics", "8.0.198", None),
|
||||
("mediapipe", "0.10.7", None),
|
||||
("rich", "13.0.0", None),
|
||||
# mediapipe
|
||||
("protobuf", "3.20", "3.9999"),
|
||||
|
||||
@@ -10,7 +10,7 @@ from copy import copy, deepcopy
|
||||
from functools import partial
|
||||
from pathlib import Path
|
||||
from textwrap import dedent
|
||||
from typing import Any
|
||||
from typing import Any, NamedTuple
|
||||
|
||||
import gradio as gr
|
||||
import torch
|
||||
@@ -100,6 +100,22 @@ def preseve_prompts(p):
|
||||
p.all_negative_prompts = all_ng
|
||||
|
||||
|
||||
@contextmanager
|
||||
def change_skip_img2img_args(p):
|
||||
if not hasattr(p, "_ad_skip_img2img") or not p._ad_skip_img2img:
|
||||
yield
|
||||
else:
|
||||
steps = p.steps
|
||||
sampler_name = p.sampler_name
|
||||
try:
|
||||
p.steps = p._ad_orig_steps
|
||||
p.sampler_name = p._ad_orig_sampler_name
|
||||
yield
|
||||
finally:
|
||||
p.steps = steps
|
||||
p.sampler_name = sampler_name
|
||||
|
||||
|
||||
class AfterDetailerScript(scripts.Script):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@@ -201,7 +217,9 @@ class AfterDetailerScript(scripts.Script):
|
||||
p._ad_skip_img2img = args_[1]
|
||||
if args_[1]:
|
||||
p._ad_orig_steps = p.steps
|
||||
p._ad_orig_sampler_name = p.sampler_name
|
||||
p.steps = 1
|
||||
p.sampler_name = "Euler"
|
||||
else:
|
||||
p._ad_skip_img2img = False
|
||||
|
||||
@@ -270,7 +288,12 @@ class AfterDetailerScript(scripts.Script):
|
||||
return all_prompts[j]
|
||||
|
||||
def _get_prompt(
|
||||
self, ad_prompt: str, all_prompts: list[str], i: int, default: str
|
||||
self,
|
||||
ad_prompt: str,
|
||||
all_prompts: list[str],
|
||||
i: int,
|
||||
default: str,
|
||||
replacements: list[PromptSR],
|
||||
) -> list[str]:
|
||||
prompts = re.split(r"\s*\[SEP\]\s*", ad_prompt)
|
||||
blank_replacement = self.prompt_blank_replacement(all_prompts, i, default)
|
||||
@@ -279,14 +302,22 @@ class AfterDetailerScript(scripts.Script):
|
||||
prompts[n] = blank_replacement
|
||||
elif "[PROMPT]" in prompts[n]:
|
||||
prompts[n] = prompts[n].replace("[PROMPT]", f" {blank_replacement} ")
|
||||
|
||||
for pair in replacements:
|
||||
prompts[n] = prompts[n].replace(pair.s, pair.r)
|
||||
return prompts
|
||||
|
||||
def get_prompt(self, p, args: ADetailerArgs) -> tuple[list[str], list[str]]:
|
||||
i = p._ad_idx
|
||||
prompt_sr = p._ad_xyz_prompt_sr if hasattr(p, "_ad_xyz_prompt_sr") else []
|
||||
|
||||
prompt = self._get_prompt(args.ad_prompt, p.all_prompts, i, p.prompt)
|
||||
prompt = self._get_prompt(args.ad_prompt, p.all_prompts, i, p.prompt, prompt_sr)
|
||||
negative_prompt = self._get_prompt(
|
||||
args.ad_negative_prompt, p.all_negative_prompts, i, p.negative_prompt
|
||||
args.ad_negative_prompt,
|
||||
p.all_negative_prompts,
|
||||
i,
|
||||
p.negative_prompt,
|
||||
prompt_sr,
|
||||
)
|
||||
|
||||
return prompt, negative_prompt
|
||||
@@ -333,7 +364,11 @@ class AfterDetailerScript(scripts.Script):
|
||||
return args.ad_cfg_scale if args.ad_use_cfg_scale else p.cfg_scale
|
||||
|
||||
def get_sampler(self, p, args: ADetailerArgs) -> str:
|
||||
return args.ad_sampler if args.ad_use_sampler else p.sampler_name
|
||||
if args.ad_use_sampler:
|
||||
return args.ad_sampler
|
||||
if hasattr(p, "_ad_orig_sampler_name"):
|
||||
return p._ad_orig_sampler_name
|
||||
return p.sampler_name
|
||||
|
||||
def get_override_settings(self, p, args: ADetailerArgs) -> dict[str, Any]:
|
||||
d = {}
|
||||
@@ -371,19 +406,13 @@ class AfterDetailerScript(scripts.Script):
|
||||
if i % lenp != lenp - 1:
|
||||
return
|
||||
|
||||
prev = None
|
||||
if hasattr(p, "_ad_orig_steps"):
|
||||
prev = p.steps
|
||||
p.steps = p._ad_orig_steps
|
||||
with change_skip_img2img_args(p):
|
||||
infotext = self.infotext(p)
|
||||
|
||||
infotext = self.infotext(p)
|
||||
params_txt = Path(data_path, "params.txt")
|
||||
with suppress(Exception):
|
||||
params_txt.write_text(infotext, encoding="utf-8")
|
||||
|
||||
if hasattr(p, "_ad_orig_steps"):
|
||||
p.steps = prev
|
||||
|
||||
def script_filter(self, p, args: ADetailerArgs):
|
||||
script_runner = copy(p.scripts)
|
||||
script_args = deepcopy(p.script_args)
|
||||
@@ -785,6 +814,27 @@ def on_ui_settings():
|
||||
# xyz_grid
|
||||
|
||||
|
||||
class PromptSR(NamedTuple):
|
||||
s: str
|
||||
r: str
|
||||
|
||||
|
||||
def set_value(p, x: Any, xs: Any, *, field: str):
|
||||
if not hasattr(p, "_ad_xyz"):
|
||||
p._ad_xyz = {}
|
||||
p._ad_xyz[field] = x
|
||||
|
||||
|
||||
def search_and_replace_prompt(p, x: Any, xs: Any, replace_in_main_prompt: bool):
|
||||
if replace_in_main_prompt:
|
||||
p.prompt = p.prompt.replace(xs[0], x)
|
||||
p.negative_prompt = p.negative_prompt.replace(xs[0], x)
|
||||
|
||||
if not hasattr(p, "_ad_xyz_prompt_sr"):
|
||||
p._ad_xyz_prompt_sr = []
|
||||
p._ad_xyz_prompt_sr.append(PromptSR(s=xs[0], r=x))
|
||||
|
||||
|
||||
def make_axis_on_xyz_grid():
|
||||
xyz_grid = None
|
||||
for script in scripts.scripts_data:
|
||||
@@ -798,11 +848,6 @@ def make_axis_on_xyz_grid():
|
||||
model_list = ["None", *model_mapping.keys()]
|
||||
samplers = [sampler.name for sampler in all_samplers]
|
||||
|
||||
def set_value(p, x, xs, *, field: str):
|
||||
if not hasattr(p, "_ad_xyz"):
|
||||
p._ad_xyz = {}
|
||||
p._ad_xyz[field] = x
|
||||
|
||||
axis = [
|
||||
xyz_grid.AxisOption(
|
||||
"[ADetailer] ADetailer model 1st",
|
||||
@@ -820,6 +865,16 @@ def make_axis_on_xyz_grid():
|
||||
str,
|
||||
partial(set_value, field="ad_negative_prompt"),
|
||||
),
|
||||
xyz_grid.AxisOption(
|
||||
"[ADetailer] Prompt S/R (AD 1st)",
|
||||
str,
|
||||
partial(search_and_replace_prompt, replace_in_main_prompt=False),
|
||||
),
|
||||
xyz_grid.AxisOption(
|
||||
"[ADetailer] Prompt S/R (AD 1st and main prompt)",
|
||||
str,
|
||||
partial(search_and_replace_prompt, replace_in_main_prompt=True),
|
||||
),
|
||||
xyz_grid.AxisOption(
|
||||
"[ADetailer] Mask erosion / dilation 1st",
|
||||
int,
|
||||
|
||||
Reference in New Issue
Block a user