| 5 | |
| 6 | |
| 7 | class MaskSplit: |
| 8 | def __init__(self): |
| 9 | pass |
| 10 | |
| 11 | @classmethod |
| 12 | def INPUT_TYPES(cls): |
| 13 | return { |
| 14 | "required": { |
| 15 | "image": ("IMAGE",), |
| 16 | "mask": ("MASK",), |
| 17 | |
| 18 | }, |
| 19 | } |
| 20 | |
| 21 | RETURN_TYPES = ("IMAGE","MASK") |
| 22 | RETURN_NAMES = ("segmented_images","segmented_masks") |
| 23 | FUNCTION = "segment_mask" |
| 24 | |
| 25 | CATEGORY = "CyberEveLoop🐰" |
| 26 | |
| 27 | def find_top_left_point(self, mask_np): |
| 28 | """找到mask中最左上角的点""" |
| 29 | # 找到所有非零点 |
| 30 | y_coords, x_coords = np.nonzero(mask_np) |
| 31 | if len(x_coords) == 0: |
| 32 | return float('inf'), float('inf') |
| 33 | |
| 34 | # 找到最小x值 |
| 35 | min_x = np.min(x_coords) |
| 36 | # 在最小x值的点中找到最小y值 |
| 37 | min_y = np.min(y_coords[x_coords == min_x]) |
| 38 | |
| 39 | return min_x, min_y |
| 40 | |
| 41 | def segment_mask(self, mask, image): |
| 42 | """使用OpenCV快速分割蒙版并处理图像""" |
| 43 | # 保存原始设备信息 |
| 44 | device = mask.device if isinstance(mask, torch.Tensor) else torch.device('cpu') |
| 45 | |
| 46 | # 确保mask是正确的形状并转换为numpy数组 |
| 47 | if isinstance(mask, torch.Tensor): |
| 48 | if len(mask.shape) == 2: |
| 49 | mask = mask.unsqueeze(0) |
| 50 | mask_np = (mask[0] * 255).cpu().numpy().astype(np.uint8) |
| 51 | else: |
| 52 | mask_np = (mask * 255).astype(np.uint8) |
| 53 | |
| 54 | # 使用OpenCV找到轮廓 |
| 55 | contours, hierarchy = cv2.findContours( |
| 56 | mask_np, |
| 57 | cv2.RETR_TREE, |
| 58 | cv2.CHAIN_APPROX_SIMPLE |
| 59 | ) |
| 60 | |
| 61 | mask_info = [] # 用于排序的信息列表 |
| 62 | |
| 63 | if hierarchy is not None and len(contours) > 0: |
| 64 | hierarchy = hierarchy[0] |
nothing calls this directly
no outgoing calls
no test coverage detected