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
|