Update handler.py
Browse files- handler.py +57 -8
handler.py
CHANGED
|
@@ -24,13 +24,30 @@ class EndpointHandler():
|
|
| 24 |
# "stabilityai/stable-diffusion-xl-refiner-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
|
| 25 |
# )
|
| 26 |
# self.smooth_pipe.to("cuda")
|
| 27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
self.controlnet = ControlNetModel.from_pretrained(
|
| 29 |
"lllyasviel/control_v11p_sd15_inpaint", torch_dtype=torch.float16
|
| 30 |
)
|
|
|
|
| 31 |
|
| 32 |
self.pipe = StableDiffusionControlNetInpaintPipeline.from_pretrained(
|
| 33 |
-
"runwayml/stable-diffusion-v1-5", controlnet=self.
|
| 34 |
)
|
| 35 |
|
| 36 |
self.pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(self.pipe.scheduler.config)
|
|
@@ -158,18 +175,50 @@ class EndpointHandler():
|
|
| 158 |
|
| 159 |
control_image = self.make_inpaint_condition(image, mask_image)
|
| 160 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
# generate image
|
| 162 |
image = self.pipe(
|
| 163 |
prompt=prompt,
|
| 164 |
negative_prompt=negative_prompt,
|
| 165 |
num_inference_steps=num_inference_steps,
|
| 166 |
eta=1.0,
|
| 167 |
-
image=
|
| 168 |
-
mask_image=mask_image,
|
| 169 |
-
control_image=control_image,
|
| 170 |
-
guidance_scale=guidance_scale,
|
| 171 |
strength=strength,
|
| 172 |
-
controlnet_conditioning_scale=0.
|
| 173 |
).images[0]
|
| 174 |
|
| 175 |
return image
|
|
@@ -190,4 +239,4 @@ class EndpointHandler():
|
|
| 190 |
image[image_mask > 0.5] = -1.0 # set as masked pixel
|
| 191 |
image = np.expand_dims(image, 0).transpose(0, 3, 1, 2)
|
| 192 |
image = torch.from_numpy(image)
|
| 193 |
-
return image
|
|
|
|
| 24 |
# "stabilityai/stable-diffusion-xl-refiner-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
|
| 25 |
# )
|
| 26 |
# self.smooth_pipe.to("cuda")
|
| 27 |
+
|
| 28 |
+
self.canny_pipe = StableDiffusionPipeline.from_pretrained(
|
| 29 |
+
"runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16
|
| 30 |
+
)
|
| 31 |
+
self.canny_pipe = self.canny_pipe.to("cuda")
|
| 32 |
+
self.canny_pipe.enable_model_cpu_offload()
|
| 33 |
+
self.canny_pipe.enable_xformers_memory_efficient_attention()
|
| 34 |
+
|
| 35 |
+
self.controlnets = [
|
| 36 |
+
ControlNetModel.from_pretrained(
|
| 37 |
+
"diffusers/controlnet-canny-sdxl-1.0", torch_dtype=torch.float16, use_safetensors=True
|
| 38 |
+
),
|
| 39 |
+
ControlNetModel.from_pretrained(
|
| 40 |
+
"lllyasviel/control_v11p_sd15_inpaint", torch_dtype=torch.float16
|
| 41 |
+
)
|
| 42 |
+
]
|
| 43 |
+
"""
|
| 44 |
self.controlnet = ControlNetModel.from_pretrained(
|
| 45 |
"lllyasviel/control_v11p_sd15_inpaint", torch_dtype=torch.float16
|
| 46 |
)
|
| 47 |
+
"""
|
| 48 |
|
| 49 |
self.pipe = StableDiffusionControlNetInpaintPipeline.from_pretrained(
|
| 50 |
+
"runwayml/stable-diffusion-v1-5", controlnet=self.controlnets, torch_dtype=torch.float16
|
| 51 |
)
|
| 52 |
|
| 53 |
self.pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(self.pipe.scheduler.config)
|
|
|
|
| 175 |
|
| 176 |
control_image = self.make_inpaint_condition(image, mask_image)
|
| 177 |
|
| 178 |
+
low_threshold = 100
|
| 179 |
+
high_threshold = 200
|
| 180 |
+
|
| 181 |
+
# generate a first version of the prompt for the canny image
|
| 182 |
+
gen_canny_img = self.canny_pipe(prompt).images[0]
|
| 183 |
+
|
| 184 |
+
gen_canny_img = np.array(gen_canny_img)
|
| 185 |
+
|
| 186 |
+
help_image = cv2.Canny(gen_canny_img, low_threshold, high_threshold)
|
| 187 |
+
|
| 188 |
+
# get bounding box from selected area in mask image
|
| 189 |
+
# make help_image fit exactly into the bounding box
|
| 190 |
+
# create black image with canny edges only in the selected area
|
| 191 |
+
|
| 192 |
+
# get bounding box from selected area in mask image
|
| 193 |
+
mask_image = np.array(mask_image)
|
| 194 |
+
mask_image = cv2.cvtColor(mask_image, cv2.COLOR_RGB2GRAY)
|
| 195 |
+
mask_image = cv2.bitwise_not(mask_image)
|
| 196 |
+
contours, _ = cv2.findContours(mask_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
| 197 |
+
x, y, w, h = cv2.boundingRect(contours[0])
|
| 198 |
+
|
| 199 |
+
# create a completely black image with the same size as the mask image
|
| 200 |
+
black_image = np.zeros_like(mask_image)
|
| 201 |
+
|
| 202 |
+
# put the canny edges into the black image but resize it to the bounding box
|
| 203 |
+
help_image = cv2.resize(help_image, (w, h))
|
| 204 |
+
black_image[y:y+h, x:x+w] = help_image
|
| 205 |
+
|
| 206 |
+
canny_image = Image.fromarray(black_image)
|
| 207 |
+
|
| 208 |
+
input_images = [canny_image.resize((1024, 1024)), image.resize((1024, 1024))]
|
| 209 |
+
|
| 210 |
# generate image
|
| 211 |
image = self.pipe(
|
| 212 |
prompt=prompt,
|
| 213 |
negative_prompt=negative_prompt,
|
| 214 |
num_inference_steps=num_inference_steps,
|
| 215 |
eta=1.0,
|
| 216 |
+
image=input_images,
|
| 217 |
+
# mask_image=mask_image,
|
| 218 |
+
# control_image=control_image,
|
| 219 |
+
# guidance_scale=guidance_scale,
|
| 220 |
strength=strength,
|
| 221 |
+
controlnet_conditioning_scale=[0.8, 1.0]
|
| 222 |
).images[0]
|
| 223 |
|
| 224 |
return image
|
|
|
|
| 239 |
image[image_mask > 0.5] = -1.0 # set as masked pixel
|
| 240 |
image = np.expand_dims(image, 0).transpose(0, 3, 1, 2)
|
| 241 |
image = torch.from_numpy(image)
|
| 242 |
+
return image
|