Spaces:
Sleeping
Sleeping
| import cv2 | |
| import numpy as np | |
| import supervision as sv | |
| from PIL import Image | |
| MIN_AREA = 100 | |
| def load_image(image_path: str): | |
| return Image.open(image_path).convert("RGB") | |
| def draw_image(image_rgb, masks, xyxy, probs, labels): | |
| box_annotator = sv.BoxCornerAnnotator() | |
| label_annotator = sv.LabelAnnotator() | |
| mask_annotator = sv.MaskAnnotator() | |
| # Create class_id for each unique label | |
| unique_labels = list(set(labels)) | |
| class_id_map = {label: idx for idx, label in enumerate(unique_labels)} | |
| class_id = [class_id_map[label] for label in labels] | |
| # Add class_id to the Detections object | |
| detections = sv.Detections( | |
| xyxy=xyxy, | |
| mask=masks.astype(bool), | |
| confidence=probs, | |
| class_id=np.array(class_id), | |
| ) | |
| annotated_image = box_annotator.annotate(scene=image_rgb.copy(), detections=detections) | |
| annotated_image = label_annotator.annotate(scene=annotated_image, detections=detections, labels=labels) | |
| annotated_image = mask_annotator.annotate(scene=annotated_image, detections=detections) | |
| return annotated_image | |
| def get_contours(mask): | |
| if len(mask.shape) > 2: | |
| mask = np.squeeze(mask, 0) | |
| mask = mask.astype(np.uint8) | |
| mask *= 255 | |
| contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) | |
| effContours = [] | |
| for c in contours: | |
| area = cv2.contourArea(c) | |
| if area > MIN_AREA: | |
| effContours.append(c) | |
| return effContours | |
| def contour_to_points(contour): | |
| pointsNum = len(contour) | |
| contour = contour.reshape(pointsNum, -1).astype(np.float32) | |
| points = [point.tolist() for point in contour] | |
| return points | |
| def generate_labelme_json(binary_masks, labels, image_size, image_path=None): | |
| """Generate a LabelMe format JSON file from binary mask tensor. | |
| Args: | |
| binary_masks: Binary mask tensor of shape [N, H, W]. | |
| labels: List of labels for each mask. | |
| image_size: Tuple of (height, width) for the image size. | |
| image_path: Path to the image file (optional). | |
| Returns: | |
| A dictionary representing the LabelMe JSON file. | |
| """ | |
| num_masks = binary_masks.shape[0] | |
| binary_masks = binary_masks.numpy() | |
| json_dict = { | |
| "version": "4.5.6", | |
| "imageHeight": image_size[0], | |
| "imageWidth": image_size[1], | |
| "imagePath": image_path, | |
| "flags": {}, | |
| "shapes": [], | |
| "imageData": None, | |
| } | |
| # Loop through the masks and add them to the JSON dictionary | |
| for i in range(num_masks): | |
| mask = binary_masks[i] | |
| label = labels[i] | |
| effContours = get_contours(mask) | |
| for effContour in effContours: | |
| points = contour_to_points(effContour) | |
| shape_dict = { | |
| "label": label, | |
| "line_color": None, | |
| "fill_color": None, | |
| "points": points, | |
| "shape_type": "polygon", | |
| } | |
| json_dict["shapes"].append(shape_dict) | |
| return json_dict | |