supervisely 6.73.281__py3-none-any.whl → 6.73.283__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.
Potentially problematic release.
This version of supervisely might be problematic. Click here for more details.
- supervisely/convert/base_converter.py +1 -0
- supervisely/convert/image/cityscapes/cityscapes_converter.py +8 -0
- supervisely/convert/image/coco/coco_anntotation_converter.py +8 -0
- supervisely/convert/image/coco/coco_converter.py +6 -1
- supervisely/convert/image/coco/coco_helper.py +1 -1
- supervisely/convert/image/image_converter.py +14 -14
- supervisely/convert/image/multi_view/multi_view.py +17 -2
- supervisely/convert/image/yolo/yolo_converter.py +7 -1
- supervisely/convert/pointcloud_episodes/nuscenes_conv/nuscenes_converter.py +12 -18
- supervisely/convert/pointcloud_episodes/nuscenes_conv/nuscenes_helper.py +5 -5
- supervisely/geometry/cuboid_2d.py +182 -10
- {supervisely-6.73.281.dist-info → supervisely-6.73.283.dist-info}/METADATA +1 -1
- {supervisely-6.73.281.dist-info → supervisely-6.73.283.dist-info}/RECORD +17 -17
- {supervisely-6.73.281.dist-info → supervisely-6.73.283.dist-info}/LICENSE +0 -0
- {supervisely-6.73.281.dist-info → supervisely-6.73.283.dist-info}/WHEEL +0 -0
- {supervisely-6.73.281.dist-info → supervisely-6.73.283.dist-info}/entry_points.txt +0 -0
- {supervisely-6.73.281.dist-info → supervisely-6.73.283.dist-info}/top_level.txt +0 -0
|
@@ -168,6 +168,7 @@ class BaseConverter:
|
|
|
168
168
|
self._upload_as_links: bool = upload_as_links
|
|
169
169
|
self._remote_files_map: Optional[Dict[str, str]] = remote_files_map
|
|
170
170
|
self._supports_links = False # if converter supports uploading by links
|
|
171
|
+
self._force_shape_for_links = False
|
|
171
172
|
self._api = Api.from_env() if self._upload_as_links else None
|
|
172
173
|
self._team_id = team_id() if self._upload_as_links else None
|
|
173
174
|
self._converter = None
|
|
@@ -34,6 +34,8 @@ class CityscapesConverter(ImageConverter):
|
|
|
34
34
|
super().__init__(input_data, labeling_interface, upload_as_links, remote_files_map)
|
|
35
35
|
|
|
36
36
|
self._classes_mapping = {}
|
|
37
|
+
self._supports_links = True
|
|
38
|
+
self._force_shape_for_links = self.upload_as_links
|
|
37
39
|
|
|
38
40
|
def __str__(self):
|
|
39
41
|
return AvailableImageConverters.CITYSCAPES
|
|
@@ -41,6 +43,10 @@ class CityscapesConverter(ImageConverter):
|
|
|
41
43
|
@property
|
|
42
44
|
def key_file_ext(self) -> str:
|
|
43
45
|
return ".json"
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def ann_ext(self) -> str:
|
|
49
|
+
return ".json"
|
|
44
50
|
|
|
45
51
|
def ann_file_ext(self) -> str:
|
|
46
52
|
return ".json"
|
|
@@ -108,6 +114,8 @@ class CityscapesConverter(ImageConverter):
|
|
|
108
114
|
return False
|
|
109
115
|
|
|
110
116
|
def validate_format(self) -> bool:
|
|
117
|
+
if self.upload_as_links:
|
|
118
|
+
self._download_remote_ann_files()
|
|
111
119
|
detected_ann_cnt = 0
|
|
112
120
|
images_list, ann_dict = [], {}
|
|
113
121
|
for root, _, files in os.walk(self._input_data):
|
|
@@ -37,6 +37,7 @@ class FastCOCOConverter(COCOConverter, ImageConverter):
|
|
|
37
37
|
self._items = []
|
|
38
38
|
meta = ProjectMeta()
|
|
39
39
|
warnings = defaultdict(list)
|
|
40
|
+
item_names = set()
|
|
40
41
|
for ann_path in ann_paths:
|
|
41
42
|
try:
|
|
42
43
|
with coco_helper.HiddenCocoPrints():
|
|
@@ -74,11 +75,18 @@ class FastCOCOConverter(COCOConverter, ImageConverter):
|
|
|
74
75
|
coco_ann = coco_anns[image_id]
|
|
75
76
|
if len(coco_ann) == 0 or coco_ann is None or image_name is None:
|
|
76
77
|
continue
|
|
78
|
+
if image_name in item_names:
|
|
79
|
+
# * Block to handle the case when there are mixed annotations: caption and segmentations for the same images
|
|
80
|
+
item = next(item for item in self._items if item.name == image_name)
|
|
81
|
+
if item.shape == (height, width):
|
|
82
|
+
item.ann_data.extend(coco_ann)
|
|
83
|
+
continue
|
|
77
84
|
item = self.Item(image_name) if image_url is None else self.Item(image_url)
|
|
78
85
|
item.name = image_name
|
|
79
86
|
item.ann_data = coco_ann
|
|
80
87
|
item.set_shape((height, width))
|
|
81
88
|
self._items.append(item)
|
|
89
|
+
item_names.add(image_name)
|
|
82
90
|
detected_ann_cnt += len(coco_ann)
|
|
83
91
|
|
|
84
92
|
self._meta = meta
|
|
@@ -25,6 +25,8 @@ class COCOConverter(ImageConverter):
|
|
|
25
25
|
super().__init__(input_data, labeling_interface, upload_as_links, remote_files_map)
|
|
26
26
|
|
|
27
27
|
self._coco_categories = []
|
|
28
|
+
self._supports_links = True
|
|
29
|
+
self._force_shape_for_links = self.upload_as_links
|
|
28
30
|
|
|
29
31
|
def __str__(self) -> str:
|
|
30
32
|
return AvailableImageConverters.COCO
|
|
@@ -56,6 +58,8 @@ class COCOConverter(ImageConverter):
|
|
|
56
58
|
def validate_format(self) -> bool:
|
|
57
59
|
from pycocotools.coco import COCO # pylint: disable=import-error
|
|
58
60
|
|
|
61
|
+
if self.upload_as_links:
|
|
62
|
+
self._download_remote_ann_files()
|
|
59
63
|
detected_ann_cnt = 0
|
|
60
64
|
images_list, ann_paths = [], []
|
|
61
65
|
for root, _, files in os.walk(self._input_data):
|
|
@@ -145,7 +149,8 @@ class COCOConverter(ImageConverter):
|
|
|
145
149
|
if item.ann_data is None:
|
|
146
150
|
return Annotation.from_img_path(item.path)
|
|
147
151
|
else:
|
|
148
|
-
|
|
152
|
+
if not self.upload_as_links:
|
|
153
|
+
item.set_shape()
|
|
149
154
|
ann = coco_helper.create_supervisely_annotation(
|
|
150
155
|
item,
|
|
151
156
|
meta,
|
|
@@ -182,7 +182,7 @@ def convert_rle_mask_to_polygon(coco_ann):
|
|
|
182
182
|
return Bitmap(mask).to_contours()
|
|
183
183
|
|
|
184
184
|
|
|
185
|
-
def convert_polygon_vertices(coco_ann, image_size):
|
|
185
|
+
def convert_polygon_vertices(coco_ann, image_size: Tuple[int, int]):
|
|
186
186
|
polygons = coco_ann["segmentation"]
|
|
187
187
|
if all(type(coord) is float for coord in polygons):
|
|
188
188
|
polygons = [polygons]
|
|
@@ -136,20 +136,16 @@ class ImageConverter(BaseConverter):
|
|
|
136
136
|
item_names = []
|
|
137
137
|
item_paths = []
|
|
138
138
|
item_metas = []
|
|
139
|
-
anns = []
|
|
140
139
|
for item in batch:
|
|
141
140
|
item.path = self.validate_image(item.path)
|
|
142
141
|
if item.path is None:
|
|
143
142
|
continue # image has failed validation
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
ann = self.to_supervisely(item, meta, renamed_classes, renamed_tags)
|
|
149
|
-
name = generate_free_name(
|
|
150
|
-
existing_names, item.name, with_ext=True, extend_used_names=True
|
|
143
|
+
name = f"{get_file_name(item.path)}{get_file_ext(item.path).lower()}"
|
|
144
|
+
|
|
145
|
+
item.name = generate_free_name(
|
|
146
|
+
existing_names, name, with_ext=True, extend_used_names=True
|
|
151
147
|
)
|
|
152
|
-
item_names.append(name)
|
|
148
|
+
item_names.append(item.name)
|
|
153
149
|
item_paths.append(item.path)
|
|
154
150
|
|
|
155
151
|
if isinstance(item.meta, str): # path to file
|
|
@@ -159,9 +155,6 @@ class ImageConverter(BaseConverter):
|
|
|
159
155
|
else:
|
|
160
156
|
item_metas.append({})
|
|
161
157
|
|
|
162
|
-
if ann is not None:
|
|
163
|
-
anns.append(ann)
|
|
164
|
-
|
|
165
158
|
with ApiContext(
|
|
166
159
|
api=api, project_id=project_id, dataset_id=dataset_id, project_meta=meta
|
|
167
160
|
):
|
|
@@ -173,7 +166,7 @@ class ImageConverter(BaseConverter):
|
|
|
173
166
|
metas=item_metas,
|
|
174
167
|
batch_size=batch_size,
|
|
175
168
|
conflict_resolution="rename",
|
|
176
|
-
force_metadata_for_links=
|
|
169
|
+
force_metadata_for_links=self._force_shape_for_links,
|
|
177
170
|
)
|
|
178
171
|
else:
|
|
179
172
|
img_infos = api.image.upload_paths(
|
|
@@ -183,8 +176,15 @@ class ImageConverter(BaseConverter):
|
|
|
183
176
|
metas=item_metas,
|
|
184
177
|
conflict_resolution="rename",
|
|
185
178
|
)
|
|
186
|
-
|
|
187
179
|
img_ids = [img_info.id for img_info in img_infos]
|
|
180
|
+
|
|
181
|
+
anns = []
|
|
182
|
+
if not (self.upload_as_links and not self.supports_links):
|
|
183
|
+
for info, item in zip(img_infos, batch):
|
|
184
|
+
if self._force_shape_for_links:
|
|
185
|
+
item.set_shape((info.height, info.width))
|
|
186
|
+
anns.append(self.to_supervisely(item, meta, renamed_classes, renamed_tags))
|
|
187
|
+
|
|
188
188
|
if len(anns) == len(img_ids):
|
|
189
189
|
api.annotation.upload_anns(
|
|
190
190
|
img_ids, anns, skip_bounds_validation=self.upload_as_links
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from collections import defaultdict
|
|
3
|
-
from typing import Dict, Union
|
|
3
|
+
from typing import Dict, Union, Optional
|
|
4
4
|
|
|
5
5
|
from supervisely import ProjectMeta, generate_free_name, is_development, logger
|
|
6
6
|
from supervisely.api.api import Api, ApiContext
|
|
@@ -13,6 +13,18 @@ from supervisely.project.project_settings import LabelingInterface
|
|
|
13
13
|
|
|
14
14
|
class MultiViewImageConverter(ImageConverter):
|
|
15
15
|
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
input_data: str,
|
|
19
|
+
labeling_interface: Optional[Union[LabelingInterface, str]],
|
|
20
|
+
upload_as_links: bool,
|
|
21
|
+
remote_files_map: Optional[Dict[str, str]] = None,
|
|
22
|
+
):
|
|
23
|
+
super().__init__(input_data, labeling_interface, upload_as_links, remote_files_map)
|
|
24
|
+
|
|
25
|
+
self._supports_links = True
|
|
26
|
+
self._force_shape_for_links = self.upload_as_links
|
|
27
|
+
|
|
16
28
|
def __str__(self):
|
|
17
29
|
return AvailableImageConverters.MULTI_VIEW
|
|
18
30
|
|
|
@@ -79,13 +91,16 @@ class MultiViewImageConverter(ImageConverter):
|
|
|
79
91
|
logger.warn(f"Image '{name}' already exists. Renamed to '{new_name}'.")
|
|
80
92
|
os.rename(image, os.path.join(group_path, new_name))
|
|
81
93
|
image = os.path.join(group_path, new_name)
|
|
94
|
+
if self._upload_as_links:
|
|
95
|
+
image = self.remote_files_map.get(image, image)
|
|
82
96
|
images.append(image)
|
|
83
97
|
|
|
84
98
|
with ApiContext(
|
|
85
99
|
api=api, project_id=project_id, dataset_id=dataset_id, project_meta=meta
|
|
86
100
|
):
|
|
101
|
+
kwarg = {"links": images} if self.upload_as_links else {"paths": images}
|
|
87
102
|
api.image.upload_multiview_images(
|
|
88
|
-
dataset.id, group_name,
|
|
103
|
+
dataset.id, group_name, **kwarg, progress_cb=progress_cb
|
|
89
104
|
)
|
|
90
105
|
|
|
91
106
|
if log_progress:
|
|
@@ -38,6 +38,8 @@ class YOLOConverter(ImageConverter):
|
|
|
38
38
|
self._coco_classes_dict: dict = {}
|
|
39
39
|
self._num_kpts = None
|
|
40
40
|
self._num_dims = None
|
|
41
|
+
self._supports_links = True
|
|
42
|
+
self._force_shape_for_links = self.upload_as_links
|
|
41
43
|
|
|
42
44
|
def __str__(self) -> str:
|
|
43
45
|
return AvailableImageConverters.YOLO
|
|
@@ -151,6 +153,9 @@ class YOLOConverter(ImageConverter):
|
|
|
151
153
|
return False
|
|
152
154
|
|
|
153
155
|
def validate_format(self) -> bool:
|
|
156
|
+
if self.upload_as_links:
|
|
157
|
+
self._download_remote_ann_files()
|
|
158
|
+
|
|
154
159
|
detected_ann_cnt = 0
|
|
155
160
|
config_path = None
|
|
156
161
|
images_list, ann_dict = [], {}
|
|
@@ -238,7 +243,8 @@ class YOLOConverter(ImageConverter):
|
|
|
238
243
|
|
|
239
244
|
try:
|
|
240
245
|
labels = []
|
|
241
|
-
|
|
246
|
+
if not self.upload_as_links:
|
|
247
|
+
item.set_shape()
|
|
242
248
|
height, width = item.shape
|
|
243
249
|
with open(item.ann_data, "r") as ann_file:
|
|
244
250
|
lines = ann_file.readlines()
|
|
@@ -61,35 +61,27 @@ class NuscenesEpisodesConverter(PointcloudEpisodeConverter):
|
|
|
61
61
|
return False
|
|
62
62
|
|
|
63
63
|
def filter_fn(path):
|
|
64
|
-
return all(
|
|
65
|
-
[
|
|
66
|
-
(Path(path) / name).exists()
|
|
67
|
-
for name in ["maps", "samples", "sweeps", "v1.0-mini"]
|
|
68
|
-
]
|
|
69
|
-
)
|
|
64
|
+
return all([(Path(path) / name).exists() for name in ["maps", "samples"]])
|
|
70
65
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
except IndexError:
|
|
66
|
+
input_path = next((d for d in fs.dirs_filter(self._input_data, filter_fn)), None)
|
|
67
|
+
if input_path is None:
|
|
74
68
|
return False
|
|
75
69
|
|
|
76
70
|
sample_dir = input_path + "/samples/"
|
|
77
71
|
if any([not fs.dir_exists(f"{sample_dir}/{d}") for d in helpers.DIR_NAMES]):
|
|
78
72
|
return False
|
|
79
73
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
ann_dir = input_path + "/v1.0-mini/"
|
|
85
|
-
if any([not fs.file_exists(f"{ann_dir}/{d}.json") for d in helpers.TABLE_NAMES]):
|
|
74
|
+
fil_fn = lambda p: all(fs.file_exists(f"{p}/{name}.json") for name in helpers.TABLE_NAMES)
|
|
75
|
+
ann_dir = next((d for d in fs.dirs_filter(input_path, fil_fn)), None)
|
|
76
|
+
if ann_dir is None:
|
|
86
77
|
return False
|
|
87
78
|
|
|
79
|
+
version = osp.basename(ann_dir)
|
|
88
80
|
try:
|
|
89
81
|
t = TinyTimer()
|
|
90
|
-
nuscenes = NuScenes(dataroot=input_path, verbose=False)
|
|
82
|
+
nuscenes = NuScenes(version=version, dataroot=input_path, verbose=False)
|
|
91
83
|
self._nuscenes: NuScenes = nuscenes
|
|
92
|
-
logger.
|
|
84
|
+
logger.debug(f"NuScenes initialization took {t.get_sec():.3f} sec")
|
|
93
85
|
except Exception as e:
|
|
94
86
|
logger.debug(f"Failed to initialize NuScenes: {e}")
|
|
95
87
|
return False
|
|
@@ -184,7 +176,9 @@ class NuscenesEpisodesConverter(PointcloudEpisodeConverter):
|
|
|
184
176
|
scene_name_to_dataset[scene_names[0]] = dataset_info
|
|
185
177
|
|
|
186
178
|
if log_progress:
|
|
187
|
-
progress, progress_cb = self.get_progress(
|
|
179
|
+
progress, progress_cb = self.get_progress(
|
|
180
|
+
total_sample_cnt, "Converting episode scenes..."
|
|
181
|
+
)
|
|
188
182
|
else:
|
|
189
183
|
progress_cb = None
|
|
190
184
|
|
|
@@ -16,11 +16,11 @@ DIR_NAMES = [
|
|
|
16
16
|
"CAM_FRONT_LEFT",
|
|
17
17
|
"CAM_FRONT_RIGHT",
|
|
18
18
|
"LIDAR_TOP",
|
|
19
|
-
"RADAR_FRONT",
|
|
20
|
-
"RADAR_FRONT_LEFT",
|
|
21
|
-
"RADAR_FRONT_RIGHT",
|
|
22
|
-
"RADAR_BACK_LEFT",
|
|
23
|
-
"RADAR_BACK_RIGHT",
|
|
19
|
+
# "RADAR_FRONT",
|
|
20
|
+
# "RADAR_FRONT_LEFT",
|
|
21
|
+
# "RADAR_FRONT_RIGHT",
|
|
22
|
+
# "RADAR_BACK_LEFT",
|
|
23
|
+
# "RADAR_BACK_RIGHT",
|
|
24
24
|
]
|
|
25
25
|
|
|
26
26
|
TABLE_NAMES = [
|
|
@@ -8,6 +8,13 @@ from typing import Dict, List, Optional, Union
|
|
|
8
8
|
|
|
9
9
|
import numpy as np
|
|
10
10
|
|
|
11
|
+
from supervisely.geometry.constants import (
|
|
12
|
+
CLASS_ID,
|
|
13
|
+
CREATED_AT,
|
|
14
|
+
ID,
|
|
15
|
+
LABELER_LOGIN,
|
|
16
|
+
UPDATED_AT,
|
|
17
|
+
)
|
|
11
18
|
from supervisely.geometry.geometry import Geometry
|
|
12
19
|
from supervisely.geometry.graph import EDGES, GraphNodes, Node, _maybe_transform_colors
|
|
13
20
|
from supervisely.geometry.point_location import PointLocation
|
|
@@ -36,19 +43,19 @@ CUBOID2D_EDGES_MAPPING = [
|
|
|
36
43
|
|
|
37
44
|
class Cuboid2d(GraphNodes):
|
|
38
45
|
"""
|
|
39
|
-
|
|
46
|
+
Cuboid2d geometry for a single :class:`Label<supervisely.annotation.label.Label>`. :class:`Cuboid2d<Cuboid2d>` class object is immutable.
|
|
40
47
|
|
|
41
48
|
:param nodes: Dict or List containing nodes of graph
|
|
42
49
|
:type nodes: dict
|
|
43
|
-
:param sly_id:
|
|
50
|
+
:param sly_id: Cuboid2d ID in Supervisely server.
|
|
44
51
|
:type sly_id: int, optional
|
|
45
|
-
:param class_id: ID of :class:`ObjClass<supervisely.annotation.obj_class.ObjClass>` to which
|
|
52
|
+
:param class_id: ID of :class:`ObjClass<supervisely.annotation.obj_class.ObjClass>` to which Cuboid2d belongs.
|
|
46
53
|
:type class_id: int, optional
|
|
47
|
-
:param labeler_login: Login of the user who created
|
|
54
|
+
:param labeler_login: Login of the user who created Cuboid2d.
|
|
48
55
|
:type labeler_login: str, optional
|
|
49
|
-
:param updated_at: Date and Time when
|
|
56
|
+
:param updated_at: Date and Time when Cuboid2d was modified last. Date Format: Year:Month:Day:Hour:Minute:Seconds. Example: '2021-01-22T19:37:50.158Z'.
|
|
50
57
|
:type updated_at: str, optional
|
|
51
|
-
:param created_at: Date and Time when
|
|
58
|
+
:param created_at: Date and Time when Cuboid2d was created. Date Format is the same as in "updated_at" parameter.
|
|
52
59
|
:type created_at: str, optional
|
|
53
60
|
|
|
54
61
|
:Usage example:
|
|
@@ -56,13 +63,13 @@ class Cuboid2d(GraphNodes):
|
|
|
56
63
|
.. code-block:: python
|
|
57
64
|
|
|
58
65
|
import supervisely as sly
|
|
59
|
-
from supervisely.geometry.graph import Node,
|
|
66
|
+
from supervisely.geometry.graph import Node, Cuboid2d
|
|
60
67
|
|
|
61
68
|
vertex_1 = Node(sly.PointLocation(5, 5))
|
|
62
69
|
vertex_2 = Node(sly.PointLocation(100, 100))
|
|
63
70
|
vertex_3 = Node(sly.PointLocation(200, 250))
|
|
64
71
|
nodes = {0: vertex_1, 1: vertex_2, 2: vertex_3}
|
|
65
|
-
figure =
|
|
72
|
+
figure = Cuboid2d(nodes)
|
|
66
73
|
"""
|
|
67
74
|
|
|
68
75
|
items_json_field = VERTICES
|
|
@@ -79,6 +86,9 @@ class Cuboid2d(GraphNodes):
|
|
|
79
86
|
labeler_login: Optional[int] = None,
|
|
80
87
|
updated_at: Optional[str] = None,
|
|
81
88
|
created_at: Optional[str] = None,
|
|
89
|
+
position: Optional[Dict] = None,
|
|
90
|
+
rotation: Optional[Dict] = None,
|
|
91
|
+
dimensions: Optional[Dict] = None,
|
|
82
92
|
):
|
|
83
93
|
super().__init__(
|
|
84
94
|
nodes=nodes,
|
|
@@ -88,6 +98,9 @@ class Cuboid2d(GraphNodes):
|
|
|
88
98
|
updated_at=updated_at,
|
|
89
99
|
created_at=created_at,
|
|
90
100
|
)
|
|
101
|
+
self._position = position
|
|
102
|
+
self._rotation = rotation
|
|
103
|
+
self._dimensions = dimensions
|
|
91
104
|
|
|
92
105
|
if len(self._nodes) != 8:
|
|
93
106
|
raise ValueError("Cuboid2d must have exactly 8 vertices")
|
|
@@ -98,10 +111,169 @@ class Cuboid2d(GraphNodes):
|
|
|
98
111
|
Copy of Cuboid2d vertices.
|
|
99
112
|
|
|
100
113
|
:return: Cuboid2d vertices
|
|
101
|
-
:rtype:
|
|
114
|
+
:rtype: Optional[Dict]
|
|
102
115
|
"""
|
|
103
116
|
return self.nodes
|
|
104
117
|
|
|
118
|
+
@property
|
|
119
|
+
def position(self) -> Optional[Dict]:
|
|
120
|
+
"""
|
|
121
|
+
Copy of the position of the Cuboid2d.
|
|
122
|
+
|
|
123
|
+
:return: Position of the Cuboid2d
|
|
124
|
+
:rtype: Optional[Dict]
|
|
125
|
+
"""
|
|
126
|
+
if isinstance(self._position, dict):
|
|
127
|
+
return self._position.copy()
|
|
128
|
+
|
|
129
|
+
@property
|
|
130
|
+
def rotation(self) -> Optional[Dict]:
|
|
131
|
+
"""
|
|
132
|
+
Copy of the rotation of the Cuboid2d.
|
|
133
|
+
|
|
134
|
+
:return: Rotation of the Cuboid2d
|
|
135
|
+
:rtype: Optional[Dict]
|
|
136
|
+
"""
|
|
137
|
+
if isinstance(self._rotation, dict):
|
|
138
|
+
return self._rotation.copy()
|
|
139
|
+
|
|
140
|
+
@property
|
|
141
|
+
def dimensions(self) -> Optional[Dict]:
|
|
142
|
+
"""
|
|
143
|
+
Copy of the dimensions of the Cuboid2d.
|
|
144
|
+
|
|
145
|
+
:return: Dimensions of the Cuboid2d
|
|
146
|
+
:rtype: :class:`dict`
|
|
147
|
+
"""
|
|
148
|
+
if isinstance(self._dimensions, dict):
|
|
149
|
+
return self._dimensions.copy()
|
|
150
|
+
|
|
151
|
+
@classmethod
|
|
152
|
+
def from_json(cls, data: Dict[str, Dict]) -> Cuboid2d:
|
|
153
|
+
"""
|
|
154
|
+
Convert a json dict to Cuboid2d. Read more about `Supervisely format <https://docs.supervise.ly/data-organization/00_ann_format_navi>`_.
|
|
155
|
+
|
|
156
|
+
:param data: Cuboid2d in json format as a dict.
|
|
157
|
+
:type data: Dict[str, Dict]
|
|
158
|
+
:return: Cuboid2d object
|
|
159
|
+
:rtype: :class:`Cuboid2d<Cuboid2d>`
|
|
160
|
+
:Usage example:
|
|
161
|
+
|
|
162
|
+
.. code-block:: python
|
|
163
|
+
|
|
164
|
+
figure_json = {
|
|
165
|
+
"vertices": {
|
|
166
|
+
"0": {
|
|
167
|
+
"loc": [5, 5]
|
|
168
|
+
},
|
|
169
|
+
"1": {
|
|
170
|
+
"loc": [100, 100]
|
|
171
|
+
},
|
|
172
|
+
"2": {
|
|
173
|
+
"loc": [250, 200]
|
|
174
|
+
},
|
|
175
|
+
"position": {
|
|
176
|
+
"x": 0.0657651107620552,
|
|
177
|
+
"y": -0.05634319555373257,
|
|
178
|
+
"z": 0.7267282757573887
|
|
179
|
+
},
|
|
180
|
+
"rotation": { "x": 0, "y": 0, "z": 0 },
|
|
181
|
+
"dimensions": {
|
|
182
|
+
"x": 0.1425456564648202,
|
|
183
|
+
"y": 0.1,
|
|
184
|
+
"z": 0.36738880874660756
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
from supervisely.geometry.graph import Cuboid2d
|
|
189
|
+
figure = Cuboid2d.from_json(figure_json)
|
|
190
|
+
"""
|
|
191
|
+
nodes = {
|
|
192
|
+
node_id: Node.from_json(node_json)
|
|
193
|
+
for node_id, node_json in data[cls.items_json_field].items()
|
|
194
|
+
}
|
|
195
|
+
labeler_login = data.get(LABELER_LOGIN, None)
|
|
196
|
+
updated_at = data.get(UPDATED_AT, None)
|
|
197
|
+
created_at = data.get(CREATED_AT, None)
|
|
198
|
+
sly_id = data.get(ID, None)
|
|
199
|
+
class_id = data.get(CLASS_ID, None)
|
|
200
|
+
position = data.get("position", None)
|
|
201
|
+
rotation = data.get("rotation", None)
|
|
202
|
+
dimensions = data.get("dimensions", None)
|
|
203
|
+
return cls(
|
|
204
|
+
nodes=nodes,
|
|
205
|
+
sly_id=sly_id,
|
|
206
|
+
class_id=class_id,
|
|
207
|
+
labeler_login=labeler_login,
|
|
208
|
+
updated_at=updated_at,
|
|
209
|
+
created_at=created_at,
|
|
210
|
+
position=position,
|
|
211
|
+
rotation=rotation,
|
|
212
|
+
dimensions=dimensions,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
def to_json(self) -> Dict[str, Dict]:
|
|
216
|
+
"""
|
|
217
|
+
Convert the Cuboid2d to list. Read more about `Supervisely format <https://docs.supervise.ly/data-organization/00_ann_format_navi>`_.
|
|
218
|
+
|
|
219
|
+
:return: Json format as a dict
|
|
220
|
+
:rtype: Dict[str, Dict]
|
|
221
|
+
:Usage example:
|
|
222
|
+
|
|
223
|
+
.. code-block:: python
|
|
224
|
+
|
|
225
|
+
import supervisely as sly
|
|
226
|
+
from supervisely.geometry.graph import Node, Cuboid2d
|
|
227
|
+
|
|
228
|
+
vertex_1 = Node(sly.PointLocation(5, 5))
|
|
229
|
+
vertex_2 = Node(sly.PointLocation(100, 100))
|
|
230
|
+
vertex_3 = Node(sly.PointLocation(200, 250))
|
|
231
|
+
nodes = {0: vertex_1, 1: vertex_2, 2: vertex_3}
|
|
232
|
+
figure = Cuboid2d(nodes)
|
|
233
|
+
|
|
234
|
+
figure_json = figure.to_json()
|
|
235
|
+
print(figure_json)
|
|
236
|
+
# Output: {
|
|
237
|
+
# "nodes": {
|
|
238
|
+
# "0": {
|
|
239
|
+
# "loc": [5, 5]
|
|
240
|
+
# },
|
|
241
|
+
# "1": {
|
|
242
|
+
# "loc": [100, 100]
|
|
243
|
+
# },
|
|
244
|
+
# "2": {
|
|
245
|
+
# "loc": [250, 200]
|
|
246
|
+
# }
|
|
247
|
+
# },
|
|
248
|
+
# "position": {
|
|
249
|
+
# "x": 0.0657651107620552,
|
|
250
|
+
# "y": -0.05634319555373257,
|
|
251
|
+
# "z": 0.7267282757573887
|
|
252
|
+
# },
|
|
253
|
+
# "rotation": { "x": 0, "y": 0, "z": 0 },
|
|
254
|
+
# "dimensions": {
|
|
255
|
+
# "x": 0.1425456564648202,
|
|
256
|
+
# "y": 0.1,
|
|
257
|
+
# "z": 0.36738880874660756
|
|
258
|
+
# }
|
|
259
|
+
|
|
260
|
+
# }
|
|
261
|
+
"""
|
|
262
|
+
res = {
|
|
263
|
+
self.items_json_field: {
|
|
264
|
+
node_id: node.to_json() for node_id, node in self._nodes.items()
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if self._position is not None:
|
|
268
|
+
res["position"] = self._position
|
|
269
|
+
if self._rotation is not None:
|
|
270
|
+
res["rotation"] = self._rotation
|
|
271
|
+
if self._dimensions is not None:
|
|
272
|
+
res["dimensions"] = self._dimensions
|
|
273
|
+
|
|
274
|
+
self._add_creation_info(res)
|
|
275
|
+
return res
|
|
276
|
+
|
|
105
277
|
def validate(self, name: str, settings: Dict) -> None:
|
|
106
278
|
"""
|
|
107
279
|
Checks the graph for correctness and compliance with the template
|
|
@@ -184,7 +356,7 @@ class Cuboid2dTemplate(Cuboid2d, Geometry):
|
|
|
184
356
|
"""
|
|
185
357
|
config = {VERTICES: {}, EDGES: []}
|
|
186
358
|
|
|
187
|
-
x = y = w = h = s = 1
|
|
359
|
+
x = y = w = h = s = 1 # sample values only for config creation
|
|
188
360
|
base_vertices = [(x, y), (x + w, y), (x + w, y + h), (x, y + h)]
|
|
189
361
|
shifted_vertices = [(vx + s, vy + s) for vx, vy in base_vertices]
|
|
190
362
|
verices_coords = base_vertices + shifted_vertices
|
|
@@ -561,18 +561,18 @@ supervisely/collection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
|
561
561
|
supervisely/collection/key_indexed_collection.py,sha256=x2UVlkprspWhhae9oLUzjTWBoIouiWY9UQSS_MozfH0,37643
|
|
562
562
|
supervisely/collection/str_enum.py,sha256=Zp29yFGvnxC6oJRYNNlXhO2lTSdsriU1wiGHj6ahEJE,1250
|
|
563
563
|
supervisely/convert/__init__.py,sha256=pF1bOrg8SzkdFn90AWGRmVa9OQrHABY0gTlgurJ86Tw,962
|
|
564
|
-
supervisely/convert/base_converter.py,sha256=
|
|
564
|
+
supervisely/convert/base_converter.py,sha256=m4wh1BZIW_wbzZk4eS3PN50TMIsb2ZPud2RjVcPfQxY,18627
|
|
565
565
|
supervisely/convert/converter.py,sha256=tWxTDfFv7hwzQhUQrBxzfr6WP8FUGFX_ewg5T2HbUYo,8959
|
|
566
566
|
supervisely/convert/image/__init__.py,sha256=JEuyaBiiyiYmEUYqdn8Mog5FVXpz0H1zFubKkOOm73I,1395
|
|
567
|
-
supervisely/convert/image/image_converter.py,sha256=
|
|
567
|
+
supervisely/convert/image/image_converter.py,sha256=8vak8ZoKTN1ye2ZmCTvCZ605-Rw1AFLIEo7bJMfnR68,10426
|
|
568
568
|
supervisely/convert/image/image_helper.py,sha256=fdV0edQD6hVGQ8TXn2JGDzsnrAXPDMacHBQsApzOME8,3677
|
|
569
569
|
supervisely/convert/image/cityscapes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
570
|
-
supervisely/convert/image/cityscapes/cityscapes_converter.py,sha256=
|
|
570
|
+
supervisely/convert/image/cityscapes/cityscapes_converter.py,sha256=tnelQJHvGz_IGMXWe-EKWAkBhexRzmkv_0Kln5sN12E,8100
|
|
571
571
|
supervisely/convert/image/cityscapes/cityscapes_helper.py,sha256=in5nR7__q_u5dCkVtZmynfZ_ZuvsIAHrTzyTG4EvNgU,2988
|
|
572
572
|
supervisely/convert/image/coco/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
573
|
-
supervisely/convert/image/coco/coco_anntotation_converter.py,sha256=
|
|
574
|
-
supervisely/convert/image/coco/coco_converter.py,sha256=
|
|
575
|
-
supervisely/convert/image/coco/coco_helper.py,sha256=
|
|
573
|
+
supervisely/convert/image/coco/coco_anntotation_converter.py,sha256=O1PQbwrbnpQBks2pcz2nbAnhSqpKqNk13B2ARk_roFM,7078
|
|
574
|
+
supervisely/convert/image/coco/coco_converter.py,sha256=7dW7vE6yTRz7O31vTVSnEA4MDCc_UXTqc2UFEqaKorI,5650
|
|
575
|
+
supervisely/convert/image/coco/coco_helper.py,sha256=ykZe_M_yfDqJT9FoQXQ3zuLbQMO0l1WP75QMbvKEx5Y,32866
|
|
576
576
|
supervisely/convert/image/csv/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
577
577
|
supervisely/convert/image/csv/csv_converter.py,sha256=iLyc2PAVtlsAq7blnGH4iS1_D7Ai6-4UsdI_RlDVB9Q,11677
|
|
578
578
|
supervisely/convert/image/csv/csv_helper.py,sha256=-nR192IfMU0vTlNRoKXu5FS6tTs9fENqySyeKKyemRs,8409
|
|
@@ -592,7 +592,7 @@ supervisely/convert/image/medical2d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQ
|
|
|
592
592
|
supervisely/convert/image/medical2d/medical2d_converter.py,sha256=cYEaRfr8YFxEG_Pv-_SVMxrqZudi3kWbGQ3aArL2mds,8156
|
|
593
593
|
supervisely/convert/image/medical2d/medical2d_helper.py,sha256=pfLRCSFbFa5EIhmbB7kdmdWRu01OwIEDPXeNHzAeagg,12329
|
|
594
594
|
supervisely/convert/image/multi_view/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
595
|
-
supervisely/convert/image/multi_view/multi_view.py,sha256=
|
|
595
|
+
supervisely/convert/image/multi_view/multi_view.py,sha256=V-6oFN6oDre7UhejfyDkGKAg4rbM3C9JCQ8pHhuUBb8,4436
|
|
596
596
|
supervisely/convert/image/multispectral/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
597
597
|
supervisely/convert/image/multispectral/multispectral_converter.py,sha256=T3etYVNI0AUUrQsQhxw_r85NthXrqhqmdZQfz8kUY0g,5194
|
|
598
598
|
supervisely/convert/image/pascal_voc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -606,7 +606,7 @@ supervisely/convert/image/sly/fast_sly_image_converter.py,sha256=pZmQzhx9FrHwgVn
|
|
|
606
606
|
supervisely/convert/image/sly/sly_image_converter.py,sha256=097ijLa_62ZBu0elRx0xX_wpi9tmwgNZonVvBccfclg,12842
|
|
607
607
|
supervisely/convert/image/sly/sly_image_helper.py,sha256=5Ri8fKb5dzh5b3v8AJ5u8xVFOQfAtoWqZ7HktPsCjTI,7373
|
|
608
608
|
supervisely/convert/image/yolo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
609
|
-
supervisely/convert/image/yolo/yolo_converter.py,sha256=
|
|
609
|
+
supervisely/convert/image/yolo/yolo_converter.py,sha256=Wn5dR05y4SEPONcaxWr9ofnbvbf-SbRZN0fkksk5Dps,11391
|
|
610
610
|
supervisely/convert/image/yolo/yolo_helper.py,sha256=IwyBMZE_3eblsHhw8egeZUR9h_NciwjrxvVLNuZbxY4,19194
|
|
611
611
|
supervisely/convert/pointcloud/__init__.py,sha256=WPeIpPoTWDIKAa0lF6t2SMUhFNZ0l-vKujf6yD6w7SA,589
|
|
612
612
|
supervisely/convert/pointcloud/pointcloud_converter.py,sha256=yCCpzm7GrvL6WT4lNesvtYWWwdO3DO32JIOBBSSQgSA,7130
|
|
@@ -637,8 +637,8 @@ supervisely/convert/pointcloud_episodes/bag/bag_converter.py,sha256=jzWKXoFUWu11
|
|
|
637
637
|
supervisely/convert/pointcloud_episodes/lyft/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
638
638
|
supervisely/convert/pointcloud_episodes/lyft/lyft_converter.py,sha256=QXreWUJ-QhoWgLPqRxCayatYCCCuSV6Z2XCZKScrD3o,10419
|
|
639
639
|
supervisely/convert/pointcloud_episodes/nuscenes_conv/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
640
|
-
supervisely/convert/pointcloud_episodes/nuscenes_conv/nuscenes_converter.py,sha256=
|
|
641
|
-
supervisely/convert/pointcloud_episodes/nuscenes_conv/nuscenes_helper.py,sha256=
|
|
640
|
+
supervisely/convert/pointcloud_episodes/nuscenes_conv/nuscenes_converter.py,sha256=4HWouf-H4e5M_Hwd481DpLq17mIZMGkhRVOBgY4alXM,12692
|
|
641
|
+
supervisely/convert/pointcloud_episodes/nuscenes_conv/nuscenes_helper.py,sha256=cJTwhFn1JgblbPjrTrZu30y6FxyjGF-12sMFfvN1xzM,8969
|
|
642
642
|
supervisely/convert/pointcloud_episodes/sly/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
643
643
|
supervisely/convert/pointcloud_episodes/sly/sly_pointcloud_episodes_converter.py,sha256=fSEGxuTtFTAOLNBAZncOxw9PVALBOtB7yZ8qTCaET7w,6102
|
|
644
644
|
supervisely/convert/pointcloud_episodes/sly/sly_pointcloud_episodes_helper.py,sha256=h4WvNH6cEHtjxxhCnU7Hs2vkyJMye0qwabqXNYVTywE,3570
|
|
@@ -674,7 +674,7 @@ supervisely/geometry/closed_surface_mesh.py,sha256=3ZplCm3Q2bhPcxNmtv2U1UfdezRkC
|
|
|
674
674
|
supervisely/geometry/constants.py,sha256=TPYWGcr2GsbgEtKiZj1L_6wpmbaWU9Qjtlwjg136iVg,788
|
|
675
675
|
supervisely/geometry/conversions.py,sha256=ZY6xWYFWaDA5KDJkcIBBP8LAmMfZwxMeVFfYUYEM6fw,1170
|
|
676
676
|
supervisely/geometry/cuboid.py,sha256=oxsRoTKuwTNxH4Vp6khyvw1TCrBagSWNV5HmQKJZHt0,20693
|
|
677
|
-
supervisely/geometry/cuboid_2d.py,sha256
|
|
677
|
+
supervisely/geometry/cuboid_2d.py,sha256=-oXeKiUS2gguQ4GyIZYp1cNPPhOLsGOFZl7uI71BfZM,13438
|
|
678
678
|
supervisely/geometry/cuboid_3d.py,sha256=x472ZPHTZDIY5Dj8tKbLQG3BCukFPgSvPJlxfHdKi1w,4168
|
|
679
679
|
supervisely/geometry/geometry.py,sha256=dbXnct8hrr7Wour6yCrtAef22KSJ2uYRm1F5GE10_MM,15287
|
|
680
680
|
supervisely/geometry/graph.py,sha256=1_tX7FGmYkXuAx3P_w4zA4p8mRYnCN4iZ--2pMyxseI,24121
|
|
@@ -1070,9 +1070,9 @@ supervisely/worker_proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
|
|
|
1070
1070
|
supervisely/worker_proto/worker_api_pb2.py,sha256=VQfi5JRBHs2pFCK1snec3JECgGnua3Xjqw_-b3aFxuM,59142
|
|
1071
1071
|
supervisely/worker_proto/worker_api_pb2_grpc.py,sha256=3BwQXOaP9qpdi0Dt9EKG--Lm8KGN0C5AgmUfRv77_Jk,28940
|
|
1072
1072
|
supervisely_lib/__init__.py,sha256=7-3QnN8Zf0wj8NCr2oJmqoQWMKKPKTECvjH9pd2S5vY,159
|
|
1073
|
-
supervisely-6.73.
|
|
1074
|
-
supervisely-6.73.
|
|
1075
|
-
supervisely-6.73.
|
|
1076
|
-
supervisely-6.73.
|
|
1077
|
-
supervisely-6.73.
|
|
1078
|
-
supervisely-6.73.
|
|
1073
|
+
supervisely-6.73.283.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
1074
|
+
supervisely-6.73.283.dist-info/METADATA,sha256=gGM5GzwuguFaiu6gAtr9fqRwh9yRE4P49Y65qkNoHEA,33573
|
|
1075
|
+
supervisely-6.73.283.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
1076
|
+
supervisely-6.73.283.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
|
|
1077
|
+
supervisely-6.73.283.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
|
|
1078
|
+
supervisely-6.73.283.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|