supervisely 6.73.366__py3-none-any.whl → 6.73.367__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- supervisely/annotation/annotation.py +21 -21
- supervisely/annotation/label.py +4 -4
- supervisely/annotation/obj_class.py +9 -5
- supervisely/annotation/obj_class_collection.py +2 -2
- supervisely/annotation/tag.py +2 -2
- supervisely/annotation/tag_collection.py +3 -3
- supervisely/annotation/tag_meta.py +2 -2
- supervisely/annotation/tag_meta_collection.py +2 -2
- supervisely/api/agent_api.py +1 -1
- supervisely/api/annotation_api.py +1 -1
- supervisely/api/dataset_api.py +4 -4
- supervisely/api/entities_collection_api.py +1 -1
- supervisely/api/file_api.py +10 -10
- supervisely/api/image_api.py +9 -9
- supervisely/api/labeling_job_api.py +1 -1
- supervisely/api/labeling_queue_api.py +1 -1
- supervisely/api/module_api.py +6 -6
- supervisely/api/object_class_api.py +1 -1
- supervisely/api/plugin_api.py +1 -1
- supervisely/api/pointcloud/pointcloud_annotation_api.py +1 -1
- supervisely/api/pointcloud/pointcloud_api.py +1 -1
- supervisely/api/pointcloud/pointcloud_episode_annotation_api.py +1 -1
- supervisely/api/pointcloud/pointcloud_episode_api.py +1 -1
- supervisely/api/project_api.py +4 -4
- supervisely/api/remote_storage_api.py +6 -6
- supervisely/api/role_api.py +1 -1
- supervisely/api/storage_api.py +3 -3
- supervisely/api/task_api.py +1 -1
- supervisely/api/team_api.py +1 -1
- supervisely/api/user_api.py +1 -1
- supervisely/api/video/video_annotation_api.py +1 -1
- supervisely/api/video/video_api.py +4 -4
- supervisely/api/volume/volume_annotation_api.py +1 -1
- supervisely/api/volume/volume_api.py +1 -1
- supervisely/api/workspace_api.py +1 -2
- supervisely/app/development/sly-net.sh +2 -2
- supervisely/app/fastapi/index.html +3 -3
- supervisely/app/fastapi/subapp.py +1 -1
- supervisely/aug/aug.py +10 -10
- supervisely/cli/__init__.py +15 -10
- supervisely/geometry/alpha_mask.py +2 -2
- supervisely/geometry/bitmap.py +8 -6
- supervisely/geometry/bitmap_base.py +63 -24
- supervisely/geometry/cuboid.py +97 -50
- supervisely/geometry/cuboid_2d.py +2 -2
- supervisely/geometry/graph.py +4 -4
- supervisely/geometry/mask_3d.py +1 -1
- supervisely/geometry/point.py +63 -24
- supervisely/geometry/point_location.py +2 -2
- supervisely/geometry/polygon.py +2 -2
- supervisely/geometry/polyline.py +32 -40
- supervisely/geometry/rectangle.py +2 -2
- supervisely/geometry/vector_geometry.py +27 -39
- supervisely/io/env.py +3 -2
- supervisely/labeling_jobs/utils.py +5 -5
- supervisely/nn/model/prediction_session.py +2 -2
- supervisely/pointcloud/pointcloud.py +2 -2
- supervisely/pointcloud_annotation/pointcloud_annotation.py +19 -17
- supervisely/pointcloud_annotation/pointcloud_episode_annotation.py +23 -20
- supervisely/pointcloud_annotation/pointcloud_episode_frame.py +18 -12
- supervisely/pointcloud_annotation/pointcloud_episode_frame_collection.py +9 -6
- supervisely/pointcloud_annotation/pointcloud_episode_object_collection.py +7 -3
- supervisely/pointcloud_annotation/pointcloud_episode_tag.py +1 -1
- supervisely/pointcloud_annotation/pointcloud_episode_tag_collection.py +2 -2
- supervisely/pointcloud_annotation/pointcloud_figure.py +1 -1
- supervisely/pointcloud_annotation/pointcloud_object_collection.py +11 -10
- supervisely/pointcloud_annotation/pointcloud_tag.py +5 -4
- supervisely/pointcloud_annotation/pointcloud_tag_collection.py +7 -6
- supervisely/pointcloud_episodes/pointcloud_episodes.py +2 -2
- supervisely/project/download.py +1 -1
- supervisely/project/pointcloud_episode_project.py +1 -2
- supervisely/project/pointcloud_project.py +1 -1
- supervisely/project/project.py +8 -7
- supervisely/project/project_meta.py +2 -2
- supervisely/project/readme_template.md +1 -1
- supervisely/project/upload.py +1 -1
- supervisely/project/video_project.py +1 -1
- supervisely/project/volume_project.py +1 -1
- supervisely/task/progress.py +1 -1
- supervisely/video_annotation/frame.py +2 -2
- supervisely/video_annotation/frame_collection.py +3 -3
- supervisely/video_annotation/video_annotation.py +7 -5
- supervisely/video_annotation/video_figure.py +2 -2
- supervisely/video_annotation/video_object.py +47 -28
- supervisely/video_annotation/video_object_collection.py +15 -8
- supervisely/video_annotation/video_tag.py +2 -2
- supervisely/video_annotation/video_tag_collection.py +5 -5
- supervisely/volume_annotation/volume_figure.py +2 -2
- supervisely/volume_annotation/volume_tag.py +6 -5
- {supervisely-6.73.366.dist-info → supervisely-6.73.367.dist-info}/METADATA +2 -2
- {supervisely-6.73.366.dist-info → supervisely-6.73.367.dist-info}/RECORD +95 -95
- {supervisely-6.73.366.dist-info → supervisely-6.73.367.dist-info}/LICENSE +0 -0
- {supervisely-6.73.366.dist-info → supervisely-6.73.367.dist-info}/WHEEL +0 -0
- {supervisely-6.73.366.dist-info → supervisely-6.73.367.dist-info}/entry_points.txt +0 -0
- {supervisely-6.73.366.dist-info → supervisely-6.73.367.dist-info}/top_level.txt +0 -0
|
@@ -1,20 +1,34 @@
|
|
|
1
1
|
# coding: utf-8
|
|
2
2
|
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from typing import Dict, Optional, Tuple
|
|
5
|
+
|
|
3
6
|
import numpy as np
|
|
4
|
-
from typing import Tuple, Dict, Optional
|
|
5
7
|
|
|
6
|
-
from supervisely.geometry.constants import
|
|
7
|
-
|
|
8
|
+
from supervisely.geometry.constants import (
|
|
9
|
+
CLASS_ID,
|
|
10
|
+
CREATED_AT,
|
|
11
|
+
DATA,
|
|
12
|
+
GEOMETRY_SHAPE,
|
|
13
|
+
GEOMETRY_TYPE,
|
|
14
|
+
ID,
|
|
15
|
+
LABELER_LOGIN,
|
|
16
|
+
ORIGIN,
|
|
17
|
+
UPDATED_AT,
|
|
18
|
+
)
|
|
8
19
|
from supervisely.geometry.geometry import Geometry
|
|
9
20
|
from supervisely.geometry.point_location import PointLocation
|
|
10
21
|
from supervisely.geometry.rectangle import Rectangle
|
|
11
22
|
from supervisely.imaging.image import resize_inter_nearest, restore_proportional_size
|
|
12
23
|
|
|
24
|
+
if not hasattr(np, "bool"):
|
|
25
|
+
np.bool = np.bool_
|
|
13
26
|
|
|
14
|
-
if not hasattr(np, 'bool'): np.bool = np.bool_
|
|
15
27
|
|
|
16
28
|
# TODO: rename to resize_bitmap_and_origin
|
|
17
|
-
def resize_origin_and_bitmap(
|
|
29
|
+
def resize_origin_and_bitmap(
|
|
30
|
+
origin: PointLocation, bitmap: np.ndarray, in_size: Tuple[int, int], out_size: Tuple[int, int]
|
|
31
|
+
) -> Tuple[PointLocation, np.ndarray]:
|
|
18
32
|
"""
|
|
19
33
|
Change PointLocation and resize numpy array to match a certain size.
|
|
20
34
|
|
|
@@ -46,7 +60,9 @@ def resize_origin_and_bitmap(origin: PointLocation, bitmap: np.ndarray, in_size:
|
|
|
46
60
|
scaled_rows = max(round(bitmap.shape[0] * row_scale), 1)
|
|
47
61
|
scaled_cols = max(round(bitmap.shape[1] * col_scale), 1)
|
|
48
62
|
|
|
49
|
-
scaled_origin = PointLocation(
|
|
63
|
+
scaled_origin = PointLocation(
|
|
64
|
+
row=round(origin.row * row_scale), col=round(origin.col * col_scale)
|
|
65
|
+
)
|
|
50
66
|
scaled_bitmap = resize_inter_nearest(bitmap, (scaled_rows, scaled_cols))
|
|
51
67
|
return scaled_origin, scaled_bitmap
|
|
52
68
|
|
|
@@ -74,6 +90,7 @@ class BitmapBase(Geometry):
|
|
|
74
90
|
|
|
75
91
|
:Usage example: Example of creating and using see in :class:`Bitmap<supervisely.geometry.bitmap.Bitmap>`.
|
|
76
92
|
"""
|
|
93
|
+
|
|
77
94
|
def __init__(
|
|
78
95
|
self,
|
|
79
96
|
data: np.ndarray,
|
|
@@ -85,7 +102,13 @@ class BitmapBase(Geometry):
|
|
|
85
102
|
updated_at: Optional[str] = None,
|
|
86
103
|
created_at: Optional[str] = None,
|
|
87
104
|
):
|
|
88
|
-
super().__init__(
|
|
105
|
+
super().__init__(
|
|
106
|
+
sly_id=sly_id,
|
|
107
|
+
class_id=class_id,
|
|
108
|
+
labeler_login=labeler_login,
|
|
109
|
+
updated_at=updated_at,
|
|
110
|
+
created_at=created_at,
|
|
111
|
+
)
|
|
89
112
|
if origin is None:
|
|
90
113
|
origin = PointLocation(row=0, col=0)
|
|
91
114
|
|
|
@@ -111,19 +134,17 @@ class BitmapBase(Geometry):
|
|
|
111
134
|
|
|
112
135
|
@staticmethod
|
|
113
136
|
def base64_2_data(s: str) -> np.ndarray:
|
|
114
|
-
"""
|
|
115
|
-
"""
|
|
137
|
+
""" """
|
|
116
138
|
raise NotImplementedError()
|
|
117
139
|
|
|
118
140
|
@staticmethod
|
|
119
141
|
def data_2_base64(data: np.ndarray) -> str:
|
|
120
|
-
"""
|
|
121
|
-
"""
|
|
142
|
+
""" """
|
|
122
143
|
raise NotImplementedError()
|
|
123
144
|
|
|
124
145
|
def to_json(self) -> Dict:
|
|
125
146
|
"""
|
|
126
|
-
Convert the BitmapBase to a json dict. Read more about `Supervisely format <https://docs.
|
|
147
|
+
Convert the BitmapBase to a json dict. Read more about `Supervisely format <https://docs.supervisely.com/data-organization/00_ann_format_navi>`_.
|
|
127
148
|
|
|
128
149
|
:return: Json format as a dict
|
|
129
150
|
:rtype: :class:`dict`
|
|
@@ -154,7 +175,7 @@ class BitmapBase(Geometry):
|
|
|
154
175
|
res = {
|
|
155
176
|
self._impl_json_class_name(): {
|
|
156
177
|
ORIGIN: [self.origin.col, self.origin.row],
|
|
157
|
-
DATA: self.data_2_base64(self.data)
|
|
178
|
+
DATA: self.data_2_base64(self.data),
|
|
158
179
|
},
|
|
159
180
|
GEOMETRY_SHAPE: self.geometry_name(),
|
|
160
181
|
GEOMETRY_TYPE: self.geometry_name(),
|
|
@@ -165,7 +186,7 @@ class BitmapBase(Geometry):
|
|
|
165
186
|
@classmethod
|
|
166
187
|
def from_json(cls, json_data: Dict) -> BitmapBase:
|
|
167
188
|
"""
|
|
168
|
-
Convert a json dict to BitmapBase. Read more about `Supervisely format <https://docs.
|
|
189
|
+
Convert a json dict to BitmapBase. Read more about `Supervisely format <https://docs.supervisely.com/data-organization/00_ann_format_navi>`_.
|
|
169
190
|
|
|
170
191
|
:param data: Bitmap in json format as a dict.
|
|
171
192
|
:type data: dict
|
|
@@ -191,11 +212,17 @@ class BitmapBase(Geometry):
|
|
|
191
212
|
json_root_key = cls._impl_json_class_name()
|
|
192
213
|
if json_root_key not in json_data:
|
|
193
214
|
raise ValueError(
|
|
194
|
-
|
|
215
|
+
"Data must contain {} field to create MultichannelBitmap object.".format(
|
|
216
|
+
json_root_key
|
|
217
|
+
)
|
|
218
|
+
)
|
|
195
219
|
|
|
196
220
|
if ORIGIN not in json_data[json_root_key] or DATA not in json_data[json_root_key]:
|
|
197
|
-
raise ValueError(
|
|
198
|
-
|
|
221
|
+
raise ValueError(
|
|
222
|
+
"{} field must contain {} and {} fields to create MultichannelBitmap object.".format(
|
|
223
|
+
json_root_key, ORIGIN, DATA
|
|
224
|
+
)
|
|
225
|
+
)
|
|
199
226
|
|
|
200
227
|
col, row = json_data[json_root_key][ORIGIN]
|
|
201
228
|
data = cls.base64_2_data(json_data[json_root_key][DATA])
|
|
@@ -205,8 +232,15 @@ class BitmapBase(Geometry):
|
|
|
205
232
|
created_at = json_data.get(CREATED_AT, None)
|
|
206
233
|
sly_id = json_data.get(ID, None)
|
|
207
234
|
class_id = json_data.get(CLASS_ID, None)
|
|
208
|
-
return cls(
|
|
209
|
-
|
|
235
|
+
return cls(
|
|
236
|
+
data=data,
|
|
237
|
+
origin=PointLocation(row=row, col=col),
|
|
238
|
+
sly_id=sly_id,
|
|
239
|
+
class_id=class_id,
|
|
240
|
+
labeler_login=labeler_login,
|
|
241
|
+
updated_at=updated_at,
|
|
242
|
+
created_at=created_at,
|
|
243
|
+
)
|
|
210
244
|
|
|
211
245
|
@property
|
|
212
246
|
def origin(self) -> PointLocation:
|
|
@@ -267,7 +301,9 @@ class BitmapBase(Geometry):
|
|
|
267
301
|
fliplr_figure = figure.fliplr((height, width))
|
|
268
302
|
"""
|
|
269
303
|
flipped_mask = np.flip(self.data, axis=1)
|
|
270
|
-
flipped_origin = PointLocation(
|
|
304
|
+
flipped_origin = PointLocation(
|
|
305
|
+
row=self.origin.row, col=(img_size[1] - flipped_mask.shape[1] - self.origin.col)
|
|
306
|
+
)
|
|
271
307
|
return self.__class__(data=flipped_mask, origin=flipped_origin)
|
|
272
308
|
|
|
273
309
|
def flipud(self, img_size: Tuple[int, int]) -> BitmapBase:
|
|
@@ -288,7 +324,9 @@ class BitmapBase(Geometry):
|
|
|
288
324
|
flipud_figure = figure.flipud((height, width))
|
|
289
325
|
"""
|
|
290
326
|
flipped_mask = np.flip(self.data, axis=0)
|
|
291
|
-
flipped_origin = PointLocation(
|
|
327
|
+
flipped_origin = PointLocation(
|
|
328
|
+
row=(img_size[0] - flipped_mask.shape[0] - self.origin.row), col=self.origin.col
|
|
329
|
+
)
|
|
292
330
|
return self.__class__(data=flipped_mask, origin=flipped_origin)
|
|
293
331
|
|
|
294
332
|
def scale(self, factor: float) -> BitmapBase:
|
|
@@ -315,8 +353,7 @@ class BitmapBase(Geometry):
|
|
|
315
353
|
|
|
316
354
|
@staticmethod
|
|
317
355
|
def _resize_mask(mask, out_rows, out_cols):
|
|
318
|
-
"""
|
|
319
|
-
"""
|
|
356
|
+
""" """
|
|
320
357
|
return resize_inter_nearest(mask.astype(np.uint8), (out_rows, out_cols)).astype(np.bool)
|
|
321
358
|
|
|
322
359
|
def to_bbox(self) -> Rectangle:
|
|
@@ -332,4 +369,6 @@ class BitmapBase(Geometry):
|
|
|
332
369
|
|
|
333
370
|
rectangle = figure.to_bbox()
|
|
334
371
|
"""
|
|
335
|
-
return Rectangle.from_array(self._data).translate(
|
|
372
|
+
return Rectangle.from_array(self._data).translate(
|
|
373
|
+
drow=self._origin.row, dcol=self._origin.col
|
|
374
|
+
)
|
supervisely/geometry/cuboid.py
CHANGED
|
@@ -2,20 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
# docs
|
|
4
4
|
from __future__ import annotations
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
from typing import Dict, List, Optional, Tuple
|
|
7
|
+
|
|
6
8
|
import cv2
|
|
7
9
|
import numpy as np
|
|
8
|
-
from supervisely.geometry.image_rotator import ImageRotator
|
|
9
|
-
from supervisely.geometry.point_location import PointLocation
|
|
10
|
-
|
|
11
10
|
|
|
12
|
-
from supervisely.geometry.constants import
|
|
11
|
+
from supervisely.geometry.constants import (
|
|
12
|
+
CLASS_ID,
|
|
13
|
+
CREATED_AT,
|
|
14
|
+
FACES,
|
|
15
|
+
ID,
|
|
16
|
+
LABELER_LOGIN,
|
|
17
|
+
POINTS,
|
|
18
|
+
UPDATED_AT,
|
|
19
|
+
)
|
|
13
20
|
from supervisely.geometry.geometry import Geometry
|
|
14
|
-
from supervisely.geometry.
|
|
21
|
+
from supervisely.geometry.image_rotator import ImageRotator
|
|
22
|
+
from supervisely.geometry.point_location import (
|
|
23
|
+
PointLocation,
|
|
24
|
+
points_to_row_col_list,
|
|
25
|
+
row_col_list_to_points,
|
|
26
|
+
)
|
|
15
27
|
from supervisely.geometry.rectangle import Rectangle
|
|
16
28
|
|
|
29
|
+
if not hasattr(np, "bool"):
|
|
30
|
+
np.bool = np.bool_
|
|
17
31
|
|
|
18
|
-
if not hasattr(np, 'bool'): np.bool = np.bool_
|
|
19
32
|
|
|
20
33
|
class CuboidFace:
|
|
21
34
|
"""
|
|
@@ -35,6 +48,7 @@ class CuboidFace:
|
|
|
35
48
|
|
|
36
49
|
edge = CuboidFace(0, 1, 2, 3)
|
|
37
50
|
"""
|
|
51
|
+
|
|
38
52
|
def __init__(self, a: int, b: int, c: int, d: int):
|
|
39
53
|
self._a = a
|
|
40
54
|
self._b = b
|
|
@@ -43,7 +57,7 @@ class CuboidFace:
|
|
|
43
57
|
|
|
44
58
|
def to_json(self) -> List[int]:
|
|
45
59
|
"""
|
|
46
|
-
Convert the CuboidFace to list. Read more about `Supervisely format <https://docs.
|
|
60
|
+
Convert the CuboidFace to list. Read more about `Supervisely format <https://docs.supervisely.com/data-organization/00_ann_format_navi>`_.
|
|
47
61
|
|
|
48
62
|
:return: List of integers
|
|
49
63
|
:rtype: :class:`List[int, int, int, int]`
|
|
@@ -61,7 +75,7 @@ class CuboidFace:
|
|
|
61
75
|
@classmethod
|
|
62
76
|
def from_json(cls, data: List[int]) -> CuboidFace:
|
|
63
77
|
"""
|
|
64
|
-
Convert list of integers to CuboidFace. Read more about `Supervisely format <https://docs.
|
|
78
|
+
Convert list of integers to CuboidFace. Read more about `Supervisely format <https://docs.supervisely.com/data-organization/00_ann_format_navi>`_.
|
|
65
79
|
|
|
66
80
|
:param data: List of integers.
|
|
67
81
|
:type data: List[int, int, int, int]
|
|
@@ -75,31 +89,29 @@ class CuboidFace:
|
|
|
75
89
|
new_edge = CuboidFace.from_json([0, 1, 2, 3])
|
|
76
90
|
"""
|
|
77
91
|
if len(data) != 4:
|
|
78
|
-
raise ValueError(
|
|
92
|
+
raise ValueError(
|
|
93
|
+
f"CuboidFace JSON data must have exactly 4 indices, instead got {len(data)!r}."
|
|
94
|
+
)
|
|
79
95
|
return cls(data[0], data[1], data[2], data[3])
|
|
80
96
|
|
|
81
97
|
@property
|
|
82
98
|
def a(self):
|
|
83
|
-
"""
|
|
84
|
-
"""
|
|
99
|
+
""" """
|
|
85
100
|
return self._a
|
|
86
101
|
|
|
87
102
|
@property
|
|
88
103
|
def b(self):
|
|
89
|
-
"""
|
|
90
|
-
"""
|
|
104
|
+
""" """
|
|
91
105
|
return self._b
|
|
92
106
|
|
|
93
107
|
@property
|
|
94
108
|
def c(self):
|
|
95
|
-
"""
|
|
96
|
-
"""
|
|
109
|
+
""" """
|
|
97
110
|
return self._c
|
|
98
111
|
|
|
99
112
|
@property
|
|
100
113
|
def d(self):
|
|
101
|
-
"""
|
|
102
|
-
"""
|
|
114
|
+
""" """
|
|
103
115
|
return self._d
|
|
104
116
|
|
|
105
117
|
def tolist(self) -> List[int]:
|
|
@@ -151,28 +163,44 @@ class Cuboid(Geometry):
|
|
|
151
163
|
pl_nodes = (sly.PointLocation(node[0], node[1]) for node in nodes)
|
|
152
164
|
figure = sly.Cuboid(pl_nodes, edges)
|
|
153
165
|
"""
|
|
166
|
+
|
|
154
167
|
@staticmethod
|
|
155
168
|
def geometry_name():
|
|
156
|
-
"""
|
|
157
|
-
""
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
169
|
+
""" """
|
|
170
|
+
return "cuboid"
|
|
171
|
+
|
|
172
|
+
def __init__(
|
|
173
|
+
self,
|
|
174
|
+
points: List[PointLocation],
|
|
175
|
+
faces: List[CuboidFace],
|
|
176
|
+
sly_id: Optional[int] = None,
|
|
177
|
+
class_id: Optional[int] = None,
|
|
178
|
+
labeler_login: Optional[int] = None,
|
|
179
|
+
updated_at: Optional[str] = None,
|
|
180
|
+
created_at: Optional[str] = None,
|
|
181
|
+
):
|
|
182
|
+
|
|
183
|
+
super().__init__(
|
|
184
|
+
sly_id=sly_id,
|
|
185
|
+
class_id=class_id,
|
|
186
|
+
labeler_login=labeler_login,
|
|
187
|
+
updated_at=updated_at,
|
|
188
|
+
created_at=created_at,
|
|
189
|
+
)
|
|
164
190
|
|
|
165
191
|
points = list(points)
|
|
166
192
|
faces = list(faces)
|
|
167
193
|
|
|
168
194
|
if len(faces) != 3:
|
|
169
|
-
raise ValueError(f
|
|
195
|
+
raise ValueError(f"A cuboid must have exactly 3 faces. Instead got {len(faces)} faces.")
|
|
170
196
|
|
|
171
197
|
for face in faces:
|
|
172
198
|
for point_idx in (face.a, face.b, face.c, face.d):
|
|
173
199
|
if point_idx >= len(points) or point_idx < 0:
|
|
174
|
-
raise ValueError(
|
|
175
|
-
|
|
200
|
+
raise ValueError(
|
|
201
|
+
f"Point index is out of bounds for cuboid face. Got {len(points)!r} points, but "
|
|
202
|
+
f"the index is {point_idx!r}."
|
|
203
|
+
)
|
|
176
204
|
|
|
177
205
|
self._points = points
|
|
178
206
|
self._faces = faces
|
|
@@ -199,7 +227,7 @@ class Cuboid(Geometry):
|
|
|
199
227
|
|
|
200
228
|
def to_json(self) -> Dict:
|
|
201
229
|
"""
|
|
202
|
-
Convert the Cuboid to a json dict. Read more about `Supervisely format <https://docs.
|
|
230
|
+
Convert the Cuboid to a json dict. Read more about `Supervisely format <https://docs.supervisely.com/data-organization/00_ann_format_navi>`_.
|
|
203
231
|
|
|
204
232
|
:return: Json format as a dict
|
|
205
233
|
:rtype: :class:`dict`
|
|
@@ -236,7 +264,7 @@ class Cuboid(Geometry):
|
|
|
236
264
|
"""
|
|
237
265
|
packed_obj = {
|
|
238
266
|
POINTS: points_to_row_col_list(self._points, flip_row_col_order=True),
|
|
239
|
-
FACES: [face.to_json() for face in self._faces]
|
|
267
|
+
FACES: [face.to_json() for face in self._faces],
|
|
240
268
|
}
|
|
241
269
|
self._add_creation_info(packed_obj)
|
|
242
270
|
return packed_obj
|
|
@@ -244,7 +272,7 @@ class Cuboid(Geometry):
|
|
|
244
272
|
@classmethod
|
|
245
273
|
def from_json(cls, data: Dict) -> Cuboid:
|
|
246
274
|
"""
|
|
247
|
-
Convert a json dict to Cuboid. Read more about `Supervisely format <https://docs.
|
|
275
|
+
Convert a json dict to Cuboid. Read more about `Supervisely format <https://docs.supervisely.com/data-organization/00_ann_format_navi>`_.
|
|
248
276
|
|
|
249
277
|
:param data: Cuboid in json format as a dict.
|
|
250
278
|
:type data: dict
|
|
@@ -278,7 +306,7 @@ class Cuboid(Geometry):
|
|
|
278
306
|
"""
|
|
279
307
|
for k in [POINTS, FACES]:
|
|
280
308
|
if k not in data:
|
|
281
|
-
raise ValueError(f
|
|
309
|
+
raise ValueError(f"Field {k!r} not found in Cuboid JSON data.")
|
|
282
310
|
|
|
283
311
|
points = row_col_list_to_points(data[POINTS], flip_row_col_order=True)
|
|
284
312
|
faces = [CuboidFace.from_json(face_json) for face_json in data[FACES]]
|
|
@@ -288,8 +316,15 @@ class Cuboid(Geometry):
|
|
|
288
316
|
created_at = data.get(CREATED_AT, None)
|
|
289
317
|
sly_id = data.get(ID, None)
|
|
290
318
|
class_id = data.get(CLASS_ID, None)
|
|
291
|
-
return cls(
|
|
292
|
-
|
|
319
|
+
return cls(
|
|
320
|
+
points=points,
|
|
321
|
+
faces=faces,
|
|
322
|
+
sly_id=sly_id,
|
|
323
|
+
class_id=class_id,
|
|
324
|
+
labeler_login=labeler_login,
|
|
325
|
+
updated_at=updated_at,
|
|
326
|
+
created_at=created_at,
|
|
327
|
+
)
|
|
293
328
|
|
|
294
329
|
def crop(self, rect: Rectangle) -> List[Cuboid]:
|
|
295
330
|
"""
|
|
@@ -314,12 +349,14 @@ class Cuboid(Geometry):
|
|
|
314
349
|
crop_figures = figure.crop(sly.Rectangle(1, 1, 1500, 1550))
|
|
315
350
|
"""
|
|
316
351
|
is_all_nodes_inside = all(
|
|
317
|
-
rect.contains_point_location(self._points[p])
|
|
352
|
+
rect.contains_point_location(self._points[p])
|
|
353
|
+
for face in self._faces
|
|
354
|
+
for p in face.tolist()
|
|
355
|
+
)
|
|
318
356
|
return [self] if is_all_nodes_inside else []
|
|
319
357
|
|
|
320
358
|
def _transform(self, transform_fn):
|
|
321
|
-
"""
|
|
322
|
-
"""
|
|
359
|
+
""" """
|
|
323
360
|
return Cuboid(points=[transform_fn(p) for p in self.points], faces=self.faces)
|
|
324
361
|
|
|
325
362
|
def rotate(self, rotator: ImageRotator) -> Cuboid:
|
|
@@ -489,8 +526,7 @@ class Cuboid(Geometry):
|
|
|
489
526
|
return self._transform(lambda p: p.flipud(img_size))
|
|
490
527
|
|
|
491
528
|
def _draw_impl(self, bitmap: np.ndarray, color, thickness=1, config=None):
|
|
492
|
-
"""
|
|
493
|
-
"""
|
|
529
|
+
""" """
|
|
494
530
|
bmp_to_draw = np.zeros(bitmap.shape[:2], np.uint8)
|
|
495
531
|
for contour in self._contours_list():
|
|
496
532
|
cv2.fillPoly(bmp_to_draw, pts=[np.array(contour, dtype=np.int32)], color=1)
|
|
@@ -498,16 +534,18 @@ class Cuboid(Geometry):
|
|
|
498
534
|
bitmap[bool_mask] = color
|
|
499
535
|
|
|
500
536
|
def _draw_contour_impl(self, bitmap, color, thickness=1, config=None):
|
|
501
|
-
"""
|
|
502
|
-
"""
|
|
537
|
+
""" """
|
|
503
538
|
contours_np_list = [np.array(contour, dtype=np.int32) for contour in self._contours_list()]
|
|
504
539
|
cv2.polylines(bitmap, pts=contours_np_list, isClosed=True, color=color, thickness=thickness)
|
|
505
540
|
|
|
506
541
|
def _contours_list(self):
|
|
507
|
-
"""
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
for
|
|
542
|
+
""" """
|
|
543
|
+
return [
|
|
544
|
+
points_to_row_col_list(
|
|
545
|
+
[self._points[idx] for idx in face.tolist()], flip_row_col_order=True
|
|
546
|
+
)
|
|
547
|
+
for face in self._faces
|
|
548
|
+
]
|
|
511
549
|
|
|
512
550
|
def to_bbox(self) -> Rectangle:
|
|
513
551
|
"""
|
|
@@ -530,11 +568,20 @@ class Cuboid(Geometry):
|
|
|
530
568
|
|
|
531
569
|
rectangle = figure.to_bbox()
|
|
532
570
|
"""
|
|
533
|
-
points_np = np.array(
|
|
534
|
-
|
|
571
|
+
points_np = np.array(
|
|
572
|
+
[
|
|
573
|
+
[self._points[p].row, self._points[p].col]
|
|
574
|
+
for face in self._faces
|
|
575
|
+
for p in face.tolist()
|
|
576
|
+
]
|
|
577
|
+
)
|
|
535
578
|
rows, cols = points_np[:, 0], points_np[:, 1]
|
|
536
|
-
return Rectangle(
|
|
537
|
-
|
|
579
|
+
return Rectangle(
|
|
580
|
+
top=round(min(rows).item()),
|
|
581
|
+
left=round(min(cols).item()),
|
|
582
|
+
bottom=round(max(rows).item()),
|
|
583
|
+
right=round(max(cols).item()),
|
|
584
|
+
)
|
|
538
585
|
|
|
539
586
|
@property
|
|
540
587
|
def area(self) -> float:
|
|
@@ -151,7 +151,7 @@ class Cuboid2d(GraphNodes):
|
|
|
151
151
|
@classmethod
|
|
152
152
|
def from_json(cls, data: Dict[str, Dict]) -> Cuboid2d:
|
|
153
153
|
"""
|
|
154
|
-
Convert a json dict to Cuboid2d. Read more about `Supervisely format <https://docs.
|
|
154
|
+
Convert a json dict to Cuboid2d. Read more about `Supervisely format <https://docs.supervisely.com/data-organization/00_ann_format_navi>`_.
|
|
155
155
|
|
|
156
156
|
:param data: Cuboid2d in json format as a dict.
|
|
157
157
|
:type data: Dict[str, Dict]
|
|
@@ -214,7 +214,7 @@ class Cuboid2d(GraphNodes):
|
|
|
214
214
|
|
|
215
215
|
def to_json(self) -> Dict[str, Dict]:
|
|
216
216
|
"""
|
|
217
|
-
Convert the Cuboid2d to list. Read more about `Supervisely format <https://docs.
|
|
217
|
+
Convert the Cuboid2d to list. Read more about `Supervisely format <https://docs.supervisely.com/data-organization/00_ann_format_navi>`_.
|
|
218
218
|
|
|
219
219
|
:return: Json format as a dict
|
|
220
220
|
:rtype: Dict[str, Dict]
|
supervisely/geometry/graph.py
CHANGED
|
@@ -96,7 +96,7 @@ class Node(JsonSerializable):
|
|
|
96
96
|
@classmethod
|
|
97
97
|
def from_json(cls, data: Dict) -> Node:
|
|
98
98
|
"""
|
|
99
|
-
Convert a json dict to Node. Read more about `Supervisely format <https://docs.
|
|
99
|
+
Convert a json dict to Node. Read more about `Supervisely format <https://docs.supervisely.com/data-organization/00_ann_format_navi>`_.
|
|
100
100
|
|
|
101
101
|
:param data: Node in json format as a dict.
|
|
102
102
|
:type data: dict
|
|
@@ -120,7 +120,7 @@ class Node(JsonSerializable):
|
|
|
120
120
|
|
|
121
121
|
def to_json(self) -> Dict:
|
|
122
122
|
"""
|
|
123
|
-
Convert the Node to a json dict. Read more about `Supervisely format <https://docs.
|
|
123
|
+
Convert the Node to a json dict. Read more about `Supervisely format <https://docs.supervisely.com/data-organization/00_ann_format_navi>`_.
|
|
124
124
|
|
|
125
125
|
:return: Json format as a dict
|
|
126
126
|
:rtype: :class:`dict`
|
|
@@ -240,7 +240,7 @@ class GraphNodes(Geometry):
|
|
|
240
240
|
@classmethod
|
|
241
241
|
def from_json(cls, data: Dict[str, Dict]) -> GraphNodes:
|
|
242
242
|
"""
|
|
243
|
-
Convert a json dict to GraphNodes. Read more about `Supervisely format <https://docs.
|
|
243
|
+
Convert a json dict to GraphNodes. Read more about `Supervisely format <https://docs.supervisely.com/data-organization/00_ann_format_navi>`_.
|
|
244
244
|
|
|
245
245
|
:param data: GraphNodes in json format as a dict.
|
|
246
246
|
:type data: dict
|
|
@@ -286,7 +286,7 @@ class GraphNodes(Geometry):
|
|
|
286
286
|
|
|
287
287
|
def to_json(self) -> Dict[str, Dict]:
|
|
288
288
|
"""
|
|
289
|
-
Convert the GraphNodes to list. Read more about `Supervisely format <https://docs.
|
|
289
|
+
Convert the GraphNodes to list. Read more about `Supervisely format <https://docs.supervisely.com/data-organization/00_ann_format_navi>`_.
|
|
290
290
|
|
|
291
291
|
:return: Json format as a dict
|
|
292
292
|
:rtype: :class:`dict`
|
supervisely/geometry/mask_3d.py
CHANGED