Add Roll Mask node

This commit is contained in:
ProGamerGov
2025-08-21 13:32:25 -06:00
committed by GitHub
parent 4bd6e4e807
commit 2fb5b784a8
4 changed files with 75 additions and 4 deletions
+6
View File
@@ -94,6 +94,12 @@ The Roll Image node rolls an image along the height dimension (y axis) or the wi
If you set 'roll_x_by_50_percent' to True, then any x and y axis values are ignored, and the image is shifted horizontally to be 50%. This is equivalent to a 180 degree rotation on an equirectangular image.
### Roll Mask Axes
The Roll Mask node rolls an mask along the height dimension (y axis) or the width dimension (x axis). This can help make artifacts like seams more accessible. Note that y axis rotations are not correct for final equirectangular outputs. Use the E2E node instead for y axis rotations.
If you set 'roll_x_by_50_percent' to True, then any x and y axis values are ignored, and the image is shifted horizontally to be 50%. This is equivalent to a 180 degree rotation on an equirectangular image.
### Crop Image with Coords & Paste Image with Coords
These two nodes allow you to crop a section of an image out to make things like in-painting faster and more memory efficient, before pasting the cropped section back into the original image.
+3
View File
@@ -16,6 +16,7 @@ from .nodes import (
Pad180To360Node,
PasteImageWithCoordsNode,
RollImageNode,
RollMaskNode,
SplitFacesNode,
StackFacesNode,
StereoToMonoScopicNode,
@@ -42,6 +43,7 @@ NODE_CLASS_MAPPINGS = {
"Create Pole Mask": CreatePoleMask,
"Equirectangular to Face": E2Face,
"Face to Equirectangular": Face2E,
"Roll Mask Axes": RollMaskNode,
}
NODE_DISPLAY_NAME_MAPPINGS = {
@@ -65,4 +67,5 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"Create Pole Mask": "Create Pole Mask",
"Equirectangular to Face": "Equirectangular to Face",
"Face to Equirectangular": "Face to Equirectangular",
"Roll Mask Axes": "Roll Mask Axes",
}
+65 -3
View File
@@ -971,7 +971,18 @@ class CreateSeamMask:
"required": {
"image": ("IMAGE", {"default": None}),
"seam_mask_width": ("FLOAT", {"default": 0.10}),
"feather": ("INT", {"default": 0}),
"feather": (
"INT",
{"default": 0, "tooltip": "Pixel size of the feathering."},
),
"roll_x_by_50_percent": (
"BOOLEAN",
{
"default": False,
"tooltip": "Shifts the output mask horizontally by 50%."
+ " Equivalent to a 180 degree rotation on an equirectangular image.",
},
),
},
}
@@ -987,12 +998,17 @@ class CreateSeamMask:
image: torch.Tensor,
seam_mask_width: float = 0.10,
feather: int = 0,
roll_x_by_50_percent: bool = False,
) -> Tuple[torch.Tensor]:
assert image.dim() == 4, "Image should have 4 dimensions"
_, H, W, _ = image.shape
px_half = W // 2
image_rolled = torch.roll(image, shifts=(0, px_half), dims=(1, 2))
seam_mask = _create_center_seam_mask(image, frac_width=seam_mask_width, feather=feather)
seam_mask = _create_center_seam_mask(
image, frac_width=seam_mask_width, feather=feather
)
if roll_x_by_50_percent:
seam_mask = torch.roll(seam_mask, shifts=(0, px_half), dims=(1, 2))
return (seam_mask,)
@@ -1237,3 +1253,49 @@ class Face2E:
)
]
return (torch.stack(output_image),)
class RollMaskNode:
"""
Roll a mask to make face seams easier to remove or access.
"""
@classmethod
def INPUT_TYPES(s) -> Dict:
return {
"required": {
"mask": ("MASK", {"default": None}),
"roll_x": ("INT", {"default": 0}),
"roll_y": ("INT", {"default": 0}),
"roll_x_by_50_percent": (
"BOOLEAN",
{
"default": False,
"tooltip": "Shifts the input mask horizontally by 50%."
+ " Equivalent to a 180 degree rotation on an equirectangular image.",
},
),
},
}
RETURN_TYPES = ("MASK",)
RETURN_NAMES = ("Rolled Mask",)
FUNCTION = "roll_mask"
CATEGORY = "pytorch360convert"
def roll_mask(
self,
mask: torch.Tensor,
roll_x: int = 0,
roll_y: int = 0,
roll_x_by_50_percent: bool = False,
) -> Tuple[torch.Tensor]:
assert mask.dim() == 3, f"mask should have 3 dimensions, got {mask.dim()}"
if roll_x_by_50_percent:
_, H, W = mask.shape
px_half = W // 2
roll_y = 0
roll_x = px_half
return (torch.roll(mask, shifts=(roll_y, roll_x), dims=(1, 2)),)
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "comfyui-pytorch360convert"
description = "A collection of custom nodes for working with and converting between and working with 360 degree equirectangular images, cubemap, and perspective images. Also includes Circular padding Conv2d options for models and VAEs, along with nodes to fix seams and polar artifacts. Panoramic 360 images are also sometimes known as VR photography (virtual reality), HDRI environments (ex: skyboxes), image spheres, spherical images, 360 pano."
version = "1.0.8"
version = "1.0.9"
license = {file = "LICENSE"}
dependencies = ["pytorch360convert"]