supervisely 6.73.387__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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: supervisely
3
- Version: 6.73.387
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
@@ -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.387.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1107
- supervisely-6.73.387.dist-info/METADATA,sha256=6bZcP704iqdDpgH802O7uWemj3baQXCsDcmb5-hsDIE,35154
1108
- supervisely-6.73.387.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
1109
- supervisely-6.73.387.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1110
- supervisely-6.73.387.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1111
- supervisely-6.73.387.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,,