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.

@@ -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
- item.set_shape()
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
- item.name = f"{get_file_name(item.path)}{get_file_ext(item.path).lower()}"
145
- if self.upload_as_links and not self.supports_links:
146
- ann = None
147
- else:
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=False,
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, images, progress_cb=progress_cb
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
- item.set_shape()
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
- try:
72
- input_path = [d for d in fs.dirs_filter(self._input_data, filter_fn)].pop()
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
- sweeps_dir = input_path + "/sweeps/"
81
- if any([not fs.dir_exists(f"{sweeps_dir}/{d}") for d in helpers.DIR_NAMES]):
82
- return False
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.info(f"NuScenes initialization took {t.get_sec():.3f} sec")
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(total_sample_cnt, "Converting episode scenes...")
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
- GraphNodes geometry for a single :class:`Label<supervisely.annotation.label.Label>`. :class:`GraphNodes<GraphNodes>` class object is immutable.
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: GraphNodes ID in Supervisely server.
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 GraphNodes belongs.
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 GraphNodes.
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 GraphNodes was modified last. Date Format: Year:Month:Day:Hour:Minute:Seconds. Example: '2021-01-22T19:37:50.158Z'.
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 GraphNodes was created. Date Format is the same as in "updated_at" parameter.
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, GraphNodes
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 = GraphNodes(nodes)
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: :class:`dict`
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 # sample values only for config creation
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: supervisely
3
- Version: 6.73.281
3
+ Version: 6.73.283
4
4
  Summary: Supervisely Python SDK.
5
5
  Home-page: https://github.com/supervisely/supervisely
6
6
  Author: Supervisely
@@ -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=NHbOYxfZ8Yfs6qJz8zuR5kzKSlkfQs9-fpuafwdAGnA,18583
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=r-qdhuwOsk727mXIM26ucQhkoIKigu1M0BF-tw9IfGg,10321
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=msmsR2W-Xiod06dwn-MzmkbrEmQQqlKh7zyfTrW6YQw,7854
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=79rhAy_nkudxEgJDLW0BziUz808-fSqTOnlUeN-kvn8,6603
574
- supervisely/convert/image/coco/coco_converter.py,sha256=7czTd4I1we_HxEc9diQiXPC2pXAtnoqSnFSVCtNOmP4,5431
575
- supervisely/convert/image/coco/coco_helper.py,sha256=dUk5vCsIxeZDbpjs8_oviPGQDW7CosjqbnjwaJQd0mU,32849
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=TF53gXEpfudMb2MPbzunNqrR44tMTCOBBMBqGGwqQAQ,3794
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=cg5___X5MzvR-rZbNLmaKtr0MdRnyqtEzbBq5UBnYZ0,11171
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=hveKmKVe-jOvME1mMbDwynTlL5kKqd53T9BDmFitbkM,12808
641
- supervisely/convert/pointcloud_episodes/nuscenes_conv/nuscenes_helper.py,sha256=RrTlskRrqxwzrjFfT4e5aI9YeAxnun7Io9fjoicZmnY,8959
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=tJoaqIAAl1ED-EMu1tEeuMvNi5CIE1rGE0RMLnpkpcg,7933
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.281.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1074
- supervisely-6.73.281.dist-info/METADATA,sha256=24JmJE-D0v4zGZJO-XnHJ3yiFXVK69F_UwSGz0rItEQ,33573
1075
- supervisely-6.73.281.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
1076
- supervisely-6.73.281.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1077
- supervisely-6.73.281.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1078
- supervisely-6.73.281.dist-info/RECORD,,
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,,