Update app.py
Browse files
app.py
CHANGED
|
@@ -689,68 +689,117 @@ def step1_gpu_refine(
|
|
| 689 |
except Exception:
|
| 690 |
dev = "cpu"; dtype = None # type: ignore
|
| 691 |
|
| 692 |
-
# ---- T-ํฌ์ฆ (ControlNet/OpenPose)
|
| 693 |
if enforce_tpose:
|
| 694 |
try:
|
|
|
|
|
|
|
| 695 |
from diffusers import (
|
| 696 |
ControlNetModel,
|
| 697 |
StableDiffusionControlNetImg2ImgPipeline,
|
| 698 |
DPMSolverMultistepScheduler
|
| 699 |
)
|
| 700 |
-
import
|
|
|
|
| 701 |
|
| 702 |
dev = "cuda" if torch.cuda.is_available() else "cpu"
|
| 703 |
dtype = torch.float16 if dev == "cuda" else torch.float32
|
| 704 |
|
| 705 |
-
#
|
| 706 |
-
|
| 707 |
-
|
| 708 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 709 |
)
|
| 710 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 711 |
"runwayml/stable-diffusion-v1-5",
|
| 712 |
controlnet=controlnet,
|
| 713 |
torch_dtype=dtype,
|
| 714 |
-
safety_checker=None,
|
| 715 |
-
feature_extractor=None,
|
| 716 |
)
|
| 717 |
-
|
| 718 |
-
pipe_pose = _disable_safety(pipe_pose)
|
| 719 |
-
|
| 720 |
-
# โ
๋ ์์ ์ ์ธ Karras DPM-Solver
|
| 721 |
try:
|
| 722 |
-
|
| 723 |
-
|
| 724 |
-
use_karras_sigmas=True
|
| 725 |
)
|
| 726 |
except Exception:
|
| 727 |
pass
|
| 728 |
-
|
| 729 |
-
|
| 730 |
try:
|
| 731 |
-
|
| 732 |
except Exception:
|
| 733 |
pass
|
| 734 |
|
| 735 |
-
#
|
| 736 |
-
|
|
|
|
|
|
|
|
|
|
| 737 |
|
| 738 |
-
#
|
| 739 |
-
|
| 740 |
-
|
| 741 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 742 |
|
| 743 |
-
#
|
| 744 |
-
|
| 745 |
-
|
| 746 |
-
|
| 747 |
-
|
| 748 |
-
|
| 749 |
-
|
| 750 |
-
|
| 751 |
-
|
| 752 |
-
|
| 753 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 754 |
|
| 755 |
# 3) ํ๋กใณใํธ (๋ฐ๊ณ ๋จ์ํ ๋ฐฐ๊ฒฝ + NSFW ๋ฐฉ์ง ๋จ์ด)
|
| 756 |
POS = (
|
|
@@ -798,31 +847,7 @@ def step1_gpu_refine(
|
|
| 798 |
|
| 799 |
out = out_b
|
| 800 |
|
| 801 |
-
|
| 802 |
-
try:
|
| 803 |
-
# ์ผ๊ตด ๋ฐ์ค๋ฅผ MediaPipe ์์ด ์ถ์ (๋์ถฉ ์๋จ ์ค์ 30~35%)
|
| 804 |
-
W,H = out.size
|
| 805 |
-
cx, cy = W//2, int(H*0.30)
|
| 806 |
-
bw, bh = int(W*0.36), int(H*0.28)
|
| 807 |
-
x1, y1 = max(0, cx-bw//2), max(0, cy-bh//2)
|
| 808 |
-
x2, y2 = min(W, cx+bw//2), min(H, cy+bh//2)
|
| 809 |
-
|
| 810 |
-
face_new = out.crop((x1,y1,x2,y2))
|
| 811 |
-
face_old = Image.open(s1_path).convert("RGBA").resize((W,H), Image.LANCZOS).crop((x1,y1,x2,y2))
|
| 812 |
-
|
| 813 |
-
# ์ํํธ ๋ง์คํฌ๋ก ์์ฐ์ค๋ฝ๊ฒ ๋ฎ์ด์์ฐ๊ธฐ
|
| 814 |
-
import numpy as np
|
| 815 |
-
m = Image.new("L", (x2-x1, y2-y1), 0)
|
| 816 |
-
from PIL import ImageFilter
|
| 817 |
-
# ํ์ํ ๋ง์คํฌ
|
| 818 |
-
mm = Image.new("L", m.size, 0)
|
| 819 |
-
draw = ImageDraw.Draw(mm)
|
| 820 |
-
draw.ellipse([4,4,mm.size[0]-5,mm.size[1]-5], fill=255)
|
| 821 |
-
mm = mm.filter(ImageFilter.GaussianBlur(6))
|
| 822 |
-
face_mix = Image.composite(face_old, face_new, mm)
|
| 823 |
-
out.paste(face_mix, (x1,y1), mm)
|
| 824 |
-
except Exception:
|
| 825 |
-
pass
|
| 826 |
|
| 827 |
# 6) ๋๋ฌด ์ด๋์ฐ๋ฉด ๋ฐ๊ธฐ ๋ฆฌํํธ + ์คํจ ์ ์๋ณธ ๋กค๋ฐฑ
|
| 828 |
if _mean_brightness(out) < 16:
|
|
@@ -840,34 +865,26 @@ def step1_gpu_refine(
|
|
| 840 |
|
| 841 |
|
| 842 |
|
| 843 |
-
|
| 844 |
-
|
| 845 |
-
try:
|
| 846 |
from diffusers import StableDiffusionImg2ImgPipeline
|
| 847 |
-
|
| 848 |
-
"runwayml/stable-diffusion-v1-5",
|
| 849 |
-
|
| 850 |
-
safety_checker=None,
|
| 851 |
-
feature_extractor=None,
|
| 852 |
)
|
| 853 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 854 |
|
| 855 |
|
| 856 |
-
if dev == "cuda":
|
| 857 |
-
pipe_redraw.to("cuda")
|
| 858 |
-
|
| 859 |
-
img_for_redraw = _resize_to_multiple(img.convert("RGB"), multiple=8, max_side=768)
|
| 860 |
-
Image.fromarray(img_for_redraw).save(OUT/"step1"/"dbg_04_before_redraw.png")
|
| 861 |
-
|
| 862 |
-
out = pipe_redraw(
|
| 863 |
-
prompt="clean anime illustration, sharp lines, simple solid background, same outfit and colors",
|
| 864 |
-
negative_prompt="deformed, extra limbs, bad anatomy, watermark, text, noisy",
|
| 865 |
-
image=img_for_redraw,
|
| 866 |
-
strength=float(redraw_strength),
|
| 867 |
-
guidance_scale=float(redraw_guidance),
|
| 868 |
-
num_inference_steps=int(redraw_steps),
|
| 869 |
-
).images[0]
|
| 870 |
-
|
| 871 |
img = out.convert("RGBA")
|
| 872 |
img.save(OUT/"step1"/"dbg_05_after_redraw.png")
|
| 873 |
logs.append("img2img ๋ฆฌ๋๋ก์ฐ ์ ์ฉ")
|
|
|
|
| 689 |
except Exception:
|
| 690 |
dev = "cpu"; dtype = None # type: ignore
|
| 691 |
|
|
|
|
| 692 |
if enforce_tpose:
|
| 693 |
try:
|
| 694 |
+
import math, torch
|
| 695 |
+
from PIL import Image
|
| 696 |
from diffusers import (
|
| 697 |
ControlNetModel,
|
| 698 |
StableDiffusionControlNetImg2ImgPipeline,
|
| 699 |
DPMSolverMultistepScheduler
|
| 700 |
)
|
| 701 |
+
from diffusers.utils import load_image
|
| 702 |
+
from diffusers.pipelines.controlnet.multicontrolnet import MultiControlNetModel
|
| 703 |
|
| 704 |
dev = "cuda" if torch.cuda.is_available() else "cpu"
|
| 705 |
dtype = torch.float16 if dev == "cuda" else torch.float32
|
| 706 |
|
| 707 |
+
# --- ์
๋ ฅ/์บ๋ฒ์ค ์ค๋น ---
|
| 708 |
+
base_rgb = _resize_to_multiple(img.convert("RGB"), multiple=8, max_side=512)
|
| 709 |
+
|
| 710 |
+
# ์๋ณธ ํฌ์ฆ ์บ๋ฒ์ค + Tํฌ์ฆ ์บ๋ฒ์ค โ ์ฝ๋ธ๋ ๋(์๋ณธ 80% : T 20%)
|
| 711 |
+
pose_orig = _openpose_canvas_from_image(base_rgb)
|
| 712 |
+
pose_t = _make_tpose_canvas_like(base_rgb)
|
| 713 |
+
pose_canvas= _blend_pose_canvases(pose_orig, pose_t, alpha=0.20).resize(base_rgb.size)
|
| 714 |
+
|
| 715 |
+
# --- Dual ControlNet: OpenPose + Reference-Only ---
|
| 716 |
+
cn_pose = ControlNetModel.from_pretrained(
|
| 717 |
+
"lllyasviel/control_v11p_sd15_openpose", torch_dtype=dtype
|
| 718 |
)
|
| 719 |
+
cn_ref = ControlNetModel.from_pretrained(
|
| 720 |
+
"lllyasviel/control_v11f1e_sd15_tile", torch_dtype=dtype
|
| 721 |
+
)
|
| 722 |
+
# ์ฐธ๊ณ : reference-only๋ tile ๋ชจ๋ธ์์ ref ๋ชจ๋๋ก ๋์ํฉ๋๋ค.
|
| 723 |
+
controlnet = MultiControlNetModel([cn_pose, cn_ref])
|
| 724 |
+
|
| 725 |
+
pipe = StableDiffusionControlNetImg2ImgPipeline.from_pretrained(
|
| 726 |
"runwayml/stable-diffusion-v1-5",
|
| 727 |
controlnet=controlnet,
|
| 728 |
torch_dtype=dtype,
|
| 729 |
+
safety_checker=None, feature_extractor=None,
|
|
|
|
| 730 |
)
|
| 731 |
+
pipe = _disable_safety(pipe)
|
|
|
|
|
|
|
|
|
|
| 732 |
try:
|
| 733 |
+
pipe.scheduler = DPMSolverMultistepScheduler.from_config(
|
| 734 |
+
pipe.scheduler.config, use_karras_sigmas=True
|
|
|
|
| 735 |
)
|
| 736 |
except Exception:
|
| 737 |
pass
|
| 738 |
+
if dev == "cuda":
|
| 739 |
+
pipe.to("cuda")
|
| 740 |
try:
|
| 741 |
+
pipe.enable_vae_slicing()
|
| 742 |
except Exception:
|
| 743 |
pass
|
| 744 |
|
| 745 |
+
# --- ์ปจ๋์
์ด๋ฏธ์ง 2๊ฐ ์ค๋น ---
|
| 746 |
+
control_images = [
|
| 747 |
+
pose_canvas, # 0: ํฌ์ฆ
|
| 748 |
+
base_rgb # 1: ๋ ํผ๋ฐ์ค(์/ํ
์ค์ฒ)
|
| 749 |
+
]
|
| 750 |
|
| 751 |
+
# --- ํ๋กฌํํธ ---
|
| 752 |
+
POS = (
|
| 753 |
+
"clean anime illustration, full body, sharp lines, same outfit and colors as reference, "
|
| 754 |
+
"T-pose tendency, white studio background, bright, high-key lighting"
|
| 755 |
+
)
|
| 756 |
+
NEG = (
|
| 757 |
+
"glitch, collage, cutout, fragments, abstract shapes, mosaic, compression artifacts, "
|
| 758 |
+
"extra limbs, extra fingers, deformed, melted, noisy, text, watermark, black background"
|
| 759 |
+
)
|
| 760 |
|
| 761 |
+
# --- ํ๋ผ๋ฏธ๏ฟฝ๏ฟฝ (์์ ๊ฐ) ---
|
| 762 |
+
steps = int(max(16, min(28, int(tpose_steps))))
|
| 763 |
+
strength = float(max(0.50, min(0.65, float(tpose_strength))))
|
| 764 |
+
guidance = float(max(7.0, min(9.5, float(tpose_guidance))))
|
| 765 |
+
# controlnet ์ํฅ: [OpenPose, Reference]
|
| 766 |
+
cond_scales = [0.22, 0.70] # ํฌ์ฆ๋ ์ฝํ๊ฒ, ๋ ํผ๋ฐ์ค๋ ๊ฐํ๊ฒ
|
| 767 |
+
start_list = [0.05, 0.00] # ํฌ์ฆ๋ ์ด๋ฐ๋ถํฐ, ๋ ํผ๋ฐ์ค๋ ์ ๊ตฌ๊ฐ
|
| 768 |
+
end_list = [0.35, 0.80] # ํฌ์ฆ๋ ์ค๋ฐ๊น์ง๋ง, ๋ ํผ๋ฐ์ค๋ ์ค๋
|
| 769 |
+
|
| 770 |
+
# --- ์คํ ---
|
| 771 |
+
out = pipe(
|
| 772 |
+
prompt=POS, negative_prompt=NEG,
|
| 773 |
+
image=base_rgb,
|
| 774 |
+
control_image=control_images,
|
| 775 |
+
num_inference_steps=steps,
|
| 776 |
+
strength=strength,
|
| 777 |
+
guidance_scale=guidance,
|
| 778 |
+
controlnet_conditioning_scale=cond_scales,
|
| 779 |
+
control_guidance_start=start_list,
|
| 780 |
+
control_guidance_end=end_list,
|
| 781 |
+
guess_mode=True,
|
| 782 |
+
# reference-only ๋ชจ๋: tile controlnet์ ์ ์ฉ๋๋ ํํธ ํ ๊ธ
|
| 783 |
+
# (diffusers 0.29 ๊ธฐ์ค, tile์ ref-like ์ญํ ๋ก ์ถฉ๋ถ)
|
| 784 |
+
).images[0].convert("RGBA")
|
| 785 |
+
|
| 786 |
+
# --- ์ด๋์ ๊ฐ๋ + ๋ฐ๊ธฐ ๋ฆฌํํธ ---
|
| 787 |
+
if _mean_brightness(out) < 16:
|
| 788 |
+
out = _lift_brightness(out, gain=1.18, gamma=0.90)
|
| 789 |
+
if _mean_brightness(out) < 12:
|
| 790 |
+
logs.append("T-ํฌ์ฆ(DualCN) ๊ฒฐ๊ณผ๊ฐ ์ด๋์ ์๋ณธ ์ ์ง")
|
| 791 |
+
else:
|
| 792 |
+
img = out
|
| 793 |
+
try:
|
| 794 |
+
pose_canvas.save(OUT/"step1"/"dbg_pose_blend.png")
|
| 795 |
+
img.save(OUT/"step1"/"dbg_03_after_dualcn.png")
|
| 796 |
+
except Exception:
|
| 797 |
+
pass
|
| 798 |
+
logs.append("T-ํฌ์ฆ(Dual-ControlNet) ์ ์ฉ: Pose 0.22 + Reference 0.70")
|
| 799 |
+
|
| 800 |
+
except Exception as e:
|
| 801 |
+
logs.append(f"T-ํฌ์ฆ Dual-ControlNet ์คํจ: {e}")
|
| 802 |
+
|
| 803 |
|
| 804 |
# 3) ํ๋กใณใํธ (๋ฐ๊ณ ๋จ์ํ ๋ฐฐ๊ฒฝ + NSFW ๋ฐฉ์ง ๋จ์ด)
|
| 805 |
POS = (
|
|
|
|
| 847 |
|
| 848 |
out = out_b
|
| 849 |
|
| 850 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 851 |
|
| 852 |
# 6) ๋๋ฌด ์ด๋์ฐ๋ฉด ๋ฐ๊ธฐ ๋ฆฌํํธ + ์คํจ ์ ์๋ณธ ๋กค๋ฐฑ
|
| 853 |
if _mean_brightness(out) < 16:
|
|
|
|
| 865 |
|
| 866 |
|
| 867 |
|
| 868 |
+
# ---- (์ต์
) ๋ฆฌ๋๋ก์ฐ(img2img)
|
| 869 |
+
if do_redraw_flag:
|
|
|
|
| 870 |
from diffusers import StableDiffusionImg2ImgPipeline
|
| 871 |
+
pr = StableDiffusionImg2ImgPipeline.from_pretrained(
|
| 872 |
+
"runwayml/stable-diffusion-v1-5", torch_dtype=dtype,
|
| 873 |
+
safety_checker=None, feature_extractor=None
|
|
|
|
|
|
|
| 874 |
)
|
| 875 |
+
pr = _disable_safety(pr)
|
| 876 |
+
if dev == "cuda": pr.to("cuda")
|
| 877 |
+
img_for = _resize_to_multiple(img.convert("RGB"), 8, 640)
|
| 878 |
+
img = pr(
|
| 879 |
+
prompt="clean anime illustration, sharp lines, flat colors, plain white background",
|
| 880 |
+
negative_prompt="glitch, mosaic, text, watermark, noisy",
|
| 881 |
+
image=img_for,
|
| 882 |
+
strength=float(max(0.30, min(0.45, float(redraw_strength)))),
|
| 883 |
+
guidance_scale=float(max(6.5, min(9.0, float(redraw_guidance)))),
|
| 884 |
+
num_inference_steps=int(max(14, min(28, int(redraw_steps)))),
|
| 885 |
+
).images[0].convert("RGBA")
|
| 886 |
|
| 887 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 888 |
img = out.convert("RGBA")
|
| 889 |
img.save(OUT/"step1"/"dbg_05_after_redraw.png")
|
| 890 |
logs.append("img2img ๋ฆฌ๋๋ก์ฐ ์ ์ฉ")
|