2024-04-28 22:12:51 +00:00
|
|
|
from pathlib import Path
|
|
|
|
from typing import Any
|
2023-08-23 19:25:24 +00:00
|
|
|
|
|
|
|
import numpy as np
|
|
|
|
import torch
|
|
|
|
from PIL import Image
|
|
|
|
|
2023-08-31 21:17:41 +00:00
|
|
|
import invokeai.backend.util.logging as logger
|
2024-04-28 22:12:51 +00:00
|
|
|
from invokeai.backend.model_manager.config import AnyModel
|
2023-08-23 19:25:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
def norm_img(np_img):
|
|
|
|
if len(np_img.shape) == 2:
|
|
|
|
np_img = np_img[:, :, np.newaxis]
|
|
|
|
np_img = np.transpose(np_img, (2, 0, 1))
|
|
|
|
np_img = np_img.astype("float32") / 255
|
|
|
|
return np_img
|
|
|
|
|
|
|
|
|
|
|
|
class LaMA:
|
2024-04-28 22:12:51 +00:00
|
|
|
def __init__(self, model: AnyModel):
|
|
|
|
self._model = model
|
2024-03-20 03:17:16 +00:00
|
|
|
|
2024-04-13 01:05:23 +00:00
|
|
|
def __call__(self, input_image: Image.Image, *args: Any, **kwds: Any) -> Any:
|
2023-08-23 19:25:24 +00:00
|
|
|
image = np.asarray(input_image.convert("RGB"))
|
|
|
|
image = norm_img(image)
|
|
|
|
|
|
|
|
mask = input_image.split()[-1]
|
|
|
|
mask = np.asarray(mask)
|
|
|
|
mask = np.invert(mask)
|
|
|
|
mask = norm_img(mask)
|
|
|
|
mask = (mask > 0) * 1
|
|
|
|
|
2024-04-28 22:12:51 +00:00
|
|
|
device = next(self._model.buffers()).device
|
|
|
|
image = torch.from_numpy(image).unsqueeze(0).to(device)
|
|
|
|
mask = torch.from_numpy(mask).unsqueeze(0).to(device)
|
2024-04-13 01:05:23 +00:00
|
|
|
|
2024-04-28 22:12:51 +00:00
|
|
|
with torch.inference_mode():
|
|
|
|
infilled_image = self._model(image, mask)
|
2023-08-23 19:25:24 +00:00
|
|
|
|
|
|
|
infilled_image = infilled_image[0].permute(1, 2, 0).detach().cpu().numpy()
|
|
|
|
infilled_image = np.clip(infilled_image * 255, 0, 255).astype("uint8")
|
|
|
|
infilled_image = Image.fromarray(infilled_image)
|
|
|
|
|
|
|
|
return infilled_image
|
2024-04-28 22:12:51 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def load_jit_model(url_or_path: str | Path, device: torch.device | str = "cpu") -> torch.nn.Module:
|
|
|
|
model_path = url_or_path
|
|
|
|
logger.info(f"Loading model from: {model_path}")
|
|
|
|
model: torch.nn.Module = torch.jit.load(model_path, map_location="cpu").to(device) # type: ignore
|
|
|
|
model.eval()
|
|
|
|
return model
|