Exemplo n.º 1
0
def parse_darwin_annotation(
        annotation: Dict[str, Any]) -> Optional[dt.Annotation]:
    name: str = annotation["name"]
    main_annotation: Optional[dt.Annotation] = None
    if "polygon" in annotation:
        bounding_box = annotation.get("bounding_box")
        if "additional_paths" in annotation["polygon"]:
            paths = [annotation["polygon"]["path"]
                     ] + annotation["polygon"]["additional_paths"]
            main_annotation = dt.make_complex_polygon(name, paths,
                                                      bounding_box)
        else:
            main_annotation = dt.make_polygon(name,
                                              annotation["polygon"]["path"],
                                              bounding_box)
    elif "complex_polygon" in annotation:
        bounding_box = annotation.get("bounding_box")
        if "additional_paths" in annotation["complex_polygon"]:
            paths = annotation["complex_polygon"]["path"] + annotation[
                "complex_polygon"]["additional_paths"]
            main_annotation = dt.make_complex_polygon(name, paths,
                                                      bounding_box)
        else:
            main_annotation = dt.make_complex_polygon(
                name, annotation["complex_polygon"]["path"], bounding_box)
    elif "bounding_box" in annotation:
        bounding_box = annotation["bounding_box"]
        main_annotation = dt.make_bounding_box(name, bounding_box["x"],
                                               bounding_box["y"],
                                               bounding_box["w"],
                                               bounding_box["h"])
    elif "tag" in annotation:
        main_annotation = dt.make_tag(name)
    elif "line" in annotation:
        main_annotation = dt.make_line(name, annotation["line"]["path"])
    elif "keypoint" in annotation:
        main_annotation = dt.make_keypoint(name, annotation["keypoint"]["x"],
                                           annotation["keypoint"]["y"])
    elif "ellipse" in annotation:
        main_annotation = dt.make_ellipse(name, annotation["ellipse"])
    elif "cuboid" in annotation:
        main_annotation = dt.make_cuboid(name, annotation["cuboid"])
    elif "skeleton" in annotation:
        main_annotation = dt.make_skeleton(name,
                                           annotation["skeleton"]["nodes"])

    if not main_annotation:
        print(f"[WARNING] Unsupported annotation type: '{annotation.keys()}'")
        return None

    if "instance_id" in annotation:
        main_annotation.subs.append(
            dt.make_instance_id(annotation["instance_id"]["value"]))
    if "attributes" in annotation:
        main_annotation.subs.append(
            dt.make_attributes(annotation["attributes"]))
    if "text" in annotation:
        main_annotation.subs.append(dt.make_text(annotation["text"]["text"]))

    return main_annotation
Exemplo n.º 2
0
def parse_annotation(
        annotation: Dict[str, Any],
        category_lookup_table: Dict[str, Any]) -> Optional[dt.Annotation]:
    category = category_lookup_table[annotation["category_id"]]
    segmentation = annotation["segmentation"]
    iscrowd = annotation.get("iscrowd") == 1

    if iscrowd:
        print("Warning, unsupported RLE, skipping")
        return None

    if len(segmentation) == 0 and len(annotation["bbox"]) == 4:
        x, y, w, h = map(int, annotation["bbox"])
        return dt.make_bounding_box(category["name"], x, y, w, h)
    elif len(segmentation) == 0 and len(annotation["bbox"]) == 1 and len(
            annotation["bbox"][0]) == 4:
        x, y, w, h = map(int, annotation["bbox"][0])
        return dt.make_bounding_box(category["name"], x, y, w, h)
    elif isinstance(segmentation, dict):
        print(
            "warning, converting complex coco rle mask to polygon, could take some time"
        )
        if isinstance(segmentation["counts"], list):
            mask = rle_decode(segmentation["counts"],
                              segmentation["size"][::-1])
        else:
            counts = decode_binary_rle(segmentation["counts"])
            mask = rle_decode(counts, segmentation["size"][::-1])

        _labels, external, _internal = find_contours(mask)
        paths = []
        for external_path in external:
            # skip paths with less than 2 points
            if len(external_path) // 2 <= 2:
                continue
            path = []
            points = iter(external_path)
            while True:
                try:
                    x, y = next(points), next(points)
                    path.append({"x": x, "y": y})
                except StopIteration:
                    break
            paths.append(path)
        return dt.make_complex_polygon(category["name"], paths)
    elif isinstance(segmentation, list):
        path = []
        points = iter(segmentation[0] if isinstance(segmentation[0], list
                                                    ) else segmentation)
        while True:
            try:
                x, y = next(points), next(points)
                path.append({"x": x, "y": y})
            except StopIteration:
                break
        return dt.make_polygon(category["name"], path)
    else:
        return None
Exemplo n.º 3
0
def _to_polygon_annotation(polygon: Dict[str, Any], classes: List[Dict[str, Any]]) -> Annotation:
    data: List[float] = cast(List[float], polygon.get("points"))
    class_id: int = cast(int, polygon.get("classId"))
    instance_class: Dict[str, Any] = _find_class(class_id, classes)
    name: str = str(instance_class.get("name"))
    points: List[Point] = _map_to_list(_tuple_to_point, _group_to_list(data, 2, 0))

    attributes: Optional[SubAnnotation] = _get_attributes(polygon, instance_class)
    subannotations: Optional[List[SubAnnotation]] = None
    if attributes:
        subannotations = [attributes]
    return make_polygon(f"{name}-polygon", points, None, subannotations)
Exemplo n.º 4
0
    def test_it_returns_annotation_with_default_params():
        class_name: str = "class_name"
        points: List[Point] = [{
            "x": 1,
            "y": 2
        }, {
            "x": 3,
            "y": 4
        }, {
            "x": 1,
            "y": 2
        }]
        annotation = make_polygon(class_name, points)

        assert_annoation_class(annotation, class_name, "polygon")

        path = annotation.data.get("path")
        assert path == points
Exemplo n.º 5
0
def parse_annotation(annotation, category_lookup_table):
    category = category_lookup_table[annotation["category_id"]]
    segmentation = annotation["segmentation"]
    iscrowd = annotation.get("iscrowd") == 1

    if iscrowd:
        print("Warning, unsupported RLE, skipping")
        return None

    if len(segmentation) == 0 and len(annotation["bbox"]) == 4:
        x, y, w, h = map(int, annotation["bbox"])
        return dt.make_bounding_box(category["name"], x, y, w, h)
    elif len(segmentation) > 1:
        print("warning, converting complex coco rle mask to polygon, could take some time")
        mask = rle_decoding(segmentation["counts"], segmentation["size"])
        _labels, external, _internal = find_contours(mask)
        paths = []
        for external_path in external:
            path = []
            points = iter(external_path)
            while True:
                try:
                    x, y = next(points), next(points)
                    path.append({"x": x, "y": y})
                except StopIteration:
                    break
            paths.append(path)
        return dt.make_complex_polygon(category["name"], paths)
    elif len(segmentation) == 1:
        path = []
        points = iter(segmentation[0])
        while True:
            try:
                x, y = next(points), next(points)
                path.append({"x": x, "y": y})
            except StopIteration:
                break
        return dt.make_polygon(category["name"], path)
    else:
        return None
Exemplo n.º 6
0
    def test_it_returns_annotation_with_bounding_box():
        class_name: str = "class_name"
        points: List[Point] = [{
            "x": 1,
            "y": 2
        }, {
            "x": 3,
            "y": 4
        }, {
            "x": 1,
            "y": 2
        }]
        bbox: Dict[str, float] = {"x": 1, "y": 2, "w": 2, "h": 2}
        annotation = make_polygon(class_name, points, bbox)

        assert_annoation_class(annotation, class_name, "polygon")

        path = annotation.data.get("path")
        assert path == points

        class_bbox = annotation.data.get("bounding_box")
        assert class_bbox == bbox
Exemplo n.º 7
0
def build_annotation(annotation_file, annotation_id, annotation: dt.Annotation,
                     categories):
    annotation_type = annotation.annotation_class.annotation_type
    if annotation_type == "polygon":
        sequences = convert_polygons_to_sequences(annotation.data["path"],
                                                  rounding=False)
        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
        poly_area = np.sum([
            polygon_area(x_coord, y_coord)
            for x_coord, y_coord in zip(x_coords, y_coords)
        ])

        return {
            "id": annotation_id,
            "image_id": annotation_file.seq,
            "category_id": categories[annotation.annotation_class.name],
            "segmentation": sequences,
            "area": poly_area,
            "bbox": [min_x, min_y, w, h],
            "iscrowd": 0,
            "extra": build_extra(annotation),
        }
    elif annotation_type == "complex_polygon":
        mask = np.zeros(
            (annotation_file.image_height, annotation_file.image_width))
        sequences = convert_polygons_to_sequences(annotation.data["paths"])
        draw_polygon(mask, sequences, 1)
        counts = rle_encode(mask)

        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

        return {
            "id": annotation_id,
            "image_id": annotation_file.seq,
            "category_id": categories[annotation.annotation_class.name],
            "segmentation": {
                "counts": counts,
                "size":
                [annotation_file.image_height, annotation_file.image_width]
            },
            "area": 0,
            "bbox": [min_x, min_y, w, h],
            "iscrowd": 1,
            "extra": build_extra(annotation),
        }
    elif annotation_type == "tag":
        pass
    elif annotation_type == "bounding_box":
        x = annotation.data["x"]
        y = annotation.data["y"]
        w = annotation.data["w"]
        h = annotation.data["h"]
        return build_annotation(
            annotation_file,
            annotation_id,
            dt.make_polygon(
                annotation.annotation_class.name,
                [{
                    "x": x,
                    "y": y
                }, {
                    "x": x + w,
                    "y": y
                }, {
                    "x": x + w,
                    "y": y + h
                }, {
                    "x": x,
                    "y": y + h
                }],
            ),
            categories,
        )
    else:
        print(f"skipping unsupported annotation_type '{annotation_type}'")
Exemplo n.º 8
0
def _to_polygon_annotation(polygon: List[Point], title: str) -> Annotation:
    return make_polygon(title, polygon, None)