Skip to content

Commit

Permalink
[DAR-1734][External] Re-add functions used by the backend (#832)
Browse files Browse the repository at this point in the history
* re-added the convert_sequences_to_polygons which is used by backend

* WIP

* Docstring updates
  • Loading branch information
JBWilkie committed May 1, 2024
1 parent f84fabb commit 6fea3ab
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 0 deletions.
52 changes: 52 additions & 0 deletions darwin/datatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,58 @@ def make_polygon(
)


def make_complex_polygon(
class_name: str,
point_paths: List[List[Point]],
bounding_box: Optional[Dict] = None,
subs: Optional[List[SubAnnotation]] = None,
slot_names: Optional[List[str]] = None,
) -> Annotation:
"""
Creates and returns a complex polygon annotation. Complex polygons are those who have holes
and/or disform shapes. This is used by the backend.
Parameters
----------
class_name: str
The name of the class for this ``Annotation``.
point_paths: List[List[Point]]
A list of lists points that comprises the complex polygon. This is needed as a complex
polygon can be effectively seen as a sum of multiple simple polygons. The list should have
a format similar to:
.. code-block:: python
[
[
{"x": 1, "y": 0},
{"x": 2, "y": 1}
],
[
{"x": 3, "y": 4},
{"x": 5, "y": 6}
]
# ... and so on ...
]
bounding_box : Optional[Dict], default: None
The bounding box that encompasses the polyong.
subs : Optional[List[SubAnnotation]], default: None
List of ``SubAnnotation``s for this ``Annotation``.
Returns
-------
Annotation
A complex polygon ``Annotation``.
"""
return Annotation(
AnnotationClass(class_name, "complex_polygon", "polygon"),
_maybe_add_bounding_box_data({"paths": point_paths}, bounding_box),
subs or [],
slot_names=slot_names or [],
)


def make_keypoint(
class_name: str,
x: float,
Expand Down
55 changes: 55 additions & 0 deletions darwin/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1449,3 +1449,58 @@ def _default_schema(version: dt.AnnotationFileVersion) -> Optional[str]:
return _supported_schema_versions().get(
(version.major, version.minor, version.suffix)
)


def convert_sequences_to_polygons(
sequences: List[Union[List[int], List[float]]],
height: Optional[int] = None,
width: Optional[int] = None,
) -> Dict[str, List[dt.Polygon]]:
"""
Converts a list of polygons, encoded as a list of dictionaries of into a list of nd.arrays
of coordinates. This is used by the backend.
Parameters
----------
sequences : List[Union[List[int], List[float]]]
List of arrays of coordinates in the format ``[x1, y1, x2, y2, ..., xn, yn]`` or as a list
of them as ``[[x1, y1, x2, y2, ..., xn, yn], ..., [x1, y1, x2, y2, ..., xn, yn]]``.
height : Optional[int], default: None
Maximum height for a polygon coordinate.
width : Optional[int], default: None
Maximum width for a polygon coordinate.
Returns
-------
Dict[str, List[dt.Polygon]]
Dictionary with the key ``path`` containing a list of coordinates in the format of
``[[{x: x1, y:y1}, ..., {x: xn, y:yn}], ..., [{x: x1, y:y1}, ..., {x: xn, y:yn}]]``.
Raises
------
ValueError
If sequences is a falsy value (such as ``[]``) or if it is in an incorrect format.
"""
if not sequences:
raise ValueError("No sequences provided")
# If there is a single sequences composing the instance then this is
# transformed to polygons = [[x1, y1, ..., xn, yn]]
if not isinstance(sequences[0], list):
sequences = [sequences]

if not isinstance(sequences[0][0], (int, float)):
raise ValueError("Unknown input format")

def grouped(iterable, n):
return zip(*[iter(iterable)] * n)

polygons = []
for sequence in sequences:
path = []
for x, y in grouped(sequence, 2):
# Clip coordinates to the image size
x = max(min(x, width - 1) if width else x, 0)
y = max(min(y, height - 1) if height else y, 0)
path.append({"x": x, "y": y})
polygons.append(path)
return {"path": polygons}

0 comments on commit 6fea3ab

Please sign in to comment.