Download app.py from Doradior/testone: direct link, hf CLI and curl.
- Browser
- Download file 3.98 kB
-
https://huggingface.co/spaces/Doradior/testone/resolve/main/app.py
- Command line
-
hf download hf://spaces/Doradior/testone/app.py
-
curl -L -o app.py https://huggingface.co/spaces/Doradior/testone/resolve/main/app.py
3.98 kB
| import os | |
| import gradio as gr | |
| import torch | |
| import numpy as np | |
| from PIL import Image | |
| import cv2 | |
| from diffusers import StableDiffusionControlNetImg2ImgPipeline, ControlNetModel | |
| import insightface | |
| # ========== CONFIG ========== | |
| device = "cpu" | |
| dtype = torch.float32 | |
| BASE_MODEL = "runwayml/stable-diffusion-v1-5" | |
| CONTROLNET_MODEL = "lllyasviel/control_v11e_sd15_reference_only" | |
| # ========== UTILS ========== | |
| def pil_to_cv(img): | |
| return cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR) | |
| def cv_to_pil(img): | |
| return Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) | |
| def make_grid(images, rows, cols): | |
| w, h = images[0].size | |
| grid = Image.new("RGB", (cols*w, rows*h)) | |
| for i, im in enumerate(images): | |
| grid.paste(im, box=((i % cols) * w, (i // cols) * h)) | |
| return grid | |
| # ========== LOAD MODELS ========== | |
| print("π Loading ControlNet...") | |
| controlnet = ControlNetModel.from_pretrained(CONTROLNET_MODEL, torch_dtype=dtype) | |
| print("π Loading Stable Diffusion pipeline...") | |
| pipe = StableDiffusionControlNetImg2ImgPipeline.from_pretrained( | |
| BASE_MODEL, | |
| controlnet=controlnet, | |
| torch_dtype=dtype, | |
| safety_checker=None | |
| ).to(device) | |
| print("π Loading InsightFace (antelopev2)...") | |
| ins_model = insightface.app.FaceAnalysis(name="antelopev2", providers=["CPUExecutionProvider"]) | |
| ins_model.prepare(ctx_id=0, det_size=(640, 640)) | |
| # ========== MAIN FUNCTION ========== | |
| def generate_grid(init_image, prompt, neg_prompt, steps, cfg, strength, seed, width, height): | |
| if init_image is None: | |
| return None, "β Upload foto dulu." | |
| # Deteksi wajah | |
| cv_img = pil_to_cv(init_image) | |
| faces = ins_model.get(cv_img) | |
| if not faces: | |
| return None, "β Wajah tidak terdeteksi." | |
| # Ambil wajah terbesar | |
| faces.sort(key=lambda f: (f.bbox[2]-f.bbox[0])*(f.bbox[3]-f.bbox[1]), reverse=True) | |
| x1, y1, x2, y2 = map(int, faces[0].bbox) | |
| face_crop = init_image.crop((x1, y1, x2, y2)).resize((width, height)) | |
| # Generator seed | |
| g = torch.Generator(device=device) | |
| if seed >= 0: | |
| g.manual_seed(seed) | |
| images = [] | |
| for i in range(9): | |
| out = pipe( | |
| prompt=prompt, | |
| negative_prompt=neg_prompt if neg_prompt.strip() else None, | |
| image=init_image.resize((width, height)), | |
| control_image=face_crop, | |
| num_inference_steps=steps, | |
| guidance_scale=cfg, | |
| strength=strength, | |
| generator=torch.Generator(device=device).manual_seed( | |
| seed if seed >= 0 else torch.seed() | |
| ) | |
| ).images[0] | |
| images.append(out) | |
| return make_grid(images, 3, 3), f"β Face bbox: {x1},{y1},{x2},{y2}" | |
| # ========== GRADIO UI ========== | |
| with gr.Blocks() as demo: | |
| gr.Markdown("## π€ CPU Face Consistency 3Γ3 Generator (ControlNet Reference-Only + InsightFace)") | |
| with gr.Row(): | |
| with gr.Column(): | |
| init_image = gr.Image(label="Upload Foto Wajah", type="pil") | |
| prompt = gr.Textbox(label="Prompt", value="studio portrait, soft lighting, ultra detailed skin") | |
| neg_prompt = gr.Textbox(label="Negative Prompt", value="blurry, deformed, bad anatomy") | |
| steps = gr.Slider(8, 25, 14, step=1, label="Steps") | |
| cfg = gr.Slider(3, 12, 7.0, step=0.5, label="CFG Scale") | |
| strength = gr.Slider(0.3, 0.8, 0.55, step=0.05, label="Denoising Strength") | |
| width = gr.Slider(320, 512, 384, step=32, label="Width") | |
| height = gr.Slider(320, 512, 384, step=32, label="Height") | |
| seed = gr.Number(value=-1, precision=0, label="Seed (-1 = acak)") | |
| run = gr.Button("Generate 3Γ3") | |
| with gr.Column(): | |
| out_img = gr.Image(label="Output Grid") | |
| log = gr.Markdown() | |
| run.click( | |
| fn=generate_grid, | |
| inputs=[init_image, prompt, neg_prompt, steps, cfg, strength, seed, width, height], | |
| outputs=[out_img, log] | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() | |