Remap¶
Documentation¶
- Class name:
Remap
- Category:
Bmad/CV/Transform
- Output node:
False
The Remap
node serves as a foundational class for various image remapping operations, providing a base structure and common functionalities for specialized remapping transformations. It abstracts the core mechanisms needed to perform complex image geometry alterations, enabling derived classes to implement specific remapping effects such as distortion correction, perspective adjustments, and custom image warping techniques.
Input types¶
Required¶
remap
- Specifies the remapping function to be applied, which is a core component of the remapping process, determining how pixels from the source image are mapped to the destination image.
- Comfy dtype:
REMAP
- Python dtype:
function
src
- The source image to be remapped, serving as the input for the remapping operation.
- Comfy dtype:
IMAGE
- Python dtype:
numpy.ndarray
interpolation
- Defines the interpolation method used in the remapping process, affecting the quality and appearance of the output image.
- Comfy dtype:
COMBO[STRING]
- Python dtype:
int
Optional¶
src_mask
- An optional mask that specifies which parts of the source image should be considered for remapping.
- Comfy dtype:
MASK
- Python dtype:
numpy.ndarray
output_with_alpha
- A boolean flag indicating whether the output image should include an alpha channel, allowing for transparency effects.
- Comfy dtype:
BOOLEAN
- Python dtype:
bool
Output types¶
image
- Comfy dtype:
IMAGE
- The result of the remapping operation, which is a transformed version of the input image according to the specified remapping parameters.
- Python dtype:
numpy.ndarray
- Comfy dtype:
mask
- Comfy dtype:
MASK
- An optional output mask that corresponds to the remapped image, indicating areas of interest or exclusion.
- Python dtype:
numpy.ndarray
- Comfy dtype:
Usage tips¶
- Infra type:
GPU
- Common nodes: unknown
Source code¶
class Remap:
@classmethod
def INPUT_TYPES(cls):
return {"required": {
"remap": ("REMAP", {"forceInput": True}),
"src": ("IMAGE",),
"interpolation": (interpolation_types, {"default": interpolation_types[2]}),
},
"optional": {
"src_mask": ("MASK",),
"output_with_alpha": ("BOOLEAN", {"default": False})
}
}
RETURN_TYPES = ("IMAGE", "MASK",)
FUNCTION = "transform"
CATEGORY = f"{cv_category_path}/Transform"
def transform(self, src, remap, interpolation, src_mask=None, output_with_alpha=False):
src = tensor2opencv(src)
dst_dims = remap["dims"] if "dims" in remap else src.shape[:2]
func = remap["func"]
xargs = remap["xargs"]
# if src_mask is not defined set it to a blank canvas; otherwise, just unwrap it
src_mask = np.ones(src.shape[:2]) * 255 if src_mask is None else tensor2opencv(src_mask, 1)
if "custom" not in remap.keys():
# generic application, using cv.remap
xs, ys, bb = func(src, *xargs)
remap_img = cv.remap(src, xs, ys, interpolation_types_map[interpolation])
mask = cv.remap(src_mask, xs, ys, interpolation_types_map[interpolation])
else:
# non-generic application; replaces cv.remap w/ some other function.
# so far only for user provided homography,
# to avoid a separate node, since technically it is also a remap and also uses the interpolation argument.
custom_data = func(src, *xargs)
remap_img, mask, bb = remap["custom"](custom_data, src, interpolation_types_map[interpolation], src_mask)
if bb is not None:
new_img = np.zeros((*dst_dims, 3)) # hope width and height are not swapped
new_img[bb[1]:bb[3], bb[0]:bb[2], :] = remap_img
remap_img = new_img
new_img = np.zeros(dst_dims) # was working previously without the batch dim; unsure if really needed
new_img[bb[1]:bb[3], bb[0]:bb[2]] = mask
mask = new_img
if output_with_alpha:
new_img = np.zeros((*dst_dims, 4))
new_img[:, :, 0:3] = remap_img[:, :, :]
new_img[:, :, 3] = mask[:, :]
remap_img = new_img
return (opencv2tensor(remap_img), opencv2tensor(mask))