Views
No views yet
















1from diffusers import ControlNetModel, StableDiffusionXLControlNetPipeline, AutoencoderKL
2from diffusers import DDIMScheduler, EulerAncestralDiscreteScheduler
3from controlnet_aux import PidiNetDetector, HEDdetector
4from diffusers.utils import load_image
5from huggingface_hub import HfApi
6from pathlib import Path
7from PIL import Image
8import torch
9import numpy as np
10import cv2
11import os
12
13
14def nms(x, t, s):
15 x = cv2.GaussianBlur(x.astype(np.float32), (0, 0), s)
16
17 f1 = np.array([[0, 0, 0], [1, 1, 1], [0, 0, 0]], dtype=np.uint8)
18 f2 = np.array([[0, 1, 0], [0, 1, 0], [0, 1, 0]], dtype=np.uint8)
19 f3 = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype=np.uint8)
20 f4 = np.array([[0, 0, 1], [0, 1, 0], [1, 0, 0]], dtype=np.uint8)
21
22 y = np.zeros_like(x)
23
24 for f in [f1, f2, f3, f4]:
25 np.putmask(y, cv2.dilate(x, kernel=f) == x, x)
26
27 z = np.zeros_like(y, dtype=np.uint8)
28 z[y > t] = 255
29 return z
30
31
32controlnet_conditioning_scale = 1.0
33prompt = "your prompt, the longer the better, you can describe it as detail as possible"
34negative_prompt = 'longbody, lowres, bad anatomy, bad hands, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality'
35
36
37eulera_scheduler = EulerAncestralDiscreteScheduler.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", subfolder="scheduler")
38
39
40controlnet = ControlNetModel.from_pretrained(
41 "xinsir/controlnet-scribble-sdxl-1.0",
42 torch_dtype=torch.float16
43)
44
45# when test with other base model, you need to change the vae also.
46vae = AutoencoderKL.from_pretrained("madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16)
47
48pipe = StableDiffusionXLControlNetPipeline.from_pretrained(
49 "stabilityai/stable-diffusion-xl-base-1.0",
50 controlnet=controlnet,
51 vae=vae,
52 safety_checker=None,
53 torch_dtype=torch.float16,
54 scheduler=eulera_scheduler,
55)
56
57# you can use either hed to generate a fake scribble given an image or a sketch image totally draw by yourself
58
59if random.random() > 0.5:
60 # Method 1
61 # if you use hed, you should provide an image, the image can be real or anime, you extract its hed lines and use it as the scribbles
62 # The detail about hed detect you can refer to https://github.com/lllyasviel/ControlNet/blob/main/gradio_fake_scribble2image.py
63 # Below is a example using diffusers HED detector
64
65 # image_path = Image.open("your image path, the image can be real or anime, HED detector will extract its edge boundery")
66 image_path = cv2.imread("your image path, the image can be real or anime, HED detector will extract its edge boundery")
67 processor = HEDdetector.from_pretrained('lllyasviel/Annotators')
68 controlnet_img = processor(image_path, scribble=False)
69 controlnet_img.save("a hed detect path for an image")
70
71 # following is some processing to simulate human sketch draw, different threshold can generate different width of lines
72 controlnet_img = np.array(controlnet_img)
73 controlnet_img = nms(controlnet_img, 127, 3)
74 controlnet_img = cv2.GaussianBlur(controlnet_img, (0, 0), 3)
75
76 # higher threshold, thiner line
77 random_val = int(round(random.uniform(0.01, 0.10), 2) * 255)
78 controlnet_img[controlnet_img > random_val] = 255
79 controlnet_img[controlnet_img < 255] = 0
80 controlnet_img = Image.fromarray(controlnet_img)
81
82else:
83 # Method 2
84 # if you use a sketch image total draw by yourself
85 control_path = "the sketch image you draw with some tools, like drawing board, the path you save it"
86 controlnet_img = Image.open(control_path) # Note that the image must be black-white(0 or 255), like the examples we list
87
88# must resize to 1024*1024 or same resolution bucket to get the best performance
89width, height = controlnet_img.size
90ratio = np.sqrt(1024. * 1024. / (width * height))
91new_width, new_height = int(width * ratio), int(height * ratio)
92controlnet_img = controlnet_img.resize((new_width, new_height))
93
94images = pipe(
95 prompt,
96 negative_prompt=negative_prompt,
97 image=controlnet_img,
98 controlnet_conditioning_scale=controlnet_conditioning_scale,
99 width=new_width,
100 height=new_height,
101 num_inference_steps=30,
102 ).images
103
104images[0].save(f"your image save path, png format is usually better than jpg or webp in terms of image quality but got much bigger")| metric | xinsir/controlnet-scribble-sdxl-1.0 |
|---|---|
| laion_aesthetic | 6.03 |
| perceptual similarity | 0.5701 |