146 lines
5.1 KiB
Markdown
146 lines
5.1 KiB
Markdown
|
|
# Documentation
|
|
- Class name: ImageEffectsLensOpticAxis
|
|
- Category: image/effects/lens
|
|
- Output node: False
|
|
|
|
ImageEffectsLensOpticAxis节点用于在图像上应用镜头光轴效果,根据镜头形状、边缘、曲率、缩放、亮度和饱和度等参数操纵图像的外观。它创建一个蒙版来选择性地应用变换,模拟镜头光轴对输入图像的光学效果。
|
|
|
|
# Input types
|
|
## Required
|
|
- images
|
|
- 将应用镜头光轴效果的输入图像。这个参数至关重要,因为它作为效果应用的基础。
|
|
- Comfy dtype: IMAGE
|
|
- Python dtype: torch.Tensor
|
|
- lens_shape
|
|
- 定义应用于图像的镜头效果的形状,影响光轴效果的整体外观。
|
|
- Comfy dtype: COMBO[STRING]
|
|
- Python dtype: str
|
|
- lens_edge
|
|
- 指定镜头效果的边缘行为,决定效果如何在图像边界处淡化或过渡。
|
|
- Comfy dtype: COMBO[STRING]
|
|
- Python dtype: str
|
|
- lens_curvy
|
|
- 调整镜头效果的曲率,允许自定义光轴效果的强度和形状。
|
|
- Comfy dtype: FLOAT
|
|
- Python dtype: float
|
|
- lens_zoom
|
|
- 控制镜头效果的缩放级别,影响光轴效果在图像上的比例和强度。
|
|
- Comfy dtype: FLOAT
|
|
- Python dtype: float
|
|
- lens_aperture
|
|
- 决定镜头效果的光圈大小,影响图像中的景深和焦点区域。
|
|
- Comfy dtype: FLOAT
|
|
- Python dtype: float
|
|
- blur_intensity
|
|
- 设置与镜头光轴效果一起应用的模糊效果的强度,有助于整体模拟相机镜头的视觉效果。
|
|
- Comfy dtype: INT
|
|
- Python dtype: int
|
|
|
|
# Output types
|
|
- image
|
|
- 应用镜头光轴效果后的图像,展示了变换后的外观。
|
|
- Comfy dtype: IMAGE
|
|
- Python dtype: torch.Tensor
|
|
- mask
|
|
- 用于应用镜头光轴效果的蒙版,指示图像中受变换影响的区域。
|
|
- Comfy dtype: MASK
|
|
- Python dtype: torch.Tensor
|
|
|
|
|
|
## Usage tips
|
|
- Infra type: `GPU`
|
|
- Common nodes: unknown
|
|
|
|
|
|
## Source code
|
|
```python
|
|
class ImageEffectsLensOpticAxis:
|
|
def __init__(self):
|
|
pass
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"images": ("IMAGE",),
|
|
"lens_shape": (["circle", "square", "rectangle", "corners"],),
|
|
"lens_edge": (["around", "symmetric"],),
|
|
"lens_curvy": ("FLOAT", {
|
|
"default": 4.0,
|
|
"max": 15.0,
|
|
"step": 0.1,
|
|
}),
|
|
"lens_zoom": ("FLOAT", {
|
|
"default": 2.0,
|
|
"step": 0.1,
|
|
}),
|
|
"lens_aperture": ("FLOAT", {
|
|
"default": 0.5,
|
|
"max": 10.0,
|
|
"step": 0.1,
|
|
}),
|
|
"blur_intensity": ("INT", {
|
|
"default": 30,
|
|
"min": 2,
|
|
"step": 2
|
|
}),
|
|
},
|
|
}
|
|
|
|
RETURN_TYPES = ("IMAGE", "MASK")
|
|
FUNCTION = "node"
|
|
CATEGORY = "image/effects/lens"
|
|
|
|
def node(self, images, lens_shape, lens_edge, lens_curvy, lens_zoom, lens_aperture, blur_intensity):
|
|
blur_intensity -= 1
|
|
lens_zoom += 1
|
|
|
|
height, width = images[0, :, :, 0].shape
|
|
|
|
if lens_edge == "around":
|
|
mask = radialspace_2D((height, width), lens_curvy, lens_zoom, lens_shape, 0.0, 1.0 + lens_curvy).unsqueeze(0).unsqueeze(3)
|
|
elif lens_edge == "symmetric":
|
|
if height != width:
|
|
new_height = new_width = max(height, width)
|
|
crop_top_bottom = (new_height - height) // 2
|
|
crop_left_right = (new_width - width) // 2
|
|
|
|
mask = radialspace_2D((new_height, new_width), lens_curvy, lens_zoom, lens_shape, 0.0, 1.0 + lens_curvy)[
|
|
crop_top_bottom:-crop_top_bottom or None,
|
|
crop_left_right:-crop_left_right or None
|
|
].unsqueeze(0).unsqueeze(3)
|
|
else:
|
|
mask = radialspace_2D((height, width), lens_curvy, lens_zoom, lens_shape, 0.0, 1.0 + lens_curvy).unsqueeze(0).unsqueeze(3)
|
|
else:
|
|
raise ValueError("Not existing lens_edge parameter.")
|
|
|
|
center_x = width // 2
|
|
center_y = height // 2
|
|
|
|
y_v, x_v = torch.meshgrid(torch.arange(height), torch.arange(width), indexing='ij')
|
|
|
|
dx = x_v - center_x
|
|
dy = y_v - center_y
|
|
|
|
distance = torch.sqrt(dx ** 2 + dy ** 2)
|
|
|
|
map_x = x_v + mask[0, :, :, 0] * dx / distance * (-lens_aperture * 100)
|
|
map_y = y_v + mask[0, :, :, 0] * dy / distance * (-lens_aperture * 100)
|
|
|
|
map_x = map_x.to(torch.float32).numpy()
|
|
map_y = map_y.to(torch.float32).numpy()
|
|
|
|
shifted_images = cv2_layer(images, lambda x: cv2.remap(x, map_x, map_y, cv2.INTER_LINEAR))
|
|
shifted_mask = cv2_layer(mask, lambda x: cv2.remap(x, map_x, map_y, cv2.INTER_LINEAR))
|
|
edited_images = cv2_layer(shifted_images, lambda x: cv2.stackBlur(x, (blur_intensity, blur_intensity)))
|
|
|
|
mask = torch.clamp(mask, 0.0, 1.0)
|
|
shifted_mask = torch.clamp(shifted_mask, 0.0, 1.0)
|
|
|
|
result = shifted_images * (1 - mask) + edited_images * mask
|
|
|
|
return result, shifted_mask
|
|
|
|
```
|