🎨 完整的 IOPaint 项目更新
## 主要更新 - ✨ 更新所有依赖到最新稳定版本 - 📝 添加详细的项目文档和模型推荐 - 🔧 配置 VSCode Cloud Studio 预览功能 - 🐛 修复 PyTorch API 弃用警告 ## 依赖更新 - diffusers: 0.27.2 → 0.35.2 - gradio: 4.21.0 → 5.46.0 - peft: 0.7.1 → 0.18.0 - Pillow: 9.5.0 → 11.3.0 - fastapi: 0.108.0 → 0.116.2 ## 新增文件 - CLAUDE.md - 项目架构和开发指南 - UPGRADE_NOTES.md - 详细的升级说明 - .vscode/preview.yml - 预览配置 - .vscode/LAUNCH_GUIDE.md - 启动指南 - .gitignore - 更新的忽略规则 ## 代码修复 - 修复 iopaint/model/ldm.py 中的 torch.cuda.amp.autocast() 弃用警告 ## 文档更新 - README.md - 添加模型推荐和使用指南 - 完整的项目源码(iopaint/) - Web 前端源码(web_app/) 🤖 Generated with Claude Code
This commit is contained in:
97
iopaint/model/manga.py
Normal file
97
iopaint/model/manga.py
Normal file
@@ -0,0 +1,97 @@
|
||||
import os
|
||||
import random
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
import torch
|
||||
import time
|
||||
from loguru import logger
|
||||
|
||||
from iopaint.helper import get_cache_path_by_url, load_jit_model, download_model
|
||||
from .base import InpaintModel
|
||||
from iopaint.schema import InpaintRequest
|
||||
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user