Skip to content

Commit 07f5b19

Browse files
committed
addition of from shapely function for annotation types
1 parent 0ef700c commit 07f5b19

File tree

5 files changed

+63
-5
lines changed

5 files changed

+63
-5
lines changed

labelbox/data/annotation_types/data/tiled_image.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@
1515
from pydantic import BaseModel, validator
1616
from pydantic.class_validators import root_validator
1717

18-
from labelbox.data.annotation_types.geometry.polygon import Polygon
19-
from labelbox.data.annotation_types.geometry.point import Point
20-
from labelbox.data.annotation_types.geometry.line import Line
21-
from labelbox.data.annotation_types.geometry.rectangle import Rectangle
22-
from ..geometry import Point
18+
from labelbox.data.annotation_types import Rectangle, Point, Line, Polygon
2319
from .base_data import BaseData
2420
from .raster import RasterData
2521

labelbox/data/annotation_types/geometry/line.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
from __future__ import annotations
12
from typing import List, Optional, Union, Tuple
23

34
import geojson
45
import numpy as np
56
import cv2
67
from pydantic import validator
8+
from shapely.geometry import LineString as SLineString
79

810
from .point import Point
911
from .geometry import Geometry
@@ -25,6 +27,17 @@ def geometry(self) -> geojson.MultiLineString:
2527
return geojson.MultiLineString(
2628
[[[point.x, point.y] for point in self.points]])
2729

30+
@classmethod
31+
def from_shapely(cls, shapely_obj: SLineString) -> Line:
32+
"""Transforms a shapely object."""
33+
if not isinstance(shapely_obj, SLineString):
34+
raise ValueError(
35+
f"Expected Shapely Line. Got {shapely_obj.geom_type}")
36+
37+
obj_coords = shapely_obj.__geo_interface__['coordinates']
38+
return Line(
39+
points=[Point(x=coords[0], y=coords[1]) for coords in obj_coords])
40+
2841
def draw(self,
2942
height: Optional[int] = None,
3043
width: Optional[int] = None,

labelbox/data/annotation_types/geometry/point.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
from __future__ import annotations
12
from typing import Optional, Tuple, Union
23

34
import geojson
45
import numpy as np
56
import cv2
7+
from shapely.geometry import Point as SPoint
68

79
from .geometry import Geometry
810

@@ -24,6 +26,16 @@ class Point(Geometry):
2426
def geometry(self) -> geojson.Point:
2527
return geojson.Point((self.x, self.y))
2628

29+
@classmethod
30+
def from_shapely(cls, shapely_obj: SPoint) -> Point:
31+
"""Transforms a shapely object."""
32+
if not isinstance(shapely_obj, SPoint):
33+
raise ValueError(
34+
f"Expected Shapely Point. Got {shapely_obj.geom_type}")
35+
36+
obj_coords = shapely_obj.__geo_interface__['coordinates']
37+
return Point(x=obj_coords[0], y=obj_coords[1])
38+
2739
def draw(self,
2840
height: Optional[int] = None,
2941
width: Optional[int] = None,

labelbox/data/annotation_types/geometry/polygon.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
from __future__ import annotations
12
from typing import List, Optional, Union, Tuple
23

34
import cv2
45
import geojson
56
import numpy as np
67
from pydantic import validator
8+
from shapely.geometry import Polygon as SPolygon
79

810
from .geometry import Geometry
911
from .point import Point
@@ -30,6 +32,17 @@ def geometry(self) -> geojson.Polygon:
3032
self.points.append(self.points[0])
3133
return geojson.Polygon([[(point.x, point.y) for point in self.points]])
3234

35+
@classmethod
36+
def from_shapely(cls, shapely_obj: SPolygon) -> Polygon:
37+
"""Transforms a shapely object."""
38+
#we only consider 0th index because we only allow for filled polygons
39+
obj_coords = shapely_obj.__geo_interface__['coordinates'][0]
40+
if not isinstance(shapely_obj, SPolygon):
41+
raise ValueError(
42+
f"Expected Shapely Polygon. Got {shapely_obj.geom_type}")
43+
return Polygon(
44+
points=[Point(x=coords[0], y=coords[1]) for coords in obj_coords])
45+
3346
def draw(self,
3447
height: Optional[int] = None,
3548
width: Optional[int] = None,

labelbox/data/annotation_types/geometry/rectangle.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
from __future__ import annotations
12
from typing import Optional, Union, Tuple
23

34
import cv2
45
import geojson
56
import numpy as np
7+
from shapely.geometry import Polygon as SPolygon
68

79
from .geometry import Geometry
810
from .point import Point
@@ -30,6 +32,28 @@ def geometry(self) -> geojson.geometry.Geometry:
3032
[self.start.x, self.start.y],
3133
]])
3234

35+
@classmethod
36+
def from_shapely(cls, shapely_obj: SPolygon) -> Rectangle:
37+
"""Transforms a shapely object.
38+
39+
If the provided shape is a non-rectangular polygon, a rectangle will be
40+
returned based on the min and max x,y values."""
41+
if not isinstance(shapely_obj, SPolygon):
42+
raise ValueError(
43+
f"Expected Shapely Polygon. Got {shapely_obj.geom_type}")
44+
45+
#we only consider 0th index because we only allow for filled polygons
46+
obj_coords = np.array(shapely_obj.__geo_interface__['coordinates'][0])
47+
48+
min_x, max_x = np.min(obj_coords[:, 0]), np.max(obj_coords[:, 0])
49+
min_y, max_y = np.min(obj_coords[:, 1]), np.max(obj_coords[:, 1])
50+
51+
start = [min_x, min_y]
52+
end = [max_x, max_y]
53+
54+
return Rectangle(start=Point(x=start[0], y=start[1]),
55+
end=Point(x=end[0], y=end[1]))
56+
3357
def draw(self,
3458
height: Optional[int] = None,
3559
width: Optional[int] = None,

0 commit comments

Comments
 (0)