| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- import os
- import random
- import time
- import cv2
- import numpy as np
- import torch
- from loguru import logger
- from sorawm.iopaint.helper import download_model, get_cache_path_by_url, load_jit_model
- from sorawm.iopaint.schema import InpaintRequest
- from .base import InpaintModel
- MANGA_INPAINTOR_MODEL_URL = os.environ.get(
- "MANGA_INPAINTOR_MODEL_URL",
- "https://github.com/Sanster/models/releases/download/manga/manga_inpaintor.jit",
- )
- MANGA_INPAINTOR_MODEL_MD5 = os.environ.get(
- "MANGA_INPAINTOR_MODEL_MD5", "7d8b269c4613b6b3768af714610da86c"
- )
- MANGA_LINE_MODEL_URL = os.environ.get(
- "MANGA_LINE_MODEL_URL",
- "https://github.com/Sanster/models/releases/download/manga/erika.jit",
- )
- MANGA_LINE_MODEL_MD5 = os.environ.get(
- "MANGA_LINE_MODEL_MD5", "0c926d5a4af8450b0d00bc5b9a095644"
- )
- class Manga(InpaintModel):
- name = "manga"
- pad_mod = 16
- is_erase_model = True
- def init_model(self, device, **kwargs):
- self.inpaintor_model = load_jit_model(
- MANGA_INPAINTOR_MODEL_URL, device, MANGA_INPAINTOR_MODEL_MD5
- )
- self.line_model = load_jit_model(
- MANGA_LINE_MODEL_URL, device, MANGA_LINE_MODEL_MD5
- )
- self.seed = 42
- @staticmethod
- def download():
- download_model(MANGA_INPAINTOR_MODEL_URL, MANGA_INPAINTOR_MODEL_MD5)
- download_model(MANGA_LINE_MODEL_URL, MANGA_LINE_MODEL_MD5)
- @staticmethod
- def is_downloaded() -> bool:
- model_paths = [
- get_cache_path_by_url(MANGA_INPAINTOR_MODEL_URL),
- get_cache_path_by_url(MANGA_LINE_MODEL_URL),
- ]
- return all([os.path.exists(it) for it in model_paths])
- def forward(self, image, mask, config: InpaintRequest):
- """
- image: [H, W, C] RGB
- mask: [H, W, 1]
- return: BGR IMAGE
- """
- seed = self.seed
- random.seed(seed)
- np.random.seed(seed)
- torch.manual_seed(seed)
- torch.cuda.manual_seed_all(seed)
- gray_img = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
- gray_img = torch.from_numpy(
- gray_img[np.newaxis, np.newaxis, :, :].astype(np.float32)
- ).to(self.device)
- start = time.time()
- lines = self.line_model(gray_img)
- torch.cuda.empty_cache()
- lines = torch.clamp(lines, 0, 255)
- logger.info(f"erika_model time: {time.time() - start}")
- mask = torch.from_numpy(mask[np.newaxis, :, :, :]).to(self.device)
- mask = mask.permute(0, 3, 1, 2)
- mask = torch.where(mask > 0.5, 1.0, 0.0)
- noise = torch.randn_like(mask)
- ones = torch.ones_like(mask)
- gray_img = gray_img / 255 * 2 - 1.0
- lines = lines / 255 * 2 - 1.0
- start = time.time()
- inpainted_image = self.inpaintor_model(gray_img, lines, mask, noise, ones)
- logger.info(f"image_inpaintor_model time: {time.time() - start}")
- cur_res = inpainted_image[0].permute(1, 2, 0).detach().cpu().numpy()
- cur_res = (cur_res * 127.5 + 127.5).astype(np.uint8)
- cur_res = cv2.cvtColor(cur_res, cv2.COLOR_GRAY2BGR)
- return cur_res
|