Files

100 lines
4.5 KiB
Python

import torch
from PIL import Image
from .imagefunc import log, pil2tensor, tensor2pil, image2mask, RGB2RGBA
from .imagefunc import draw_rounded_rectangle, gaussian_blur, mask_area, max_inscribed_rect, min_bounding_rect
class LS_RoundedRectangle:
def __init__(self):
self.NODE_NAME = 'RoundedRectangle'
@classmethod
def INPUT_TYPES(self):
detect_mode = ['mask_area', 'min_bounding_rect', 'max_inscribed_rect']
return {
"required": {
"image": ("IMAGE",),
"rounded_rect_radius": ("INT", {"default": 50, "min": 0, "max": 100, "step": 1}),
"anti_aliasing": ("INT", {"default": 2, "min": 0, "max": 16, "step": 1}),
"top": ("FLOAT", {"default": 8, "min": -100, "max": 100, "step": 0.1}),
"bottom": ("FLOAT", {"default": 8, "min": -100, "max": 100, "step": 0.1}),
"left": ("FLOAT", {"default": 8, "min": -100, "max": 100, "step": 0.1}),
"right": ("FLOAT", {"default": 8, "min": -100, "max": 100, "step": 0.1}),
"detect": (detect_mode,),
"obj_ext_top": ("FLOAT", {"default": 8, "min": -100, "max": 100, "step": 0.1}),
"obj_ext_bottom": ("FLOAT", {"default": 8, "min": -100, "max": 100, "step": 0.1}),
"obj_ext_left": ("FLOAT", {"default": 8, "min": -100, "max": 100, "step": 0.1}),
"obj_ext_right": ("FLOAT", {"default": 8, "min": -100, "max": 100, "step": 0.1}),
},
"optional": {
"object_mask": ("MASK",),
"crop_box": ("BOX",),
}
}
RETURN_TYPES = ("IMAGE", "MASK",)
RETURN_NAMES = ("image", "mask",)
FUNCTION = 'rounded_rectangle'
CATEGORY = '😺dzNodes/LayerUtility'
def rounded_rectangle(self, image, rounded_rect_radius, anti_aliasing, top, bottom, left, right,
detect, obj_ext_top, obj_ext_bottom, obj_ext_left, obj_ext_right,
object_mask=None, crop_box=None):
ret_images = []
ret_masks = []
for index, img in enumerate(image):
orig_image = tensor2pil(torch.unsqueeze(img, 0)).convert('RGB')
width, height = orig_image.size
black_image = Image.new('L', (width, height), color="black")
if crop_box is not None:
w = crop_box[2] - crop_box[0]
h = crop_box[3] - crop_box[1]
x1 = crop_box[0] - int(obj_ext_left * w * 0.01)
y1 = crop_box[1] - int(obj_ext_top * h * 0.01)
x2 = crop_box[2] + int(obj_ext_right * w * 0.01)
y2 = crop_box[3] + int(obj_ext_bottom * h * 0.01)
bbox = [(x1, y1, x2, y2)]
elif object_mask is not None:
if object_mask.dim() == 2: object_mask = torch.unsqueeze(object_mask, 0)
mask = object_mask[index] if index < len(object_mask) else object_mask[-1]
mask = tensor2pil(mask)
bluredmask = gaussian_blur(mask, 20).convert('L')
x = -10
y = -10
w = 4
h = 4
if detect == "min_bounding_rect":
(x, y, w, h) = min_bounding_rect(bluredmask)
elif detect == "max_inscribed_rect":
(x, y, w, h) = max_inscribed_rect(bluredmask)
else:
(x, y, w, h) = mask_area(mask)
x1 = x - int(obj_ext_left * w * 0.01)
y1 = y - int(obj_ext_top * h * 0.01)
x2 = x + w + int(obj_ext_right * w * 0.01)
y2 = y + h + int(obj_ext_bottom * h * 0.01)
bbox = [(x1, y1, x2, y2)]
else:
bbox = [(int(left * width * 0.01),
int(top * height * 0.01),
width - int(right * width * 0.01),
height - int(bottom * height * 0.01))
]
rect_mask = draw_rounded_rectangle(black_image, rounded_rect_radius, bbox, anti_aliasing, "white")
ret_image = RGB2RGBA(orig_image, rect_mask)
ret_images.append(pil2tensor(ret_image))
ret_masks.append(image2mask(rect_mask))
return (torch.cat(ret_images, dim=0), torch.cat(ret_masks, dim=0),)
NODE_CLASS_MAPPINGS = {
"LayerUtility: RoundedRectangle": LS_RoundedRectangle
}
NODE_DISPLAY_NAME_MAPPINGS = {
"LayerUtility: RoundedRectangle": "LayerUtility: RoundedRectangle"
}