Esempio n. 1
0
    def get_target(self, index: int) -> Dict[str, Any]:
        """
        Returns the instance segmentation target
        """
        target = self.parse_json(index)

        annotations = []
        for annotation in target["annotations"]:
            if "polygon" not in annotation and "complex_polygon" not in annotation:
                print(
                    f"Warning: missing polygon in annotation {self.annotations_path[index]}"
                )
            # Extract the sequences of coordinates from the polygon annotation
            annotation_type: str = "polygon" if "polygon" in annotation else "complex_polygon"
            sequences = convert_polygons_to_sequences(
                annotation[annotation_type]["path"],
                height=target["height"],
                width=target["width"],
            )
            # Compute the bbox of the polygon
            x_coords = [s[0::2] for s in sequences]
            y_coords = [s[1::2] for s in sequences]
            min_x = np.min([np.min(x_coord) for x_coord in x_coords])
            min_y = np.min([np.min(y_coord) for y_coord in y_coords])
            max_x = np.max([np.max(x_coord) for x_coord in x_coords])
            max_y = np.max([np.max(y_coord) for y_coord in y_coords])
            w = max_x - min_x + 1
            h = max_y - min_y + 1
            # Compute the area of the polygon
            # TODO fix with addictive/subtractive paths in complex polygons
            poly_area = np.sum([
                polygon_area(x_coord, y_coord)
                for x_coord, y_coord in zip(x_coords, y_coords)
            ])

            # Create and append the new entry for this annotation
            annotations.append({
                "category_id":
                self.classes.index(annotation["name"]),
                "segmentation":
                sequences,
                "bbox": [min_x, min_y, w, h],
                "area":
                poly_area,
            })
        target["annotations"] = annotations

        return target
Esempio n. 2
0
    def _map_annotation(self, index: int):
        """See superclass for documentation

        Notes
        -----
        The return value is a dict with the following fields:
            image_id : int
                Index of the image inside the dataset
            original_filename: str
                The path to the image on the file system
            annotations : list[Dict]
                List of annotations, where each annotation is a dict with:
                category_id : int
                    The single label of the image selected.
                segmentation : ndarray(1,)
                    Array of points [x,y,x,y,x,y ...] composing the polygon enclosing the object
                bbox : ndarray(1,)
                    Coordinates of the bounding box enclosing the instance as [x, y, w, h]
                area : float
                    Area of the polygon
        """
        with self.annotations_path[index].open() as f:
            annotations = json.load(f)["annotations"]

        # Filter out unused classes
        if self.classes is not None:
            annotations = [a for a in annotations if a["name"] in self.classes]

        target = []
        for annotation in annotations:
            assert "name" in annotation
            assert "polygon" in annotation
            # Extract the sequences of coordinates from the polygon annotation
            sequences = convert_polygons_to_sequences(annotation["polygon"]["path"])
            # Discard polygons with less than three points
            sequences[:] = [s for s in sequences if len(s) >= 6]
            if not sequences:
                continue
            # Compute the bbox of the polygon
            x_coords = [s[0::2] for s in sequences]
            y_coords = [s[1::2] for s in sequences]
            min_x = np.min([np.min(x_coord) for x_coord in x_coords])
            min_y = np.min([np.min(y_coord) for y_coord in y_coords])
            max_x = np.max([np.max(x_coord) for x_coord in x_coords])
            max_y = np.max([np.max(y_coord) for y_coord in y_coords])
            w = max_x - min_x + 1
            h = max_y - min_y + 1
            bbox_area = w * h
            # Compute the area of the polygon
            poly_area = np.sum(
                [polygon_area(x_coord, y_coord) for x_coord, y_coord in zip(x_coords, y_coords)]
            )
            assert poly_area <= bbox_area

            # Create and append the new entry for this annotation
            target.append(
                {
                    "category_id": self.classes.index(annotation["name"]),
                    "segmentation": sequences,
                    "bbox": [min_x, min_y, w, h],
                    "area": poly_area,
                }
            )

        return {
            "image_id": index,
            "original_filename": self.images_path[index],
            "annotations": target,
        }
Esempio n. 3
0
    def __getitem__(self, index: int):
        """
        Notes
        -----
        The return value is a dict with the following fields:
            image_id : int
                Index of the image inside the dataset
            image_path: str
                The path to the image on the file system
            labels : tensor(n)
                The class label of each one of the instances
            masks : tensor(n, H, W)
                Segmentation mask of each one of the instances
            boxes : tensor(n, 4)
                Coordinates of the bounding box enclosing the instances as [x, y, x, y]
            area : float
                Area in pixels of each one of the instances
        """
        img = load_pil_image(self.images_path[index])
        target = self.parse_json(index)

        annotations = []
        for annotation in target["annotations"]:
            if "polygon" not in annotation and "complex_polygon" not in annotation:
                print(
                    f"Warning: missing polygon in annotation {self.annotations_path[index]}"
                )
            # Extract the sequences of coordinates from the polygon annotation
            annotation_type = "polygon" if "polygon" in annotation else "complex_polygon"
            sequences = convert_polygons_to_sequences(
                annotation[annotation_type]["path"],
                height=target["height"],
                width=target["width"],
            )
            # Compute the bbox of the polygon
            x_coords = [s[0::2] for s in sequences]
            y_coords = [s[1::2] for s in sequences]
            min_x = np.min([np.min(x_coord) for x_coord in x_coords])
            min_y = np.min([np.min(y_coord) for y_coord in y_coords])
            max_x = np.max([np.max(x_coord) for x_coord in x_coords])
            max_y = np.max([np.max(y_coord) for y_coord in y_coords])
            w = max_x - min_x + 1
            h = max_y - min_y + 1
            # Compute the area of the polygon
            # TODO fix with addictive/subtractive paths in complex polygons
            poly_area = np.sum([
                polygon_area(x_coord, y_coord)
                for x_coord, y_coord in zip(x_coords, y_coords)
            ])

            # Create and append the new entry for this annotation
            annotations.append({
                "category_id":
                self.classes.index(annotation["name"]),
                "segmentation":
                sequences,
                "bbox": [min_x, min_y, w, h],
                "area":
                poly_area,
            })
        target["annotations"] = annotations

        img, target = self.convert_polygons(img, target)
        if self.transform is not None:
            img, target = self.transform(img, target)

        return img, target