Example #1
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
Example #2
0
def _parse_annotation(annotation_object: ET.Element) -> dt.Annotation:
    """
    Parses the given XML element and returns the corresponding annotation.

    Parameters
    --------
    annotation_object: xml.etree.ElementTree.Element
        The element to convert into an annotation.

    Returns
    -------
    darwin.datatypes.AnnotationFile
        An AnnotationFile with the parsed information from the XML element.

    Raises
    ------
    ValueError
        If a mandatory chield element is missing or is empty. Mandatory child elements are: 
        name, bndbox, xmin, xmax, ymin and ymax.
    """
    class_name = _find_text_value(annotation_object, "name")

    bndbox = _find_element(annotation_object, "bndbox")
    xmin = int(float(_find_text_value(bndbox, "xmin")))
    xmax = int(float(_find_text_value(bndbox, "xmax")))
    ymin = int(float(_find_text_value(bndbox, "ymin")))
    ymax = int(float(_find_text_value(bndbox, "ymax")))

    return dt.make_bounding_box(class_name, xmin, ymin, xmax - xmin,
                                ymax - ymin)
Example #3
0
def _to_bbox_annotation(bbox: Dict[str, Any], title: str) -> Annotation:
    x: float = cast(float, bbox.get("left"))
    y: float = cast(float, bbox.get("top"))
    width: float = cast(float, bbox.get("width"))
    height: float = cast(float, bbox.get("height"))

    return make_bounding_box(title, x, y, width, height)
Example #4
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
Example #5
0
def _parse_annotation(annotation_object):
    class_name = annotation_object.find("name").text
    bndbox = annotation_object.find("bndbox")
    xmin = int(bndbox.find("xmin").text)
    xmax = int(bndbox.find("xmax").text)
    ymin = int(bndbox.find("ymin").text)
    ymax = int(bndbox.find("ymax").text)

    return dt.make_bounding_box(class_name, xmin, ymin, xmax - xmin,
                                ymax - ymin)
Example #6
0
def _to_bbox_annotation(bbox: Dict[str, Any], classes: List[Dict[str, Any]]) -> Annotation:
    points: Dict[str, float] = cast(Dict[str, float], bbox.get("points"))
    x: float = cast(float, points.get("x1"))
    y: float = cast(float, points.get("y1"))
    w: float = abs(cast(float, points.get("x2")) - cast(float, points.get("x1")))
    h: float = abs(cast(float, points.get("y1")) - cast(float, points.get("y2")))
    class_id: int = cast(int, bbox.get("classId"))

    instance_class: Dict[str, Any] = _find_class(class_id, classes)
    name: str = str(instance_class.get("name"))
    attributes: Optional[SubAnnotation] = _get_attributes(bbox, instance_class)
    subannotations: Optional[List[SubAnnotation]] = None
    if attributes:
        subannotations = [attributes]

    return make_bounding_box(f"{name}-bbox", x, y, w, h, subannotations)
Example #7
0
def _parse_annotation(annotation):
    annotation_type = annotation["type"]
    annotation_label = annotation["label"]
    if annotation_type not in ["box", "class"]:
        raise ValueError(
            f"Unknown supported annotation type: {annotation_type}")

    if len(annotation["metadata"]["system"]["snapshots_"]) > 1:
        raise ValueError(
            "multiple snapshots per annotations are not supported")

    # Class is metadata that we can ignore
    if annotation_type == "class":
        return
    if annotation_type == "box":
        coords = annotation["coordinates"]
        x1, y1 = coords[0]["x"], coords[0]["y"]
        x2, y2 = coords[1]["x"], coords[1]["y"]
        return dt.make_bounding_box(annotation_label, x1, y1, x2 - x1, y2 - y1)
Example #8
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