supervisely 6.73.386__py3-none-any.whl → 6.73.388__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.
@@ -160,7 +160,6 @@ class PascalVOCConverter(ImageConverter):
160
160
  self._items.append(item)
161
161
  return detected_ann_cnt
162
162
 
163
-
164
163
  def _scan_for_item_segm_paths(self, item: Item, item_name_noext: str) -> Item:
165
164
  if self._segm_dir is not None:
166
165
  segm_path = os.path.join(self._segm_dir, f"{item_name_noext}.png")
@@ -170,11 +169,11 @@ class PascalVOCConverter(ImageConverter):
170
169
  inst_path = os.path.join(self._inst_dir, f"{item_name_noext}.png")
171
170
  if file_exists(inst_path):
172
171
  item.inst_path = inst_path
173
-
172
+
174
173
  return item
175
174
 
176
175
  def _scan_for_item_ann_path_and_update_meta(
177
- self, item: Item, ann_path: Optional[str], existing_cls_names: Set[str]
176
+ self, item: Item, ann_path: Optional[str], existing_cls_names: Set[str]
178
177
  ) -> Item:
179
178
  if ann_path is None:
180
179
  return item
@@ -186,7 +185,6 @@ class PascalVOCConverter(ImageConverter):
186
185
  item.ann_data = ann_path
187
186
  return item
188
187
 
189
-
190
188
  def to_supervisely(
191
189
  self,
192
190
  item: Item,
@@ -200,7 +198,12 @@ class PascalVOCConverter(ImageConverter):
200
198
  try:
201
199
  item.set_shape()
202
200
  return pascal_voc_helper.get_ann(
203
- item, self.color2class_name, meta, self._bbox_classes_map, renamed_classes
201
+ item,
202
+ self.color2class_name,
203
+ meta,
204
+ self._bbox_classes_map,
205
+ renamed_classes,
206
+ renamed_tags,
204
207
  )
205
208
  except Exception as e:
206
209
  logger.warn(f"Failed to convert annotation: {repr(e)}")
@@ -12,6 +12,8 @@ from supervisely.annotation.annotation import Annotation
12
12
  from supervisely.annotation.label import Label
13
13
  from supervisely.annotation.obj_class import ObjClass
14
14
  from supervisely.annotation.obj_class_collection import ObjClassCollection
15
+ from supervisely.annotation.tag import Tag, TagValueType
16
+ from supervisely.annotation.tag_meta import TagMeta
15
17
  from supervisely.convert.image.image_helper import validate_image_bounds
16
18
  from supervisely.geometry.bitmap import Bitmap
17
19
  from supervisely.geometry.polygon import Polygon
@@ -33,6 +35,7 @@ VALID_IMG_EXT = {".jpe", ".jpeg", ".jpg"}
33
35
  TRAIN_TAG_NAME = "train"
34
36
  VAL_TAG_NAME = "val"
35
37
  TRAINVAL_TAG_NAME = "trainval"
38
+ DEFAULT_OBJECT_FIELDS = {"name", "class", "bndbox"}
36
39
 
37
40
  default_classes_colors = {
38
41
  "neutral": (224, 224, 192),
@@ -118,6 +121,7 @@ def get_ann(
118
121
  meta: ProjectMeta,
119
122
  bbox_classes_map: dict,
120
123
  renamed_classes=None,
124
+ renamed_tags=None,
121
125
  ) -> Annotation:
122
126
  segm_path, inst_path = item.segm_path, item.inst_path
123
127
  height, width = item.shape
@@ -126,7 +130,7 @@ def get_ann(
126
130
 
127
131
  if item.ann_data is not None:
128
132
  bbox_labels = xml_to_sly_labels(
129
- item.ann_data, meta, bbox_classes_map, img_rect, renamed_classes
133
+ item.ann_data, meta, bbox_classes_map, img_rect, renamed_classes, renamed_tags
130
134
  )
131
135
  ann = ann.add_labels(bbox_labels)
132
136
 
@@ -188,6 +192,7 @@ def xml_to_sly_labels(
188
192
  bbox_classes_map: dict,
189
193
  img_rect: Rectangle,
190
194
  renamed_classes=None,
195
+ renamed_tags=None,
191
196
  ) -> List[Label]:
192
197
  import xml.etree.ElementTree as ET
193
198
 
@@ -196,20 +201,40 @@ def xml_to_sly_labels(
196
201
  tree = ET.parse(in_file)
197
202
  root = tree.getroot()
198
203
 
199
- for obj in root.iter("object"):
200
- cls_name = obj.find("name").text
201
- cls_name = bbox_classes_map.get(cls_name, cls_name)
202
- if renamed_classes and cls_name in renamed_classes:
203
- cls_name = renamed_classes[cls_name]
204
- obj_cls = meta.obj_classes.get(cls_name)
205
- if obj_cls is None:
206
- logger.warn(f"Class {cls_name} is not found in meta. Skipping.")
207
- continue
208
- xmlbox = obj.find("bndbox")
209
- bbox_coords = [float(xmlbox.find(x).text) for x in ("ymin", "xmin", "ymax", "xmax")]
210
- bbox = Rectangle(*bbox_coords)
211
- label = Label(bbox, obj_cls)
212
- labels.append(label)
204
+ for obj in root.iter("object"):
205
+ geometry = None
206
+ obj_cls = None
207
+ tags = []
208
+
209
+ for element in obj:
210
+ field_name, value = element.tag, element.text
211
+ if field_name in ["name", "class"]:
212
+ cls_name = bbox_classes_map.get(value, value)
213
+ if renamed_classes and cls_name in renamed_classes:
214
+ cls_name = renamed_classes[cls_name]
215
+ obj_cls = meta.obj_classes.get(cls_name)
216
+ if obj_cls is None:
217
+ logger.warn(f"Class {cls_name} is not found in meta. Skipping.")
218
+ continue
219
+ elif field_name == "bndbox":
220
+ bbox_coords = [
221
+ float(element.find(x).text) for x in ("ymin", "xmin", "ymax", "xmax")
222
+ ]
223
+ geometry = Rectangle(*bbox_coords)
224
+ elif field_name not in DEFAULT_OBJECT_FIELDS:
225
+ tag_name = field_name
226
+ if renamed_tags and tag_name in renamed_tags:
227
+ tag_name = renamed_tags[tag_name]
228
+ tag_meta = meta.get_tag_meta(tag_name)
229
+ if tag_meta is None:
230
+ logger.warn(f"Tag meta for '{field_name}' is not found in meta. Skipping.")
231
+ continue
232
+ if not isinstance(value, str):
233
+ value = str(value)
234
+ tags.append(Tag(tag_meta, value))
235
+ if geometry is None or obj_cls is None:
236
+ continue
237
+ labels.append(Label(geometry, obj_cls, tags))
213
238
  labels = validate_image_bounds(labels, img_rect)
214
239
 
215
240
  return labels
@@ -227,32 +252,40 @@ def update_meta_from_xml(
227
252
  tree = ET.parse(in_file)
228
253
  root = tree.getroot()
229
254
 
230
- for obj in root.iter("object"):
231
- class_name = obj.find("name").text
232
- original_class_name = class_name
233
- obj_cls = meta.obj_classes.get(class_name)
234
- if obj_cls is None:
235
- obj_cls = ObjClass(name=class_name, geometry_type=Rectangle)
236
- meta = meta.add_obj_class(obj_cls)
237
- existing_cls_names.add(class_name)
238
- continue
239
- elif obj_cls.geometry_type == Rectangle:
240
- continue
241
- class_name = class_name + "_bbox"
242
- obj_cls = meta.obj_classes.get(class_name)
243
- if obj_cls is None:
244
- obj_cls = ObjClass(name=class_name, geometry_type=Rectangle)
245
- meta = meta.add_obj_class(obj_cls)
246
- existing_cls_names.add(class_name)
247
- elif obj_cls.geometry_type == Rectangle:
248
- pass
249
- else:
250
- class_name = generate_free_name(
251
- existing_cls_names, class_name, extend_used_names=True
252
- )
253
- obj_cls = ObjClass(name=class_name, geometry_type=Rectangle)
254
- meta = meta.add_obj_class(obj_cls)
255
- bbox_classes_map[original_class_name] = class_name
255
+ for obj in root.iter("object"):
256
+ for element in obj:
257
+ field_name = element.tag
258
+ if field_name in ["name", "class"]:
259
+ class_name = element.text
260
+ original_class_name = class_name
261
+ obj_cls = meta.obj_classes.get(class_name)
262
+ if obj_cls is None:
263
+ obj_cls = ObjClass(name=class_name, geometry_type=Rectangle)
264
+ meta = meta.add_obj_class(obj_cls)
265
+ existing_cls_names.add(class_name)
266
+ continue
267
+ elif obj_cls.geometry_type == Rectangle:
268
+ continue
269
+ class_name = class_name + "_bbox"
270
+ obj_cls = meta.obj_classes.get(class_name)
271
+ if obj_cls is None:
272
+ obj_cls = ObjClass(name=class_name, geometry_type=Rectangle)
273
+ meta = meta.add_obj_class(obj_cls)
274
+ existing_cls_names.add(class_name)
275
+ elif obj_cls.geometry_type == Rectangle:
276
+ pass
277
+ else:
278
+ class_name = generate_free_name(
279
+ existing_cls_names, class_name, extend_used_names=True
280
+ )
281
+ obj_cls = ObjClass(name=class_name, geometry_type=Rectangle)
282
+ meta = meta.add_obj_class(obj_cls)
283
+ bbox_classes_map[original_class_name] = class_name
284
+ elif field_name not in DEFAULT_OBJECT_FIELDS:
285
+ tag_meta = meta.get_tag_meta(field_name)
286
+ if tag_meta is None:
287
+ tag_meta = TagMeta(field_name, TagValueType.ANY_STRING)
288
+ meta = meta.add_tag_meta(tag_meta)
256
289
 
257
290
  return meta
258
291
 
@@ -705,8 +705,16 @@ class ObjectDetectionVisualizer(BaseVisualizer):
705
705
  return False
706
706
 
707
707
  def _get_sample_data_for_gallery(self):
708
- # get sample images with annotations for visualization (Prediction project)
709
- pred_ds = random.choice(self.eval_result.pred_dataset_infos)
710
- self.eval_result.sample_images = self.api.image.get_list(pred_ds.id, limit=9)
711
- image_ids = [x.id for x in self.eval_result.sample_images]
712
- self.eval_result.sample_anns = self.api.annotation.download_batch(pred_ds.id, image_ids)
708
+ """Get sample images with annotations for visualization (preview gallery)"""
709
+ sample_images = []
710
+ limit = 9
711
+ for ds_info in self.eval_result.pred_dataset_infos:
712
+ images = self.api.image.get_list(
713
+ ds_info.id, limit=limit, force_metadata_for_links=False
714
+ )
715
+ sample_images.extend(images)
716
+ if len(sample_images) > limit:
717
+ sample_images = random.sample(sample_images, limit)
718
+ self.eval_result.sample_images = sample_images
719
+ ids = [img.id for img in sample_images]
720
+ self.eval_result.sample_anns = self.api.annotation.download_batch(ds_info.id, ids)
@@ -280,15 +280,19 @@ class SemanticSegmentationVisualizer(BaseVisualizer):
280
280
  raise RuntimeError(f"Match data was not created properly. {e}")
281
281
 
282
282
  def _get_sample_data_for_gallery(self):
283
- # get sample images with annotations for visualization
284
- pred_ds = random.choice(self.eval_result.pred_dataset_infos)
285
- imgs = self.api.image.get_list(pred_ds.id, limit=9, force_metadata_for_links=False)
286
- anns = self.api.annotation.download_batch(
287
- pred_ds.id, [x.id for x in imgs], force_metadata_for_links=False
288
- )
289
-
290
- self.eval_result.sample_images = imgs
291
- self.eval_result.sample_anns = anns
283
+ """Get sample images with annotations for visualization (preview gallery)"""
284
+ sample_images = []
285
+ limit = 9
286
+ for ds_info in self.eval_result.pred_dataset_infos:
287
+ images = self.api.image.get_list(
288
+ ds_info.id, limit=limit, force_metadata_for_links=False
289
+ )
290
+ sample_images.extend(images)
291
+ if len(sample_images) > limit:
292
+ sample_images = random.sample(sample_images, limit)
293
+ self.eval_result.sample_images = sample_images
294
+ ids = [img.id for img in sample_images]
295
+ self.eval_result.sample_anns = self.api.annotation.download_batch(ds_info.id, ids)
292
296
 
293
297
  def _create_clickable_label(self):
294
298
  return MarkdownWidget(name="clickable_label", title="", text=self.vis_texts.clickable_label)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: supervisely
3
- Version: 6.73.386
3
+ Version: 6.73.388
4
4
  Summary: Supervisely Python SDK.
5
5
  Home-page: https://github.com/supervisely/supervisely
6
6
  Author: Supervisely
@@ -610,8 +610,8 @@ supervisely/convert/image/multi_view/multi_view.py,sha256=V-6oFN6oDre7UhejfyDkGK
610
610
  supervisely/convert/image/multispectral/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
611
611
  supervisely/convert/image/multispectral/multispectral_converter.py,sha256=T3etYVNI0AUUrQsQhxw_r85NthXrqhqmdZQfz8kUY0g,5194
612
612
  supervisely/convert/image/pascal_voc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
613
- supervisely/convert/image/pascal_voc/pascal_voc_converter.py,sha256=h5Q3qW4riUCXPo5535wuKGurlLvPfKbWGML0RGnMxyg,7648
614
- supervisely/convert/image/pascal_voc/pascal_voc_helper.py,sha256=oM-HKUePUwB27aQjL-EvyeS7K-GX0X31rms2yOTTnGo,27872
613
+ supervisely/convert/image/pascal_voc/pascal_voc_converter.py,sha256=zpn_s_WT1Z72WztXlPEJIBfO7-DbHCnjsOZFGOoYMCA,7729
614
+ supervisely/convert/image/pascal_voc/pascal_voc_helper.py,sha256=vu6L2Gm1IU5aDPGibngVJvdje0ndS8NW-0WRhmr6vPE,29415
615
615
  supervisely/convert/image/pdf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
616
616
  supervisely/convert/image/pdf/pdf_converter.py,sha256=LKvVng9jPp0cSIjYEjKLOb48wtdOdB7LXS2gjmOdZhE,2442
617
617
  supervisely/convert/image/pdf/pdf_helper.py,sha256=IDwLEvsVy8lu-KC1lXvSRkZZ9BCC6ylebnNEtLQU5L4,1288
@@ -809,7 +809,7 @@ supervisely/nn/benchmark/object_detection/evaluation_params.yaml,sha256=fEYA-Exm
809
809
  supervisely/nn/benchmark/object_detection/evaluator.py,sha256=s-hPBm5BmoCgwoozVyDacum4kVLNtYK6I6NCt_L_LSA,7278
810
810
  supervisely/nn/benchmark/object_detection/metric_provider.py,sha256=_fxS24Q8KhE2n2HknMnt86xVPYEDFw5atxsvXRnCl4w,23855
811
811
  supervisely/nn/benchmark/object_detection/text_templates.py,sha256=4BgTIX1Co4WK9_VSUa1qWCmh5OJzo3_opVU6LOjKSjc,25842
812
- supervisely/nn/benchmark/object_detection/visualizer.py,sha256=0eJ-ATDVMyjMRInoEK604vL3vJPN5Ge1HjarS11CS0A,32365
812
+ supervisely/nn/benchmark/object_detection/visualizer.py,sha256=4BOkSYl8rlvOKO87ZlmZuZCsAM9QTqDqAgNMoiwE8eI,32622
813
813
  supervisely/nn/benchmark/object_detection/vis_metrics/__init__.py,sha256=AXCLHEySEdR-B-5sfDoWBmmOLBVlyW2U_xr8Ta42sQI,2096
814
814
  supervisely/nn/benchmark/object_detection/vis_metrics/confidence_distribution.py,sha256=J6l9Vc8TGsvkTyH5u7Ry4P2jgJC2GYmcgOeMALftZBw,4254
815
815
  supervisely/nn/benchmark/object_detection/vis_metrics/confidence_score.py,sha256=pmxnF_UJk0WhqEdL7O_yIjIBtxPipLQZVJwCr6XB3zc,4751
@@ -838,7 +838,7 @@ supervisely/nn/benchmark/semantic_segmentation/evaluation_params.yaml,sha256=47D
838
838
  supervisely/nn/benchmark/semantic_segmentation/evaluator.py,sha256=XafPMpGL6v0ZQ-m7DkEjoY7W6fGCJNKolql5BA3M8V0,7261
839
839
  supervisely/nn/benchmark/semantic_segmentation/metric_provider.py,sha256=478l7w2n-yueBMVABsakfIQEo3MksbCYmKNrwMFOl6w,6546
840
840
  supervisely/nn/benchmark/semantic_segmentation/text_templates.py,sha256=7yRRD2FAdJHGSRqBVIjNjzCduKzaepA1OWtggi7B0Dg,8580
841
- supervisely/nn/benchmark/semantic_segmentation/visualizer.py,sha256=T7WTjnyFLL3BAyH7yQIqI6R5VNj1M3guamwhDglOegE,13293
841
+ supervisely/nn/benchmark/semantic_segmentation/visualizer.py,sha256=ny7S9cYdYeRL5je5eGpJOneVSz7MxZdykImPdNQ8uPY,13500
842
842
  supervisely/nn/benchmark/semantic_segmentation/vis_metrics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
843
843
  supervisely/nn/benchmark/semantic_segmentation/vis_metrics/acknowledgement.py,sha256=Lm82x8AIMKv1WqmqA0W9fugSlQ_JrP9dwYYYReZmhvI,440
844
844
  supervisely/nn/benchmark/semantic_segmentation/vis_metrics/classwise_error_analysis.py,sha256=0bmL43a4cqw3grFoG68NN8Y1fkRpHBIRJptcxMor-78,1884
@@ -1103,9 +1103,9 @@ supervisely/worker_proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
1103
1103
  supervisely/worker_proto/worker_api_pb2.py,sha256=VQfi5JRBHs2pFCK1snec3JECgGnua3Xjqw_-b3aFxuM,59142
1104
1104
  supervisely/worker_proto/worker_api_pb2_grpc.py,sha256=3BwQXOaP9qpdi0Dt9EKG--Lm8KGN0C5AgmUfRv77_Jk,28940
1105
1105
  supervisely_lib/__init__.py,sha256=7-3QnN8Zf0wj8NCr2oJmqoQWMKKPKTECvjH9pd2S5vY,159
1106
- supervisely-6.73.386.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1107
- supervisely-6.73.386.dist-info/METADATA,sha256=pAcUu38hzyDhqOlzLArYsO0AzNHXluQ4MbM0UtAm1nk,35154
1108
- supervisely-6.73.386.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
1109
- supervisely-6.73.386.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1110
- supervisely-6.73.386.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1111
- supervisely-6.73.386.dist-info/RECORD,,
1106
+ supervisely-6.73.388.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1107
+ supervisely-6.73.388.dist-info/METADATA,sha256=Jj-5_iGTZP0t8mfQSkiS3ADiyJg1YKqY0ZnVpmkarZQ,35154
1108
+ supervisely-6.73.388.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
1109
+ supervisely-6.73.388.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1110
+ supervisely-6.73.388.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1111
+ supervisely-6.73.388.dist-info/RECORD,,