2022-09-24 05:58:48 +00:00
|
|
|
from typing import Sequence
|
|
|
|
|
|
|
|
import numpy as np
|
|
|
|
import PIL
|
|
|
|
import torch
|
|
|
|
from einops import rearrange, repeat
|
|
|
|
from PIL import Image
|
|
|
|
|
|
|
|
from imaginairy.utils import get_device
|
|
|
|
|
|
|
|
|
2023-01-01 22:54:49 +00:00
|
|
|
def pillow_fit_image_within(
|
|
|
|
image: PIL.Image.Image, max_height=512, max_width=512, convert="RGB"
|
|
|
|
):
|
|
|
|
image = image.convert(convert)
|
2022-09-24 05:58:48 +00:00
|
|
|
w, h = image.size
|
2022-10-06 06:13:48 +00:00
|
|
|
resize_ratio = 1
|
2022-09-24 21:41:25 +00:00
|
|
|
if w > max_width or h > max_height:
|
|
|
|
resize_ratio = min(max_width / w, max_height / h)
|
2022-10-06 06:13:48 +00:00
|
|
|
elif w < max_width and h < max_height:
|
|
|
|
# it's smaller than our target image, enlarge
|
|
|
|
resize_ratio = max(max_width / w, max_height / h)
|
|
|
|
|
|
|
|
if resize_ratio != 1:
|
2022-09-24 21:41:25 +00:00
|
|
|
w, h = int(w * resize_ratio), int(h * resize_ratio)
|
2023-01-02 04:14:22 +00:00
|
|
|
# resize to integer multiple of 64
|
|
|
|
w -= w % 64
|
|
|
|
h -= h % 64
|
|
|
|
|
2022-10-06 06:13:48 +00:00
|
|
|
if (w, h) != image.size:
|
2022-09-24 21:41:25 +00:00
|
|
|
image = image.resize((w, h), resample=Image.Resampling.LANCZOS)
|
2022-09-24 07:29:45 +00:00
|
|
|
return image
|
2022-09-24 05:58:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
def pillow_img_to_torch_image(img: PIL.Image.Image):
|
|
|
|
img = img.convert("RGB")
|
|
|
|
img = np.array(img).astype(np.float32) / 255.0
|
|
|
|
img = img[None].transpose(0, 3, 1, 2)
|
|
|
|
img = torch.from_numpy(img)
|
|
|
|
return 2.0 * img - 1.0
|
|
|
|
|
|
|
|
|
|
|
|
def pillow_img_to_opencv_img(img: PIL.Image.Image):
|
|
|
|
open_cv_image = np.array(img)
|
|
|
|
# Convert RGB to BGR
|
|
|
|
open_cv_image = open_cv_image[:, :, ::-1].copy()
|
|
|
|
return open_cv_image
|
|
|
|
|
|
|
|
|
|
|
|
def model_latents_to_pillow_imgs(latents: torch.Tensor) -> Sequence[PIL.Image.Image]:
|
2022-10-23 21:46:45 +00:00
|
|
|
from imaginairy.model_manager import get_current_diffusion_model # noqa
|
2022-09-24 05:58:48 +00:00
|
|
|
|
2022-10-23 21:46:45 +00:00
|
|
|
model = get_current_diffusion_model()
|
2022-09-24 05:58:48 +00:00
|
|
|
latents = model.decode_first_stage(latents)
|
|
|
|
latents = torch.clamp((latents + 1.0) / 2.0, min=0.0, max=1.0)
|
|
|
|
imgs = []
|
|
|
|
for latent in latents:
|
|
|
|
latent = 255.0 * rearrange(latent.cpu().numpy(), "c h w -> h w c")
|
|
|
|
img = Image.fromarray(latent.astype(np.uint8))
|
|
|
|
imgs.append(img)
|
|
|
|
return imgs
|
|
|
|
|
|
|
|
|
|
|
|
def pillow_img_to_model_latent(model, img, batch_size=1, half=True):
|
|
|
|
# init_image = pil_img_to_torch(img, half=half).to(device)
|
|
|
|
init_image = pillow_img_to_torch_image(img).to(get_device())
|
|
|
|
init_image = repeat(init_image, "1 ... -> b ...", b=batch_size)
|
|
|
|
if half:
|
|
|
|
return model.get_first_stage_encoding(
|
|
|
|
model.encode_first_stage(init_image.half())
|
|
|
|
)
|
|
|
|
return model.get_first_stage_encoding(model.encode_first_stage(init_image))
|
2023-01-22 01:36:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
def make_gif_image(filepath, imgs, duration=1000, loop=0):
|
|
|
|
|
|
|
|
imgs[0].save(
|
|
|
|
filepath,
|
|
|
|
save_all=True,
|
|
|
|
append_images=imgs[1:],
|
|
|
|
duration=duration,
|
|
|
|
loop=loop,
|
|
|
|
optimize=False,
|
|
|
|
)
|