Given a mask, returns a rectangular region that fits the mask with the given constraints
| 565 | return (mask.unsqueeze(0),) |
| 566 | |
| 567 | class MaskToRegion: |
| 568 | """ |
| 569 | Given a mask, returns a rectangular region that fits the mask with the given constraints |
| 570 | """ |
| 571 | def __init__(self): |
| 572 | pass |
| 573 | |
| 574 | @classmethod |
| 575 | def INPUT_TYPES(cls): |
| 576 | return { |
| 577 | "required": { |
| 578 | "mask": ("IMAGE",), |
| 579 | "padding": ("INT", {"default": 0, "min": 0, "max": VERY_BIG_SIZE, "step": 1}), |
| 580 | "constraints": (["keep_ratio", "keep_ratio_divisible", "multiple_of", "ignore"],), |
| 581 | "constraint_x": ("INT", {"default": 64, "min": 2, "max": VERY_BIG_SIZE, "step": 1}), |
| 582 | "constraint_y": ("INT", {"default": 64, "min": 2, "max": VERY_BIG_SIZE, "step": 1}), |
| 583 | "min_width": ("INT", {"default": 0, "min": 0, "max": VERY_BIG_SIZE, "step": 1}), |
| 584 | "min_height": ("INT", {"default": 0, "min": 0, "max": VERY_BIG_SIZE, "step": 1}), |
| 585 | "batch_behavior": (["match_ratio", "match_size"],), |
| 586 | }, |
| 587 | } |
| 588 | |
| 589 | RETURN_TYPES = ("IMAGE",) |
| 590 | FUNCTION = "get_region" |
| 591 | |
| 592 | CATEGORY = "Masquerade Nodes" |
| 593 | |
| 594 | def get_region(self, mask, padding, constraints, constraint_x, constraint_y, min_width, min_height, batch_behavior): |
| 595 | mask = tensor2mask(mask) |
| 596 | mask_size = mask.size() |
| 597 | mask_width = int(mask_size[2]) |
| 598 | mask_height = int(mask_size[1]) |
| 599 | |
| 600 | # masks_to_boxes errors if the tensor is all zeros, so we'll add a single pixel and zero it out at the end |
| 601 | is_empty = ~torch.gt(torch.max(torch.reshape(mask,[mask_size[0], mask_width * mask_height]), dim=1).values, 0.) |
| 602 | mask[is_empty,0,0] = 1. |
| 603 | boxes = masks_to_boxes(mask) |
| 604 | mask[is_empty,0,0] = 0. |
| 605 | |
| 606 | # Account for padding |
| 607 | min_x = torch.max(boxes[:,0] - padding, torch.tensor(0.)) |
| 608 | min_y = torch.max(boxes[:,1] - padding, torch.tensor(0.)) |
| 609 | max_x = torch.min(boxes[:,2] + padding, torch.tensor(mask_width)) |
| 610 | max_y = torch.min(boxes[:,3] + padding, torch.tensor(mask_height)) |
| 611 | |
| 612 | width = max_x - min_x |
| 613 | height = max_y - min_y |
| 614 | |
| 615 | # Make sure the width and height are big enough |
| 616 | target_width = torch.max(width, torch.tensor(min_width)) |
| 617 | target_height = torch.max(height, torch.tensor(min_height)) |
| 618 | |
| 619 | if constraints == "keep_ratio": |
| 620 | target_width = torch.max(target_width, target_height * constraint_x // constraint_y) |
| 621 | target_height = torch.max(target_height, target_width * constraint_y // constraint_x) |
| 622 | elif constraints == "keep_ratio_divisible": |
| 623 | # Probably a more efficient way to do this, but given the bounds it's not too bad |
| 624 | max_factors = torch.min(constraint_x // target_width, constraint_y // target_height) |
nothing calls this directly
no outgoing calls
no test coverage detected