supervisely 6.73.276__py3-none-any.whl → 6.73.277__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.

@@ -39,6 +39,7 @@ from supervisely.convert.pointcloud.ply.ply_converter import PlyConverter
39
39
  from supervisely.convert.pointcloud.bag.bag_converter import BagConverter
40
40
  from supervisely.convert.pointcloud.lyft.lyft_converter import LyftConverter
41
41
  from supervisely.convert.pointcloud.nuscenes_conv.nuscenes_converter import NuscenesConverter
42
+ from supervisely.convert.pointcloud.kitti_3d.kitti_3d_converter import KITTI3DConverter
42
43
 
43
44
  # Pointcloud Episodes
44
45
  from supervisely.convert.pointcloud_episodes.sly.sly_pointcloud_episodes_converter import (
@@ -56,6 +56,7 @@ class AvailablePointcloudConverters:
56
56
  BAG = "rosbag"
57
57
  LYFT = "lyft"
58
58
  NUSCENES = "nuscenes"
59
+ KITTI3D = "kitti3d"
59
60
 
60
61
 
61
62
  class AvailablePointcloudEpisodesConverters:
File without changes
@@ -0,0 +1,139 @@
1
+ import os
2
+ from pathlib import Path
3
+
4
+ from supervisely import PointcloudAnnotation, ProjectMeta, is_development, logger
5
+ from supervisely.api.api import Api, ApiField
6
+ from supervisely.convert.base_converter import AvailablePointcloudConverters
7
+ from supervisely.convert.pointcloud.kitti_3d import kitti_3d_helper
8
+ from supervisely.convert.pointcloud.pointcloud_converter import PointcloudConverter
9
+ from supervisely.io.fs import (
10
+ dirs_filter,
11
+ file_exists,
12
+ get_file_ext,
13
+ get_file_name,
14
+ get_file_name_with_ext,
15
+ list_files,
16
+ silent_remove,
17
+ )
18
+ from supervisely.pointcloud_annotation.pointcloud_object_collection import (
19
+ PointcloudObjectCollection,
20
+ )
21
+
22
+
23
+ class KITTI3DConverter(PointcloudConverter):
24
+ def __str__(self) -> str:
25
+ return AvailablePointcloudConverters.KITTI3D
26
+
27
+ @property
28
+ def key_file_ext(self) -> str:
29
+ return ".bin"
30
+
31
+ def validate_format(self) -> bool:
32
+ def _file_filter_fn(file_path):
33
+ return get_file_ext(file_path).lower() == self.key_file_ext
34
+
35
+ def _dir_filter_fn(path):
36
+ return all([(Path(path) / name).exists() for name in kitti_3d_helper.FOLDER_NAMES])
37
+
38
+ input_paths = [d for d in dirs_filter(self._input_data, _dir_filter_fn)]
39
+ if len(input_paths) == 0:
40
+ return False
41
+
42
+ input_path = input_paths[0]
43
+ velodyne_dir = os.path.join(input_path, "velodyne")
44
+ image_2_dir = os.path.join(input_path, "image_2")
45
+ label_2_dir = os.path.join(input_path, "label_2")
46
+ calib_dir = os.path.join(input_path, "calib")
47
+
48
+ self._items = []
49
+ velodyne_files = list_files(velodyne_dir, filter_fn=_file_filter_fn)
50
+ if len(velodyne_files) == 0:
51
+ return False
52
+
53
+ kitti_labels = []
54
+ for velodyne_path in velodyne_files:
55
+ file_name = get_file_name(velodyne_path)
56
+ image_path = os.path.join(image_2_dir, f"{file_name}.png")
57
+ label_path = os.path.join(label_2_dir, f"{file_name}.txt")
58
+ calib_path = os.path.join(calib_dir, f"{file_name}.txt")
59
+ if not file_exists(image_path):
60
+ logger.debug(f"Skipping item: {velodyne_path}. Image not found.")
61
+ continue
62
+ if not file_exists(label_path):
63
+ logger.debug(f"Skipping item: {velodyne_path}. Label not found.")
64
+ continue
65
+ if not file_exists(calib_path):
66
+ logger.debug(f"Skipping item: {velodyne_path}. Calibration not found.")
67
+ continue
68
+
69
+ label = kitti_3d_helper.read_kitti_label(label_path, calib_path)
70
+ kitti_labels.append(label)
71
+ self._items.append(self.Item(velodyne_path, label, (image_path, calib_path)))
72
+
73
+ self._meta = kitti_3d_helper.convert_labels_to_meta(kitti_labels)
74
+ return self.items_count > 0
75
+
76
+ def to_supervisely(
77
+ self,
78
+ item: PointcloudConverter.Item,
79
+ meta: ProjectMeta,
80
+ renamed_classes: dict = {},
81
+ renamed_tags: dict = {},
82
+ ) -> PointcloudAnnotation:
83
+ label = item.ann_data
84
+ objs, figures = kitti_3d_helper.convert_label_to_annotation(label, meta, renamed_classes)
85
+ return PointcloudAnnotation(PointcloudObjectCollection(objs), figures)
86
+
87
+ def upload_dataset(self, api: Api, dataset_id: int, batch_size: int = 1, log_progress=True):
88
+ meta, renamed_classes, renamed_tags = self.merge_metas_with_conflicts(api, dataset_id)
89
+
90
+ if log_progress:
91
+ progress, progress_cb = self.get_progress(self.items_count, "Converting pointclouds...")
92
+ else:
93
+ progress_cb = None
94
+
95
+ for item in self._items:
96
+ # * Convert pointcloud from ".bin" to ".pcd"
97
+ pcd_path = str(Path(item.path).with_suffix(".pcd"))
98
+ if file_exists(pcd_path):
99
+ logger.warning(f"Overwriting file with path: {pcd_path}")
100
+ kitti_3d_helper.convert_bin_to_pcd(item.path, pcd_path)
101
+
102
+ # * Upload pointcloud
103
+ pcd_name = get_file_name_with_ext(pcd_path)
104
+ info = api.pointcloud.upload_path(dataset_id, pcd_name, pcd_path, {})
105
+ pcd_id = info.id
106
+
107
+ # * Convert annotation and upload
108
+ ann = self.to_supervisely(item, meta, renamed_classes, renamed_tags)
109
+ api.pointcloud.annotation.append(pcd_id, ann)
110
+
111
+ # * Upload related images
112
+ image_path, calib_path = item._related_images
113
+ rimage_info = kitti_3d_helper.convert_calib_to_image_meta(image_path, calib_path)
114
+
115
+ image_jsons = []
116
+ camera_names = []
117
+ img = api.pointcloud.upload_related_image(image_path)
118
+ image_jsons.append(
119
+ {
120
+ ApiField.ENTITY_ID: pcd_id,
121
+ ApiField.NAME: get_file_name_with_ext(rimage_info[ApiField.NAME]),
122
+ ApiField.HASH: img,
123
+ ApiField.META: rimage_info[ApiField.META],
124
+ }
125
+ )
126
+ camera_names.append(rimage_info[ApiField.META]["deviceId"])
127
+ if len(image_jsons) > 0:
128
+ api.pointcloud.add_related_images(image_jsons, camera_names)
129
+
130
+ # * Clean up
131
+ silent_remove(pcd_path)
132
+ if log_progress:
133
+ progress_cb(1)
134
+
135
+ logger.info(f"Dataset ID:{dataset_id} has been successfully uploaded.")
136
+
137
+ if log_progress:
138
+ if is_development():
139
+ progress.close()
@@ -0,0 +1,110 @@
1
+ import numpy as np
2
+
3
+ from supervisely import ObjClass, ObjClassCollection, ProjectMeta
4
+ from supervisely.geometry.cuboid_3d import Cuboid3d
5
+ from supervisely.geometry.point_3d import Vector3d
6
+ from supervisely.pointcloud_annotation.pointcloud_figure import PointcloudFigure
7
+ from supervisely.pointcloud_annotation.pointcloud_object import PointcloudObject
8
+
9
+ FOLDER_NAMES = ["velodyne", "image_2", "label_2", "calib"]
10
+
11
+
12
+ def read_kitti_label(label_path, calib_path):
13
+ import open3d as o3d # pylint: disable=import-error
14
+
15
+ calib = o3d.ml.datasets.KITTI.read_calib(calib_path)
16
+ label = o3d.ml.datasets.KITTI.read_label(label_path, calib)
17
+ return label
18
+
19
+
20
+ def convert_labels_to_meta(labels):
21
+ labels = flatten(labels)
22
+ unique_labels = np.unique([l.label_class for l in labels])
23
+ obj_classes = [ObjClass(k, Cuboid3d) for k in unique_labels]
24
+ meta = ProjectMeta(obj_classes=ObjClassCollection(obj_classes))
25
+ return meta
26
+
27
+
28
+ def convert_bin_to_pcd(src, dst):
29
+ import open3d as o3d # pylint: disable=import-error
30
+
31
+ try:
32
+ bin = np.fromfile(src, dtype=np.float32).reshape(-1, 4)
33
+ except ValueError as e:
34
+ raise Exception(
35
+ f"Incorrect data in the KITTI 3D pointcloud file: {src}. "
36
+ f"There was an error while trying to reshape the data into a 4-column matrix: {e}. "
37
+ "Please ensure that the binary file contains a multiple of 4 elements to be "
38
+ "successfully reshaped into a (N, 4) array.\n"
39
+ )
40
+ points = bin[:, 0:3]
41
+ intensity = bin[:, -1]
42
+ intensity_fake_rgb = np.zeros((intensity.shape[0], 3))
43
+ intensity_fake_rgb[:, 0] = intensity
44
+ pc = o3d.geometry.PointCloud(o3d.utility.Vector3dVector(points))
45
+ pc.colors = o3d.utility.Vector3dVector(intensity_fake_rgb)
46
+ o3d.io.write_point_cloud(dst, pc)
47
+
48
+
49
+ def flatten(list_2d):
50
+ return sum(list_2d, [])
51
+
52
+
53
+ def _convert_label_to_geometry(label):
54
+ geometries = []
55
+ for l in label:
56
+ bbox = l.to_xyzwhlr()
57
+ dim = bbox[[3, 5, 4]]
58
+ pos = bbox[:3] + [0, 0, dim[1] / 2]
59
+ yaw = bbox[-1]
60
+ position = Vector3d(float(pos[0]), float(pos[1]), float(pos[2]))
61
+ rotation = Vector3d(0, 0, float(-yaw))
62
+
63
+ dimension = Vector3d(float(dim[0]), float(dim[2]), float(dim[1]))
64
+ geometry = Cuboid3d(position, rotation, dimension)
65
+ geometries.append(geometry)
66
+ return geometries
67
+
68
+
69
+ def convert_label_to_annotation(label, meta, renamed_class_names: dict = None):
70
+ geometries = _convert_label_to_geometry(label)
71
+ figures = []
72
+ objs = []
73
+ for l, geometry in zip(label, geometries): # by object in point cloud
74
+ class_name = renamed_class_names.get(l.label_class, l.label_class)
75
+ pcobj = PointcloudObject(meta.get_obj_class(class_name))
76
+ figures.append(PointcloudFigure(pcobj, geometry))
77
+ objs.append(pcobj)
78
+
79
+ return objs, figures
80
+
81
+
82
+ def convert_calib_to_image_meta(image_name, calib_path, camera_num=2):
83
+ with open(calib_path, "r") as f:
84
+ lines = f.readlines()
85
+
86
+ assert 0 < camera_num < 4
87
+ intrinsic_matrix = lines[camera_num].strip().split(" ")[1:]
88
+ intrinsic_matrix = np.array(intrinsic_matrix, dtype=np.float32).reshape(3, 4)[:3, :3]
89
+
90
+ obj = lines[4].strip().split(" ")[1:]
91
+ rect_4x4 = np.eye(4, dtype=np.float32)
92
+ rect_4x4[:3, :3] = np.array(obj, dtype=np.float32).reshape(3, 3)
93
+
94
+ obj = lines[5].strip().split(" ")[1:]
95
+ Tr_velo_to_cam = np.eye(4, dtype=np.float32)
96
+ Tr_velo_to_cam[:3] = np.array(obj, dtype=np.float32).reshape(3, 4)
97
+ world_cam = np.transpose(rect_4x4 @ Tr_velo_to_cam)
98
+ extrinsic_matrix = world_cam[:4, :3].T
99
+
100
+ data = {
101
+ "name": image_name,
102
+ "meta": {
103
+ "deviceId": "CAM_LEFT",
104
+ "sensorsData": {
105
+ "extrinsicMatrix": list(extrinsic_matrix.flatten().astype(float)),
106
+ "intrinsicMatrix": list(intrinsic_matrix.flatten().astype(float)),
107
+ },
108
+ },
109
+ }
110
+ return data
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: supervisely
3
- Version: 6.73.276
3
+ Version: 6.73.277
4
4
  Summary: Supervisely Python SDK.
5
5
  Home-page: https://github.com/supervisely/supervisely
6
6
  Author: Supervisely
@@ -560,8 +560,8 @@ supervisely/cli/teamfiles/teamfiles_upload.py,sha256=xnsW2rvdq1e-KGjF1tMBu7Oxh3n
560
560
  supervisely/collection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
561
561
  supervisely/collection/key_indexed_collection.py,sha256=x2UVlkprspWhhae9oLUzjTWBoIouiWY9UQSS_MozfH0,37643
562
562
  supervisely/collection/str_enum.py,sha256=Zp29yFGvnxC6oJRYNNlXhO2lTSdsriU1wiGHj6ahEJE,1250
563
- supervisely/convert/__init__.py,sha256=qomoncLRQeOzJkMceC6okFbyYcVQIXdvH_VG0-yKMqo,2955
564
- supervisely/convert/base_converter.py,sha256=F2fD1zq3agV1H_T59V4nduI_0V4uVe9bjfPeu85L_8c,18004
563
+ supervisely/convert/__init__.py,sha256=742-oqcs_n0YSOQMXPxZoLaZu_72jrMBompsIsUWekI,3043
564
+ supervisely/convert/base_converter.py,sha256=6kQETAOHHRiBXGWCeVVr8Z2dbLYdPHM1to_P3lGvGRY,18028
565
565
  supervisely/convert/converter.py,sha256=tWxTDfFv7hwzQhUQrBxzfr6WP8FUGFX_ewg5T2HbUYo,8959
566
566
  supervisely/convert/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
567
567
  supervisely/convert/image/image_converter.py,sha256=r-qdhuwOsk727mXIM26ucQhkoIKigu1M0BF-tw9IfGg,10321
@@ -613,6 +613,9 @@ supervisely/convert/pointcloud/pointcloud_converter.py,sha256=yCCpzm7GrvL6WT4lNe
613
613
  supervisely/convert/pointcloud/bag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
614
614
  supervisely/convert/pointcloud/bag/bag_converter.py,sha256=WWd6A2hS7H4MRgtLdJ-yYgmNU-Wk2eycl6LTTJM2GKQ,11391
615
615
  supervisely/convert/pointcloud/bag/bag_helper.py,sha256=2TFe49isZTxMhya-PApqLPxrvGnvRFMBc_--BwyCpWU,4284
616
+ supervisely/convert/pointcloud/kitti_3d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
617
+ supervisely/convert/pointcloud/kitti_3d/kitti_3d_converter.py,sha256=Ipyf1k--0v0Aji7lEbUzseB3E_DqdicuR-eg3ZBkVFk,5462
618
+ supervisely/convert/pointcloud/kitti_3d/kitti_3d_helper.py,sha256=xrAOD_O7NQu5_rhFF5pE2uwGdZlMh6XXGgtM2rpyd9A,3946
616
619
  supervisely/convert/pointcloud/las/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
617
620
  supervisely/convert/pointcloud/las/las_converter.py,sha256=prbvApwrjQ2cuDD9nAFBDkTLxtsN4jdjCZdNnkNow-g,1722
618
621
  supervisely/convert/pointcloud/las/las_helper.py,sha256=1gQ3OZLpe6D25CY_jXWDsrLBiS7nWfCgl3Zq--9TU14,1296
@@ -1067,9 +1070,9 @@ supervisely/worker_proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
1067
1070
  supervisely/worker_proto/worker_api_pb2.py,sha256=VQfi5JRBHs2pFCK1snec3JECgGnua3Xjqw_-b3aFxuM,59142
1068
1071
  supervisely/worker_proto/worker_api_pb2_grpc.py,sha256=3BwQXOaP9qpdi0Dt9EKG--Lm8KGN0C5AgmUfRv77_Jk,28940
1069
1072
  supervisely_lib/__init__.py,sha256=7-3QnN8Zf0wj8NCr2oJmqoQWMKKPKTECvjH9pd2S5vY,159
1070
- supervisely-6.73.276.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1071
- supervisely-6.73.276.dist-info/METADATA,sha256=IEQlHjL5OYrRUVXISxSa5jZEaxfStqtTGbn40HHu810,33573
1072
- supervisely-6.73.276.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
1073
- supervisely-6.73.276.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1074
- supervisely-6.73.276.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1075
- supervisely-6.73.276.dist-info/RECORD,,
1073
+ supervisely-6.73.277.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1074
+ supervisely-6.73.277.dist-info/METADATA,sha256=46bfRNq5HF8g4IKBZISbg8yin73sQVYm-XM6H9pnGSA,33573
1075
+ supervisely-6.73.277.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
1076
+ supervisely-6.73.277.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1077
+ supervisely-6.73.277.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1078
+ supervisely-6.73.277.dist-info/RECORD,,