Files
chflame163-ComfyUI_CatVTON_…/py/func.py
T
2024-07-30 17:09:50 +08:00

90 lines
3.1 KiB
Python

"""Image process functions for ComfyUI nodes
by chflame https://github.com/chflame163
@author: chflame
@title: CatVTON_Wrapper
@nickname: CatVTON_Wrapper
@description: CatVTON warpper for ComfyUI
"""
import os
import sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
# import math
import numpy as np
import torch
import scipy.ndimage
# from tqdm import tqdm
from PIL import Image, ImageFilter
from .catvton.pipeline import CatVTONPipeline
from torchvision.transforms.functional import to_pil_image, to_tensor
from diffusers.image_processor import VaeImageProcessor
import folder_paths
def log(message:str, message_type:str='info'):
name = 'LayerStyle'
if message_type == 'error':
message = '\033[1;41m' + message + '\033[m'
elif message_type == 'warning':
message = '\033[1;31m' + message + '\033[m'
elif message_type == 'finish':
message = '\033[1;32m' + message + '\033[m'
else:
message = '\033[1;33m' + message + '\033[m'
print(f"# 😺dzNodes: {name} -> {message}")
def pil2tensor(image:Image) -> torch.Tensor:
return torch.from_numpy(np.array(image).astype(np.float32) / 255.0).unsqueeze(0)
def tensor2pil(t_image: torch.Tensor) -> Image:
return Image.fromarray(np.clip(255.0 * t_image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8))
def expand_mask(mask:torch.Tensor, grow:int, blur:int) -> torch.Tensor:
# grow
c = 0
kernel = np.array([[c, 1, c],
[1, 1, 1],
[c, 1, c]])
growmask = mask.reshape((-1, mask.shape[-2], mask.shape[-1]))
out = []
for m in growmask:
output = m.numpy()
for _ in range(abs(grow)):
if grow < 0:
output = scipy.ndimage.grey_erosion(output, footprint=kernel)
else:
output = scipy.ndimage.grey_dilation(output, footprint=kernel)
output = torch.from_numpy(output)
out.append(output)
# blur
for idx, tensor in enumerate(out):
pil_image = tensor2pil(tensor.cpu().detach())
pil_image = pil_image.filter(ImageFilter.GaussianBlur(blur))
out[idx] = pil2tensor(pil_image)
ret_mask = torch.cat(out, dim=0)
return ret_mask
def resize_and_padding_image(image:Image, size:tuple, background_color:str="#FFFFFF") -> tuple:
# Padding to size ratio
w, h = image.size
target_w, target_h = size
if w / h < target_w / target_h: # target更宽,补左右
new_h = target_h
new_w = w * target_h // h
else:
new_w = target_w
new_h = h * target_w // w
image = image.resize((new_w, new_h), Image.LANCZOS)
# padding
padding = Image.new("RGB", size, color=background_color)
paste_coordinate = ((target_w - new_w) // 2, (target_h - new_h) // 2)
padding.paste(image, paste_coordinate)
return padding, (paste_coordinate[0], paste_coordinate[1], paste_coordinate[0] + new_w, paste_coordinate[1] + new_h)
def restore_padding_image(image:Image, orig_size:tuple, bbox:tuple) -> Image:
w, h = image.size
orig_w, orig_h = orig_size
ret_image = image.crop(bbox)
return ret_image.resize((orig_w, orig_h), Image.LANCZOS)