Files
2024-03-04 16:41:54 +00:00

213 lines
5.4 KiB
Python

from diffusers.pipelines.controlnet.multicontrolnet import MultiControlNetModel
import numpy as np
from PIL import Image
import torch
class AnyType(str):
"""A special class that is always equal in not equal comparisons. Credit to pythongosssss"""
def __eq__(self, _) -> bool:
return True
def __ne__(self, __value: object) -> bool:
return False
any = AnyType("*")
class MultiControlNetConverter:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"controlnets": (any,),
},
}
RETURN_TYPES = ("MODEL",)
RETURN_NAMES = ("multicontrolnet",)
CATEGORY = "ControlNetUtils"
FUNCTION = "execute"
def execute(self, controlnets):
model = MultiControlNetModel(controlnets)
return [model]
class NHWC2NCHWTensor:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
},
"optional": {
}
}
CATEGORY = "ControlNetUtils"
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("image",)
FUNCTION = "execute"
def execute(self, image):
print(image.shape)
image.permute(0, 3, 1, 2)
print(image.shape)
return [image]
class NHWCTensor2PIL:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
},
"optional": {
}
}
CATEGORY = "ControlNetUtils"
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("image",)
FUNCTION = "execute"
def execute(self, image):
# convert NHWC Tensor to PIL Image
img_array = image.squeeze(0).cpu().numpy() * 255.0
img_pil = Image.fromarray(np.clip(img_array, 0, 255).astype(np.uint8))
return [img_pil]
class PIL2NHWCTensor:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
},
"optional": {
}
}
CATEGORY = "ControlNetUtils"
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("image",)
FUNCTION = "execute"
def execute(self, image):
# 将 PIL.Image 转换为 numpy.ndarray
img_array = np.array(image)
# 转换 numpy.ndarray 为 torch.Tensor
img_tensor = torch.from_numpy(img_array).float() / 255.
# 转换图像格式为 CHW (如果需要)
if img_tensor.ndim == 3 and img_tensor.shape[-1] == 3:
img_tensor = img_tensor.permute(2, 0, 1)
# 添加批次维度并转换为 NHWC
img_tensor = img_tensor.unsqueeze(0).permute(0, 2, 3, 1)
return [img_tensor]
class ListOfImages:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
},
"optional": {
"any_1": ("IMAGE",),
"any_2": ("IMAGE",),
"any_3": ("IMAGE",),
"any_4": ("IMAGE",),
"any_5": ("IMAGE",),
"any_6": ("IMAGE",),
"any_7": ("IMAGE",),
"any_8": ("IMAGE",),
}
}
CATEGORY = "ControlNetUtils"
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("images",)
FUNCTION = "execute"
def execute(self,
any_1=None,
any_2=None,
any_3=None,
any_4=None,
any_5=None,
any_6=None,
any_7=None,
any_8=None):
list_any = []
if any_1 is not None:
try:
list_any.append(any_1)
except Exception as e:
raise e
if any_2 is not None:
try:
list_any.append(any_2)
except Exception as e:
raise e
if any_3 is not None:
try:
list_any.append(any_3)
except Exception as e:
raise e
if any_4 is not None:
try:
list_any.append(any_4)
except Exception as e:
raise e
if any_5 is not None:
try:
list_any.append(any_5)
except Exception as e:
raise e
if any_6 is not None:
try:
list_any.append(any_6)
except Exception as e:
raise e
if any_7 is not None:
try:
list_any.append(any_7)
except Exception as e:
raise e
if any_8 is not None:
try:
list_any.append(any_8)
except Exception as e:
raise e
# yes, double brackets are needed because of the OUTPUT_IS_LIST... ¯\_(ツ)_/¯
return [list_any]
NODE_CLASS_MAPPINGS = {
"MultiControlNetConverter": MultiControlNetConverter,
"ListOfImages": ListOfImages,
"PIL2NHWCTensor": PIL2NHWCTensor,
"NHWC2NCHWTensor": NHWC2NCHWTensor,
"NHWCTensor2PIL": NHWCTensor2PIL
}
NODE_DISPLAY_NAME_MAPPINGS = {
"MultiControlNetConverter": "Multi-ControlNet Converter",
"ListOfImages": "List of Images",
"PIL2NHWCTensor": "Convert PIL to Tensor (NHWC)",
"NHWC2NCHWTensor": "Convert Tensor (NHWC) to (NCHW)",
"NHWCTensor2PIL": "Convert Tensor (NHWC) to PIL"
}