7.8 KiB
7.8 KiB
Documentation
- Class name: ImageEffectsLensChromaticAberration
- Category: image/effects/lens
- Output node: False
- Repo Ref: https://github.com/comfyanonymous/ComfyUI
此节点应用色差效果到图像上,模拟光线通过镜头时的色散现象,创造出具有视觉特色的色彩边缘效果。它通过添加艺术性或真实的镜头瑕疵来增强视觉内容,常用于赋予图像更动态或复古的外观。
Input types
Required
- images
- 将应用色差效果的输入图像。这个参数对于定义将要进行变换的基础内容至关重要。
- Comfy dtype: IMAGE
- Python dtype: torch.Tensor
- shift
- 确定模拟色差效果的像素偏移量,影响颜色通道的位移程度。
- Comfy dtype: INT
- Python dtype: int
- method
- 指定在应用色差效果时处理边缘像素的方法,确保效果在整个图像上一致应用。
- Comfy dtype: COMBO[STRING]
- Python dtype: str
- shift_type
- 定义应用于色差效果的偏移类型,影响颜色通道位移的方向和性质。
- Comfy dtype: INT
- Python dtype: int
- mixing_type
- 控制原始和偏移颜色通道的混合方式,影响色差效果的整体强度和外观。
- Comfy dtype: INT
- Python dtype: int
- transpose
- 决定在应用色差效果之前是否以及如何转置图像,影响效果的方向。
- Comfy dtype: COMBO[STRING]
- Python dtype: str
- colors
- 选择要偏移的颜色通道,直接影响色差效果的颜色组成。
- Comfy dtype: COMBO[STRING]
- Python dtype: str
- lens_curvy
- 调整镜头效果的曲率,修改色差在图像上的显著程度。
- Comfy dtype: FLOAT
- Python dtype: float
Output types
- image
- 应用了色差效果的转换后图像,展示了对原始内容添加的视觉增强或艺术效果。
- Comfy dtype: IMAGE
- Python dtype: torch.Tensor
Usage tips
- Infra type:
GPU - Common nodes: unknown
Source code
class ImageEffectsLensChromaticAberration:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"images": ("IMAGE",),
"shift": ("INT", {
"default": 10,
"step": 1,
}),
"method": (["reflect", "edge", "constant"],),
"shift_type": ("INT", {
"default": 1,
"min": 1,
"max": 4,
"step": 1,
}),
"mixing_type": ("INT", {
"default": 1,
"min": 1,
"max": 4,
"step": 1,
}),
"transpose": (["none", "rotate", "reflect"],),
"colors": (["rb", "rg", "gb"],),
"lens_curvy": ("FLOAT", {
"default": 1.0,
"max": 15.0,
"step": 0.1,
}),
},
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "node"
CATEGORY = "image/effects/lens"
def node(self, images, shift, method, shift_type, mixing_type, transpose, colors, lens_curvy):
# noinspection PyUnboundLocalVariable
def apply(image):
img = image.clone().detach()
if transpose == "rotate":
img = img.permute(1, 0, 2)
elif transpose == "none" or transpose == "reflect":
pass
else:
raise ValueError("Not existing reverse.")
r, g, b = img[:, :, 0:3].split(1, 2)
height, width = img[:, :, 0].shape
def get_space(size, min_val, max_val):
size += shift * 2
if min_val == max_val:
return torch.linspace(min_val, max_val, size)
else:
return radialspace_1D(size, lens_curvy, 1.0, min_val, max_val)
if shift_type == 1:
f_shifts = get_space(height, -shift, shift)
if transpose == "reflect":
t_shifts = get_space(width, -shift, shift)
elif shift_type == 2:
f_shifts = get_space(height, 0, shift)
f_shifts = torch.flip(f_shifts, dims=(0,))
if transpose == "reflect":
t_shifts = get_space(width, 0, shift)
t_shifts = torch.flip(t_shifts, dims=(0,))
elif shift_type == 3:
f_shifts = get_space(height, 0, shift)
if transpose == "reflect":
t_shifts = get_space(width, 0, shift)
elif shift_type == 4:
f_shifts = get_space(height, shift, shift)
if transpose == "reflect":
t_shifts = get_space(width, shift, shift)
else:
raise ValueError("Not existing shift_type.")
if mixing_type == 1:
f_shifts = f_shifts
s_shifts = -f_shifts
if transpose == "reflect":
t_shifts = t_shifts
c_shifts = -t_shifts
elif mixing_type == 2:
f_shifts = -f_shifts
s_shifts = f_shifts
if transpose == "reflect":
t_shifts = -t_shifts
c_shifts = t_shifts
elif mixing_type == 3:
f_shifts = f_shifts
s_shifts = f_shifts
if transpose == "reflect":
t_shifts = t_shifts
c_shifts = t_shifts
elif mixing_type == 4:
f_shifts = -f_shifts
s_shifts = -f_shifts
if transpose == "reflect":
t_shifts = -t_shifts
c_shifts = -t_shifts
else:
raise ValueError("Not existing mixing_type.")
if colors == "rb":
def cat(f_value, s_value):
return torch.cat([f_value, g, s_value], 2)
f = r
s = b
elif colors == "rg":
def cat(f_value, s_value):
return torch.cat([f_value, s_value, b], 2)
f = r
s = g
elif colors == "gb":
def cat(f_value, s_value):
return torch.cat([r, f_value, s_value], 2)
f = g
s = b
else:
raise ValueError("Not existing colors.")
f_pad = F.pad(f.squeeze(), [shift, shift], padding_mode=method).unsqueeze(2)
s_pad = F.pad(s.squeeze(), [shift, shift], padding_mode=method).unsqueeze(2)
f_shifted = torch.zeros_like(f_pad)
s_shifted = torch.zeros_like(s_pad)
for i in range(height + (shift * 2)):
f_shifted[i] = torch.roll(f_pad[i], shifts=int(f_shifts[i]), dims=0)
s_shifted[i] = torch.roll(s_pad[i], shifts=int(s_shifts[i]), dims=0)
if transpose == "reflect":
for i in range(width + (shift * 2)):
f_shifted[:, i] = torch.roll(f_shifted[:, i], shifts=int(t_shifts[i]), dims=0)
s_shifted[:, i] = torch.roll(s_shifted[:, i], shifts=int(c_shifts[i]), dims=0)
f_result = f_shifted[shift:-shift, shift:-shift, :]
s_result = s_shifted[shift:-shift, shift:-shift, :]
img[:, :, 0:3] = cat(f_result, s_result)
if transpose == "rotate":
img = img.permute(1, 0, 2)
elif transpose == "none" or transpose == "reflect":
pass
else:
raise ValueError("Not existing reverse.")
return img
return (torch.stack([
apply(images[i]) for i in range(len(images))
]),)