supervisely 6.73.301__py3-none-any.whl → 6.73.302__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/__init__.py +19 -3
- supervisely/convert/image/coco/coco_helper.py +177 -27
- supervisely/convert/image/pascal_voc/pascal_voc_helper.py +96 -12
- supervisely/convert/image/yolo/yolo_helper.py +84 -1
- {supervisely-6.73.301.dist-info → supervisely-6.73.302.dist-info}/METADATA +1 -1
- {supervisely-6.73.301.dist-info → supervisely-6.73.302.dist-info}/RECORD +10 -10
- {supervisely-6.73.301.dist-info → supervisely-6.73.302.dist-info}/LICENSE +0 -0
- {supervisely-6.73.301.dist-info → supervisely-6.73.302.dist-info}/WHEEL +0 -0
- {supervisely-6.73.301.dist-info → supervisely-6.73.302.dist-info}/entry_points.txt +0 -0
- {supervisely-6.73.301.dist-info → supervisely-6.73.302.dist-info}/top_level.txt +0 -0
supervisely/convert/__init__.py
CHANGED
|
@@ -3,14 +3,30 @@
|
|
|
3
3
|
# Project
|
|
4
4
|
from supervisely.convert.image.coco.coco_helper import sly_project_to_coco as project_to_coco
|
|
5
5
|
from supervisely.convert.image.yolo.yolo_helper import sly_project_to_yolo as project_to_yolo
|
|
6
|
-
from supervisely.convert.image.pascal_voc.pascal_voc_helper import
|
|
6
|
+
from supervisely.convert.image.pascal_voc.pascal_voc_helper import (
|
|
7
|
+
sly_project_to_pascal_voc as project_to_pascal_voc,
|
|
8
|
+
)
|
|
7
9
|
|
|
8
10
|
# Dataset
|
|
9
11
|
from supervisely.convert.image.coco.coco_helper import sly_ds_to_coco as dataset_to_coco
|
|
10
12
|
from supervisely.convert.image.yolo.yolo_helper import sly_ds_to_yolo as dataset_to_yolo
|
|
11
|
-
from supervisely.convert.image.pascal_voc.pascal_voc_helper import
|
|
13
|
+
from supervisely.convert.image.pascal_voc.pascal_voc_helper import (
|
|
14
|
+
sly_ds_to_pascal_voc as dataset_to_pascal_voc,
|
|
15
|
+
)
|
|
12
16
|
|
|
13
17
|
# Image Annotations
|
|
14
18
|
from supervisely.convert.image.coco.coco_helper import sly_ann_to_coco as annotation_to_coco
|
|
15
19
|
from supervisely.convert.image.yolo.yolo_helper import sly_ann_to_yolo as annotation_to_yolo
|
|
16
|
-
from supervisely.convert.image.pascal_voc.pascal_voc_helper import
|
|
20
|
+
from supervisely.convert.image.pascal_voc.pascal_voc_helper import (
|
|
21
|
+
sly_ann_to_pascal_voc as annotation_to_pascal_voc,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Supervisely Project/Dataset/Annotation to COCO
|
|
26
|
+
from supervisely.convert.image.coco.coco_helper import to_coco
|
|
27
|
+
|
|
28
|
+
# Supervisely Project/Dataset/Annotation to YOLO
|
|
29
|
+
from supervisely.convert.image.yolo.yolo_helper import to_yolo
|
|
30
|
+
|
|
31
|
+
# Supervisely Project/Dataset/Annotation to Pascal VOC
|
|
32
|
+
from supervisely.convert.image.pascal_voc.pascal_voc_helper import to_pascal_voc
|
|
@@ -4,6 +4,7 @@ import sys
|
|
|
4
4
|
import uuid
|
|
5
5
|
from copy import deepcopy
|
|
6
6
|
from datetime import datetime
|
|
7
|
+
from itertools import groupby
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, Union
|
|
9
10
|
|
|
@@ -351,7 +352,8 @@ def _get_graph_info(idx, obj_class):
|
|
|
351
352
|
return data
|
|
352
353
|
|
|
353
354
|
|
|
354
|
-
def get_categories_from_meta(meta: ProjectMeta):
|
|
355
|
+
def get_categories_from_meta(meta: ProjectMeta) -> List[Dict[str, Any]]:
|
|
356
|
+
"""Get categories from Supervisely project meta."""
|
|
355
357
|
cat = lambda idx, c: {"supercategory": c.name, "id": idx, "name": c.name}
|
|
356
358
|
return [
|
|
357
359
|
cat(idx, c) if c.geometry_type != GraphNodes else _get_graph_info(idx, c)
|
|
@@ -359,6 +361,34 @@ def get_categories_from_meta(meta: ProjectMeta):
|
|
|
359
361
|
]
|
|
360
362
|
|
|
361
363
|
|
|
364
|
+
def extend_mask_up_to_image(
|
|
365
|
+
binary_mask: np.ndarray, image_shape: Tuple[int, int], origin: PointLocation
|
|
366
|
+
) -> np.ndarray:
|
|
367
|
+
"""Extend binary mask up to image shape."""
|
|
368
|
+
y, x = origin.col, origin.row
|
|
369
|
+
new_mask = np.zeros(image_shape, dtype=binary_mask.dtype)
|
|
370
|
+
try:
|
|
371
|
+
new_mask[x : x + binary_mask.shape[0], y : y + binary_mask.shape[1]] = binary_mask
|
|
372
|
+
except ValueError as e:
|
|
373
|
+
raise ValueError(
|
|
374
|
+
f"Binary mask size {binary_mask.shape} with origin {origin} "
|
|
375
|
+
f"exceeds image boundaries {image_shape}"
|
|
376
|
+
) from e
|
|
377
|
+
return new_mask
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def coco_segmentation_rle(segmentation: np.ndarray) -> Dict[str, Any]:
|
|
381
|
+
"""Convert COCO segmentation to RLE format."""
|
|
382
|
+
binary_mask = np.asfortranarray(segmentation)
|
|
383
|
+
rle = {"counts": [], "size": list(binary_mask.shape)}
|
|
384
|
+
counts = rle.get("counts")
|
|
385
|
+
for i, (value, elements) in enumerate(groupby(binary_mask.ravel(order="F"))):
|
|
386
|
+
if i == 0 and value == 1:
|
|
387
|
+
counts.append(0)
|
|
388
|
+
counts.append(len(list(elements)))
|
|
389
|
+
return rle
|
|
390
|
+
|
|
391
|
+
|
|
362
392
|
def sly_ann_to_coco(
|
|
363
393
|
ann: Annotation,
|
|
364
394
|
coco_image_id: int,
|
|
@@ -491,17 +521,14 @@ def sly_ann_to_coco(
|
|
|
491
521
|
|
|
492
522
|
res_inst = [] # result list of COCO objects
|
|
493
523
|
|
|
524
|
+
h, w = ann.img_size
|
|
494
525
|
for binding_key, labels in ann.get_bindings().items():
|
|
495
526
|
if binding_key is None:
|
|
496
527
|
polygons = [l for l in labels if l.obj_class.geometry_type == Polygon]
|
|
497
528
|
masks = [l for l in labels if l.obj_class.geometry_type == Bitmap]
|
|
498
529
|
bboxes = [l for l in labels if l.obj_class.geometry_type == Rectangle]
|
|
499
530
|
graphs = [l for l in labels if l.obj_class.geometry_type == GraphNodes]
|
|
500
|
-
|
|
501
|
-
for l in masks:
|
|
502
|
-
polygon_cls = l.obj_class.clone(geometry_type=Polygon)
|
|
503
|
-
polygons.extend(l.convert(polygon_cls))
|
|
504
|
-
for label in polygons + bboxes:
|
|
531
|
+
for label in polygons + bboxes + masks:
|
|
505
532
|
cat_id = class_mapping[label.obj_class.name]
|
|
506
533
|
coco_obj = coco_obj_template(label_id, coco_image_id, cat_id)
|
|
507
534
|
coco_obj["bbox"] = _get_common_bbox([label])
|
|
@@ -510,6 +537,11 @@ def sly_ann_to_coco(
|
|
|
510
537
|
poly = label.geometry.to_json()["points"]["exterior"]
|
|
511
538
|
poly = np.array(poly).flatten().astype(float).tolist()
|
|
512
539
|
coco_obj["segmentation"] = [poly]
|
|
540
|
+
elif label.obj_class.geometry_type == Bitmap:
|
|
541
|
+
segmentation = extend_mask_up_to_image(
|
|
542
|
+
label.geometry.data, (h, w), label.geometry.origin
|
|
543
|
+
)
|
|
544
|
+
coco_obj["segmentation"] = coco_segmentation_rle(segmentation)
|
|
513
545
|
|
|
514
546
|
label_id = _update_inst_results(label_id, coco_ann, coco_obj, res_inst)
|
|
515
547
|
|
|
@@ -525,38 +557,60 @@ def sly_ann_to_coco(
|
|
|
525
557
|
masks = [l for l in labels if l.obj_class.geometry_type == Bitmap]
|
|
526
558
|
graphs = [l for l in labels if l.obj_class.geometry_type == GraphNodes]
|
|
527
559
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
polygons.extend(l.convert(polygon_cls))
|
|
560
|
+
need_to_process_separately = len(masks) > 0 and len(polygons) > 0
|
|
561
|
+
bbox_matched_w_mask = False
|
|
562
|
+
bbox_matched_w_poly = False
|
|
532
563
|
|
|
533
|
-
|
|
534
|
-
|
|
564
|
+
if len(graphs) > 0:
|
|
565
|
+
if len(masks) > 0 or len(polygons) > 0:
|
|
566
|
+
logger.warning(
|
|
567
|
+
"Keypoints and Polygons/Bitmaps in one binding key are not supported. "
|
|
568
|
+
"Objects will be converted separately."
|
|
569
|
+
)
|
|
570
|
+
if len(graphs) > 1:
|
|
571
|
+
logger.warning(
|
|
572
|
+
"Multiple Keypoints in one binding key are not supported. "
|
|
573
|
+
"Only the first graph will be converted."
|
|
574
|
+
)
|
|
575
|
+
cat_id = class_mapping[graphs[0].obj_class.name]
|
|
576
|
+
coco_obj = _create_keypoints_obj(graphs[0], cat_id, label_id, coco_image_id)
|
|
577
|
+
label_id = _update_inst_results(label_id, coco_ann, coco_obj, res_inst)
|
|
578
|
+
|
|
579
|
+
# convert Bitmap to Polygon
|
|
580
|
+
if len(masks) > 0:
|
|
581
|
+
for label in masks:
|
|
582
|
+
cat_id = class_mapping[label.obj_class.name]
|
|
583
|
+
coco_obj = coco_obj_template(label_id, coco_image_id, cat_id)
|
|
584
|
+
segmentation = extend_mask_up_to_image(
|
|
585
|
+
label.geometry.data, (h, w), label.geometry.origin
|
|
586
|
+
)
|
|
587
|
+
coco_obj["segmentation"] = coco_segmentation_rle(segmentation)
|
|
588
|
+
coco_obj["area"] = label.geometry.area
|
|
589
|
+
if len(bboxes) > 0 and not need_to_process_separately:
|
|
590
|
+
found = _get_common_bbox(bboxes, sly_bbox=True, approx=True)
|
|
591
|
+
new = _get_common_bbox([label], sly_bbox=True)
|
|
592
|
+
bbox_matched_w_mask = found.contains(new)
|
|
593
|
+
coco_obj["bbox"] = _get_common_bbox(bboxes if bbox_matched_w_mask else [label])
|
|
594
|
+
label_id = _update_inst_results(label_id, coco_ann, coco_obj, res_inst)
|
|
595
|
+
|
|
596
|
+
# process polygons
|
|
597
|
+
if len(polygons) > 0:
|
|
535
598
|
cat_id = class_mapping[polygons[0].obj_class.name]
|
|
536
599
|
coco_obj = coco_obj_template(label_id, coco_image_id, cat_id)
|
|
537
|
-
if len(bboxes) > 0:
|
|
600
|
+
if len(bboxes) > 0 and not need_to_process_separately:
|
|
538
601
|
found = _get_common_bbox(bboxes, sly_bbox=True, approx=True)
|
|
539
602
|
new = _get_common_bbox(polygons, sly_bbox=True)
|
|
540
|
-
|
|
603
|
+
bbox_matched_w_poly = found.contains(new)
|
|
541
604
|
|
|
542
605
|
polys = [l.geometry.to_json()["points"]["exterior"] for l in polygons]
|
|
543
606
|
polys = [np.array(p).flatten().astype(float).tolist() for p in polys]
|
|
544
607
|
coco_obj["segmentation"] = polys
|
|
545
608
|
coco_obj["area"] = sum([l.geometry.area for l in polygons])
|
|
546
|
-
coco_obj["bbox"] = _get_common_bbox(bboxes if
|
|
547
|
-
label_id = _update_inst_results(label_id, coco_ann, coco_obj, res_inst)
|
|
548
|
-
|
|
549
|
-
if len(graphs) > 0:
|
|
550
|
-
if len(graphs) > 1:
|
|
551
|
-
logger.warning(
|
|
552
|
-
"Multiple Keypoints in one binding key are not supported. "
|
|
553
|
-
"Only the first graph will be converted."
|
|
554
|
-
)
|
|
555
|
-
cat_id = class_mapping[graphs[0].obj_class.name]
|
|
556
|
-
coco_obj = _create_keypoints_obj(graphs[0], cat_id, label_id, coco_image_id)
|
|
609
|
+
coco_obj["bbox"] = _get_common_bbox(bboxes if bbox_matched_w_poly else polygons)
|
|
557
610
|
label_id = _update_inst_results(label_id, coco_ann, coco_obj, res_inst)
|
|
558
611
|
|
|
559
|
-
|
|
612
|
+
# process bboxes separately if they are not matched with masks/polygons
|
|
613
|
+
if len(bboxes) > 0 and not bbox_matched_w_poly and not bbox_matched_w_mask:
|
|
560
614
|
for label in bboxes:
|
|
561
615
|
cat_id = class_mapping[label.obj_class.name]
|
|
562
616
|
coco_obj = coco_obj_template(label_id, coco_image_id, cat_id)
|
|
@@ -713,7 +767,9 @@ def sly_ds_to_coco(
|
|
|
713
767
|
|
|
714
768
|
coco_ann["images"].append(image_coco(image_info, image_idx))
|
|
715
769
|
if with_captions is True:
|
|
716
|
-
|
|
770
|
+
# pylint: disable=unsubscriptable-object
|
|
771
|
+
coco_captions["images"].append(image_coco(image_info, image_idx))
|
|
772
|
+
# pylint: enable=unsubscriptable-object
|
|
717
773
|
|
|
718
774
|
ann = Annotation.load_json_file(ann_path, meta)
|
|
719
775
|
if ann.img_size is None or ann.img_size == (0, 0) or ann.img_size == (None, None):
|
|
@@ -815,3 +871,97 @@ def sly_project_to_coco(
|
|
|
815
871
|
)
|
|
816
872
|
logger.info(f"Dataset '{ds.short_name}' has been converted to COCO format.")
|
|
817
873
|
logger.info(f"Project '{project.name}' has been converted to COCO format.")
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
def to_coco(
|
|
877
|
+
input_data: Union[Project, Dataset, str],
|
|
878
|
+
dest_dir: Optional[str] = None,
|
|
879
|
+
meta: Optional[ProjectMeta] = None,
|
|
880
|
+
copy_images: bool = True,
|
|
881
|
+
with_captions: bool = False,
|
|
882
|
+
log_progress: bool = True,
|
|
883
|
+
progress_cb: Optional[Callable] = None,
|
|
884
|
+
) -> Union[None, str]:
|
|
885
|
+
"""
|
|
886
|
+
Universal function to convert Supervisely project or dataset to COCO format.
|
|
887
|
+
Note:
|
|
888
|
+
- For better compatibility, please pass named arguments explicitly. Otherwise, the function may not work as expected.
|
|
889
|
+
You can use the dedicated functions for each data type:
|
|
890
|
+
|
|
891
|
+
- :func:`sly.convert.sly_project_to_coco()`
|
|
892
|
+
- :func:`sly.convert.sly_ds_to_coco()`
|
|
893
|
+
|
|
894
|
+
- If the input_data is a Project, the dest_dir parameters are required.
|
|
895
|
+
- If the input_data is a Dataset, the meta and dest_dir parameters are required.
|
|
896
|
+
|
|
897
|
+
:param input_data: Supervisely project, dataset, or path to the project or dataset.
|
|
898
|
+
:type input_data: :class:`Project<supervisely.project.project.Project>`, :class:`Dataset<supervisely.project.dataset.Dataset>` or :class:`str`
|
|
899
|
+
|
|
900
|
+
# Project or Dataset conversion arguments:
|
|
901
|
+
:param dest_dir: Destination directory to save project or dataset in COCO format.
|
|
902
|
+
:type dest_dir: :class:`str`, optional
|
|
903
|
+
:param meta: Project meta information (required for dataset conversion).
|
|
904
|
+
:type meta: :class:`ProjectMeta<supervisely.project.project_meta.ProjectMeta>`, optional
|
|
905
|
+
:param copy_images: Copy images to destination directory
|
|
906
|
+
:type copy_images: :class:`bool`, optional
|
|
907
|
+
:param with_captions: If True, returns COCO captions
|
|
908
|
+
:type with_captions: :class:`bool`, optional
|
|
909
|
+
:param log_progress: Show uploading progress bar
|
|
910
|
+
:type log_progress: :class:`bool`
|
|
911
|
+
:param progress_cb: Function for tracking conversion progress (for all items in the project or dataset).
|
|
912
|
+
:type progress_cb: callable, optional
|
|
913
|
+
|
|
914
|
+
:return: None
|
|
915
|
+
:rtype: NoneType
|
|
916
|
+
|
|
917
|
+
:Usage example:
|
|
918
|
+
|
|
919
|
+
.. code-block:: python
|
|
920
|
+
|
|
921
|
+
import supervisely as sly
|
|
922
|
+
|
|
923
|
+
# Local folder with Project in Supervisely format
|
|
924
|
+
project_directory = "./source/project"
|
|
925
|
+
project_fs = sly.Project(project_directory, sly.OpenMode.READ)
|
|
926
|
+
|
|
927
|
+
# Convert Project to COCO format
|
|
928
|
+
sly.convert.to_coco(project_directory, dest_dir="./coco")
|
|
929
|
+
# or
|
|
930
|
+
sly.convert.to_coco(project_fs, dest_dir="./coco")
|
|
931
|
+
|
|
932
|
+
# Convert Dataset to COCO format
|
|
933
|
+
# dataset: sly.Dataset
|
|
934
|
+
sly.convert.to_coco(dataset, dest_dir="./coco", meta=project_fs.meta)
|
|
935
|
+
"""
|
|
936
|
+
if isinstance(input_data, str):
|
|
937
|
+
try:
|
|
938
|
+
input_data = Project(input_data, mode=OpenMode.READ)
|
|
939
|
+
except Exception:
|
|
940
|
+
try:
|
|
941
|
+
input_data = Dataset(input_data, mode=OpenMode.READ)
|
|
942
|
+
except Exception:
|
|
943
|
+
raise ValueError("Please check the path or the input data.")
|
|
944
|
+
|
|
945
|
+
if isinstance(input_data, Project):
|
|
946
|
+
return sly_project_to_coco(
|
|
947
|
+
project=input_data,
|
|
948
|
+
dest_dir=dest_dir,
|
|
949
|
+
copy_images=copy_images,
|
|
950
|
+
with_captions=with_captions,
|
|
951
|
+
log_progress=log_progress,
|
|
952
|
+
progress_cb=progress_cb,
|
|
953
|
+
)
|
|
954
|
+
if isinstance(input_data, Dataset):
|
|
955
|
+
if meta is None:
|
|
956
|
+
raise ValueError("Project meta information is required for dataset conversion.")
|
|
957
|
+
return sly_ds_to_coco(
|
|
958
|
+
dataset=input_data,
|
|
959
|
+
meta=meta,
|
|
960
|
+
return_type="path",
|
|
961
|
+
dest_dir=dest_dir,
|
|
962
|
+
copy_images=copy_images,
|
|
963
|
+
with_captions=with_captions,
|
|
964
|
+
log_progress=log_progress,
|
|
965
|
+
progress_cb=progress_cb,
|
|
966
|
+
)
|
|
967
|
+
raise ValueError("Unsupported input type. Only Project or Dataset are supported.")
|
|
@@ -7,17 +7,11 @@ import numpy as np
|
|
|
7
7
|
from PIL import Image
|
|
8
8
|
from tqdm import tqdm
|
|
9
9
|
|
|
10
|
-
from supervisely import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
ObjClassCollection,
|
|
16
|
-
Project,
|
|
17
|
-
ProjectMeta,
|
|
18
|
-
generate_free_name,
|
|
19
|
-
logger,
|
|
20
|
-
)
|
|
10
|
+
from supervisely._utils import generate_free_name
|
|
11
|
+
from supervisely.annotation.annotation import Annotation
|
|
12
|
+
from supervisely.annotation.label import Label
|
|
13
|
+
from supervisely.annotation.obj_class import ObjClass
|
|
14
|
+
from supervisely.annotation.obj_class_collection import ObjClassCollection
|
|
21
15
|
from supervisely.convert.image.image_helper import validate_image_bounds
|
|
22
16
|
from supervisely.geometry.bitmap import Bitmap
|
|
23
17
|
from supervisely.geometry.polygon import Polygon
|
|
@@ -26,6 +20,9 @@ from supervisely.imaging.color import generate_rgb
|
|
|
26
20
|
from supervisely.imaging.image import read
|
|
27
21
|
from supervisely.io.fs import file_exists, get_file_ext, get_file_name
|
|
28
22
|
from supervisely.io.json import load_json_file
|
|
23
|
+
from supervisely.project.project import Dataset, OpenMode, Project
|
|
24
|
+
from supervisely.project.project_meta import ProjectMeta
|
|
25
|
+
from supervisely.sly_logger import logger
|
|
29
26
|
from supervisely.task.progress import tqdm_sly
|
|
30
27
|
|
|
31
28
|
MASKS_EXTENSION = ".png"
|
|
@@ -374,7 +371,7 @@ def sly_ds_to_pascal_voc(
|
|
|
374
371
|
train_val_split_coef: float = 0.8,
|
|
375
372
|
log_progress: bool = False,
|
|
376
373
|
progress_cb: Optional[Union[tqdm, Callable]] = None,
|
|
377
|
-
) ->
|
|
374
|
+
) -> None:
|
|
378
375
|
"""
|
|
379
376
|
Convert Supervisely dataset to Pascal VOC format.
|
|
380
377
|
|
|
@@ -612,6 +609,9 @@ def sly_project_to_pascal_voc(
|
|
|
612
609
|
# Convert Project to Pascal VOC format
|
|
613
610
|
sly.Project(project_directory).to_pascal_voc(log_progress=True)
|
|
614
611
|
"""
|
|
612
|
+
if isinstance(project, str):
|
|
613
|
+
project = Project(project, mode=OpenMode.READ)
|
|
614
|
+
|
|
615
615
|
if dest_dir is None:
|
|
616
616
|
dest_dir = project.directory
|
|
617
617
|
|
|
@@ -636,3 +636,87 @@ def sly_project_to_pascal_voc(
|
|
|
636
636
|
)
|
|
637
637
|
logger.info(f"Dataset '{dataset.short_name}' has been converted to Pascal VOC format.")
|
|
638
638
|
logger.info(f"Project '{project.name}' has been converted to Pascal VOC format.")
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
def to_pascal_voc(
|
|
642
|
+
input_data: Union[Project, Dataset, str],
|
|
643
|
+
dest_dir: Optional[str] = None,
|
|
644
|
+
meta: Optional[ProjectMeta] = None,
|
|
645
|
+
train_val_split_coef: float = 0.8,
|
|
646
|
+
log_progress: bool = True,
|
|
647
|
+
progress_cb: Optional[Union[tqdm, Callable]] = None,
|
|
648
|
+
) -> None:
|
|
649
|
+
"""
|
|
650
|
+
Universal function to convert Supervisely project or dataset to Pascal VOC format.
|
|
651
|
+
Note:
|
|
652
|
+
- For better compatibility, please pass named arguments explicitly. Otherwise, the function may not work as expected.
|
|
653
|
+
You can use the dedicated functions for each data type:
|
|
654
|
+
|
|
655
|
+
- :func:`sly.convert.sly_project_to_pascal_voc()`
|
|
656
|
+
- :func:`sly.convert.sly_ds_to_pascal_voc()`
|
|
657
|
+
|
|
658
|
+
- If the input_data is a Project, the dest_dir parameters are required.
|
|
659
|
+
- If the input_data is a Dataset, the meta and dest_dir parameters are required.
|
|
660
|
+
|
|
661
|
+
:param input_data: Input data to convert (Project, Dataset, or path to the project/dataset directory).
|
|
662
|
+
:type input_data: :class:`Project<supervisely.project.project.Project>`, :class:`Dataset<supervisely.dataset.dataset.Dataset>`, or :class:`str`
|
|
663
|
+
:param dest_dir: Destination directory.
|
|
664
|
+
:type dest_dir: :class:`str`, optional
|
|
665
|
+
:param meta: Project meta information (required for Dataset conversion).
|
|
666
|
+
:type meta: :class:`ProjectMeta<supervisely.project.project_meta.ProjectMeta>`, optional
|
|
667
|
+
:param train_val_split_coef: Coefficient for splitting images into train and validation sets.
|
|
668
|
+
:type train_val_split_coef: :class:`float`, optional
|
|
669
|
+
:param log_progress: Show uploading progress bar.
|
|
670
|
+
:type log_progress: :class:`bool`
|
|
671
|
+
:param progress_cb: Function for tracking conversion progress (for all items in the project).
|
|
672
|
+
:type progress_cb: callable, optional
|
|
673
|
+
:return: None
|
|
674
|
+
:rtype: NoneType
|
|
675
|
+
|
|
676
|
+
:Usage example:
|
|
677
|
+
|
|
678
|
+
.. code-block:: python
|
|
679
|
+
|
|
680
|
+
import supervisely as sly
|
|
681
|
+
|
|
682
|
+
# Local folder with Project
|
|
683
|
+
project_directory = "/home/admin/work/supervisely/source/project"
|
|
684
|
+
project_fs = sly.Project(project_directory, sly.OpenMode.READ)
|
|
685
|
+
|
|
686
|
+
# Convert Project to Pascal VOC format
|
|
687
|
+
sly.convert.to_pascal_voc(project_directory, dest_dir="./pascal_voc")
|
|
688
|
+
# or
|
|
689
|
+
sly.convert.to_pascal_voc(project_fs, dest_dir="./pascal_voc")
|
|
690
|
+
|
|
691
|
+
# Convert Dataset to Pascal VOC format
|
|
692
|
+
dataset: sly.Dataset = project_fs.datasets.get("dataset_name")
|
|
693
|
+
sly.convert.to_pascal_voc(dataset, dest_dir="./pascal_voc")
|
|
694
|
+
"""
|
|
695
|
+
if isinstance(input_data, str):
|
|
696
|
+
try:
|
|
697
|
+
input_data = Project(input_data, mode=OpenMode.READ)
|
|
698
|
+
except Exception as e:
|
|
699
|
+
try:
|
|
700
|
+
input_data = Dataset(input_data, mode=OpenMode.READ)
|
|
701
|
+
except Exception as e:
|
|
702
|
+
raise ValueError("Please check the path or the input data.")
|
|
703
|
+
|
|
704
|
+
if isinstance(input_data, (Project, str)):
|
|
705
|
+
return sly_project_to_pascal_voc(
|
|
706
|
+
project=input_data,
|
|
707
|
+
dest_dir=dest_dir,
|
|
708
|
+
train_val_split_coef=train_val_split_coef,
|
|
709
|
+
log_progress=log_progress,
|
|
710
|
+
progress_cb=progress_cb,
|
|
711
|
+
)
|
|
712
|
+
elif isinstance(input_data, Dataset):
|
|
713
|
+
return sly_ds_to_pascal_voc(
|
|
714
|
+
dataset=input_data,
|
|
715
|
+
meta=meta,
|
|
716
|
+
dest_dir=dest_dir,
|
|
717
|
+
train_val_split_coef=train_val_split_coef,
|
|
718
|
+
log_progress=log_progress,
|
|
719
|
+
progress_cb=progress_cb,
|
|
720
|
+
)
|
|
721
|
+
else:
|
|
722
|
+
raise ValueError(f"Unsupported input data type: {type(input_data)}")
|
|
@@ -474,7 +474,7 @@ def label_to_yolo_lines(
|
|
|
474
474
|
max_kpts_count=max_kpts_count,
|
|
475
475
|
)
|
|
476
476
|
else:
|
|
477
|
-
raise ValueError(f"Unsupported
|
|
477
|
+
raise ValueError(f"Unsupported task type: {task_type}")
|
|
478
478
|
|
|
479
479
|
if yolo_line is not None:
|
|
480
480
|
lines.append(yolo_line)
|
|
@@ -657,3 +657,86 @@ def sly_project_to_yolo(
|
|
|
657
657
|
)
|
|
658
658
|
logger.info(f"Dataset '{dataset.short_name}' has been converted to YOLO format.")
|
|
659
659
|
logger.info(f"Project '{project.name}' has been converted to YOLO format.")
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
def to_yolo(
|
|
663
|
+
input_data: Union[Project, Dataset, str],
|
|
664
|
+
dest_dir: Optional[str] = None,
|
|
665
|
+
task_type: Literal["detection", "segmentation", "pose"] = "detection",
|
|
666
|
+
meta: Optional[ProjectMeta] = None,
|
|
667
|
+
log_progress: bool = True,
|
|
668
|
+
progress_cb: Optional[Callable] = None,
|
|
669
|
+
) -> Union[None, str]:
|
|
670
|
+
"""
|
|
671
|
+
Universal function to convert Supervisely project or dataset to YOLO format.
|
|
672
|
+
Note:
|
|
673
|
+
- For better compatibility, please pass named arguments explicitly. Otherwise, the function may not work as expected.
|
|
674
|
+
You can use the dedicated functions for each data type:
|
|
675
|
+
|
|
676
|
+
- :func:`sly.convert.sly_project_to_yolo()`
|
|
677
|
+
- :func:`sly.convert.sly_ds_to_yolo()`
|
|
678
|
+
|
|
679
|
+
- If the input_data is a Project, the dest_dir parameters are required.
|
|
680
|
+
- If the input_data is a Dataset, the meta and dest_dir parameters are required.
|
|
681
|
+
|
|
682
|
+
:param input_data: Supervisely project or dataset, or path to the directory with the project/dataset.
|
|
683
|
+
:type input_data: :class:`supervisely.project.project.Project`, :class:`supervisely.project.dataset.Dataset`, or :class:`str`
|
|
684
|
+
:param dest_dir: Destination directory.
|
|
685
|
+
:type dest_dir: :class:`str`, optional
|
|
686
|
+
:param task_type: Task type.
|
|
687
|
+
:type task_type: :class:`str`, optional
|
|
688
|
+
:param meta: Project meta (required for Dataset conversion).
|
|
689
|
+
:type meta: :class:`supervisely.project.project_meta.ProjectMeta`, optional
|
|
690
|
+
:param log_progress: Show uploading progress bar.
|
|
691
|
+
:type log_progress: :class:`bool`
|
|
692
|
+
:param progress_cb: Function for tracking conversion progress (for all items in the project).
|
|
693
|
+
:type progress_cb: callable, optional
|
|
694
|
+
:return: None, list of YOLO lines, or path to the destination directory.
|
|
695
|
+
:rtype: NoneType, list, str
|
|
696
|
+
|
|
697
|
+
:Usage example:
|
|
698
|
+
|
|
699
|
+
.. code-block:: python
|
|
700
|
+
|
|
701
|
+
import supervisely as sly
|
|
702
|
+
|
|
703
|
+
# Local folder with Project
|
|
704
|
+
project_directory = "/home/admin/work/supervisely/source/project"
|
|
705
|
+
project_fs = sly.Project(project_directory, sly.OpenMode.READ)
|
|
706
|
+
|
|
707
|
+
# Convert Project to YOLO format
|
|
708
|
+
sly.convert.to_yolo(project_directory, dest_dir="./yolo")
|
|
709
|
+
# or
|
|
710
|
+
sly.convert.to_yolo(project_fs, dest_dir="./yolo")
|
|
711
|
+
|
|
712
|
+
# Convert Dataset to YOLO format
|
|
713
|
+
dataset: sly.Dataset = project_fs.datasets.get("dataset_name")
|
|
714
|
+
sly.convert.to_yolo(dataset, dest_dir="./yolo", meta=project_fs.meta)
|
|
715
|
+
"""
|
|
716
|
+
if isinstance(input_data, str):
|
|
717
|
+
try:
|
|
718
|
+
input_data = Project(input_data, mode=OpenMode.READ)
|
|
719
|
+
except Exception:
|
|
720
|
+
try:
|
|
721
|
+
input_data = Dataset(input_data, mode=OpenMode.READ)
|
|
722
|
+
except Exception:
|
|
723
|
+
raise ValueError("Please check the path or the input data.")
|
|
724
|
+
if isinstance(input_data, Project):
|
|
725
|
+
return sly_project_to_yolo(
|
|
726
|
+
project=input_data,
|
|
727
|
+
dest_dir=dest_dir,
|
|
728
|
+
task_type=task_type,
|
|
729
|
+
log_progress=log_progress,
|
|
730
|
+
progress_cb=progress_cb,
|
|
731
|
+
)
|
|
732
|
+
elif isinstance(input_data, Dataset):
|
|
733
|
+
return sly_ds_to_yolo(
|
|
734
|
+
dataset=input_data,
|
|
735
|
+
meta=meta,
|
|
736
|
+
dest_dir=dest_dir,
|
|
737
|
+
task_type=task_type,
|
|
738
|
+
log_progress=log_progress,
|
|
739
|
+
progress_cb=progress_cb,
|
|
740
|
+
)
|
|
741
|
+
else:
|
|
742
|
+
raise ValueError("Unsupported input type. Only Project or Dataset are supported.")
|
|
@@ -564,7 +564,7 @@ supervisely/cli/teamfiles/teamfiles_upload.py,sha256=xnsW2rvdq1e-KGjF1tMBu7Oxh3n
|
|
|
564
564
|
supervisely/collection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
565
565
|
supervisely/collection/key_indexed_collection.py,sha256=x2UVlkprspWhhae9oLUzjTWBoIouiWY9UQSS_MozfH0,37643
|
|
566
566
|
supervisely/collection/str_enum.py,sha256=Zp29yFGvnxC6oJRYNNlXhO2lTSdsriU1wiGHj6ahEJE,1250
|
|
567
|
-
supervisely/convert/__init__.py,sha256=
|
|
567
|
+
supervisely/convert/__init__.py,sha256=ropgB1eebG2bfLoJyf2jp8Vv9UkFujaW3jVX-71ho1g,1353
|
|
568
568
|
supervisely/convert/base_converter.py,sha256=eCFnvyoMI96rWjB5amFPZX2fI_TSdr__ruqxwQIbfFo,18537
|
|
569
569
|
supervisely/convert/converter.py,sha256=tWxTDfFv7hwzQhUQrBxzfr6WP8FUGFX_ewg5T2HbUYo,8959
|
|
570
570
|
supervisely/convert/image/__init__.py,sha256=JEuyaBiiyiYmEUYqdn8Mog5FVXpz0H1zFubKkOOm73I,1395
|
|
@@ -576,7 +576,7 @@ supervisely/convert/image/cityscapes/cityscapes_helper.py,sha256=in5nR7__q_u5dCk
|
|
|
576
576
|
supervisely/convert/image/coco/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
577
577
|
supervisely/convert/image/coco/coco_anntotation_converter.py,sha256=O1PQbwrbnpQBks2pcz2nbAnhSqpKqNk13B2ARk_roFM,7078
|
|
578
578
|
supervisely/convert/image/coco/coco_converter.py,sha256=7dW7vE6yTRz7O31vTVSnEA4MDCc_UXTqc2UFEqaKorI,5650
|
|
579
|
-
supervisely/convert/image/coco/coco_helper.py,sha256=
|
|
579
|
+
supervisely/convert/image/coco/coco_helper.py,sha256=heJcaptN9nX8BEB3ZYiFEQvPfylUCmw3g4pGxlNt_sk,39265
|
|
580
580
|
supervisely/convert/image/csv/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
581
581
|
supervisely/convert/image/csv/csv_converter.py,sha256=iLyc2PAVtlsAq7blnGH4iS1_D7Ai6-4UsdI_RlDVB9Q,11677
|
|
582
582
|
supervisely/convert/image/csv/csv_helper.py,sha256=-nR192IfMU0vTlNRoKXu5FS6tTs9fENqySyeKKyemRs,8409
|
|
@@ -601,7 +601,7 @@ supervisely/convert/image/multispectral/__init__.py,sha256=47DEQpj8HBSa-_TImW-5J
|
|
|
601
601
|
supervisely/convert/image/multispectral/multispectral_converter.py,sha256=T3etYVNI0AUUrQsQhxw_r85NthXrqhqmdZQfz8kUY0g,5194
|
|
602
602
|
supervisely/convert/image/pascal_voc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
603
603
|
supervisely/convert/image/pascal_voc/pascal_voc_converter.py,sha256=h5Q3qW4riUCXPo5535wuKGurlLvPfKbWGML0RGnMxyg,7648
|
|
604
|
-
supervisely/convert/image/pascal_voc/pascal_voc_helper.py,sha256=
|
|
604
|
+
supervisely/convert/image/pascal_voc/pascal_voc_helper.py,sha256=oM-HKUePUwB27aQjL-EvyeS7K-GX0X31rms2yOTTnGo,27872
|
|
605
605
|
supervisely/convert/image/pdf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
606
606
|
supervisely/convert/image/pdf/pdf_converter.py,sha256=LKvVng9jPp0cSIjYEjKLOb48wtdOdB7LXS2gjmOdZhE,2442
|
|
607
607
|
supervisely/convert/image/pdf/pdf_helper.py,sha256=IDwLEvsVy8lu-KC1lXvSRkZZ9BCC6ylebnNEtLQU5L4,1288
|
|
@@ -611,7 +611,7 @@ supervisely/convert/image/sly/sly_image_converter.py,sha256=097ijLa_62ZBu0elRx0x
|
|
|
611
611
|
supervisely/convert/image/sly/sly_image_helper.py,sha256=5Ri8fKb5dzh5b3v8AJ5u8xVFOQfAtoWqZ7HktPsCjTI,7373
|
|
612
612
|
supervisely/convert/image/yolo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
613
613
|
supervisely/convert/image/yolo/yolo_converter.py,sha256=Wn5dR05y4SEPONcaxWr9ofnbvbf-SbRZN0fkksk5Dps,11391
|
|
614
|
-
supervisely/convert/image/yolo/yolo_helper.py,sha256=
|
|
614
|
+
supervisely/convert/image/yolo/yolo_helper.py,sha256=ePBnt8c52JM-lh-bH7XdIal4_UkjysSK7yVX0qhVqdE,22556
|
|
615
615
|
supervisely/convert/pointcloud/__init__.py,sha256=WPeIpPoTWDIKAa0lF6t2SMUhFNZ0l-vKujf6yD6w7SA,589
|
|
616
616
|
supervisely/convert/pointcloud/pointcloud_converter.py,sha256=yCCpzm7GrvL6WT4lNesvtYWWwdO3DO32JIOBBSSQgSA,7130
|
|
617
617
|
supervisely/convert/pointcloud/bag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -1074,9 +1074,9 @@ supervisely/worker_proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
|
|
|
1074
1074
|
supervisely/worker_proto/worker_api_pb2.py,sha256=VQfi5JRBHs2pFCK1snec3JECgGnua3Xjqw_-b3aFxuM,59142
|
|
1075
1075
|
supervisely/worker_proto/worker_api_pb2_grpc.py,sha256=3BwQXOaP9qpdi0Dt9EKG--Lm8KGN0C5AgmUfRv77_Jk,28940
|
|
1076
1076
|
supervisely_lib/__init__.py,sha256=7-3QnN8Zf0wj8NCr2oJmqoQWMKKPKTECvjH9pd2S5vY,159
|
|
1077
|
-
supervisely-6.73.
|
|
1078
|
-
supervisely-6.73.
|
|
1079
|
-
supervisely-6.73.
|
|
1080
|
-
supervisely-6.73.
|
|
1081
|
-
supervisely-6.73.
|
|
1082
|
-
supervisely-6.73.
|
|
1077
|
+
supervisely-6.73.302.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
1078
|
+
supervisely-6.73.302.dist-info/METADATA,sha256=neiLTS6rqFkTnt3DOxJqpgLrZlsRdiuJttck1TlF8pk,33573
|
|
1079
|
+
supervisely-6.73.302.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
1080
|
+
supervisely-6.73.302.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
|
|
1081
|
+
supervisely-6.73.302.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
|
|
1082
|
+
supervisely-6.73.302.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|