Skip to content

Commit 7906b22

Browse files
authored
Download lidar frame (#386)
1 parent b52db13 commit 7906b22

File tree

5 files changed

+85
-1
lines changed

5 files changed

+85
-1
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ All notable changes to the [Nucleus Python Client](https://github.com/scaleapi/n
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.15.7](https://github.com/scaleapi/nucleus-python-client/releases/tag/v0.15.7) - 2023-06-09
9+
10+
### Added
11+
- Allow for downloading pointcloud data for a give task and frame number, example:
12+
13+
```python
14+
import nucleus
15+
import numpy as np
16+
client = nucleus.NucleusClient(API_KEY)
17+
pts = client.download_pointcloud_task(task_id, frame_num=1)
18+
np_pts = np.array([pt.to_list() for pt in pts])
19+
```
20+
821
## [0.15.6](https://github.com/scaleapi/nucleus-python-client/releases/tag/v0.15.6) - 2023-06-03
922

1023
### Changed

nucleus/__init__.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"Keypoint",
1818
"KeypointsAnnotation",
1919
"KeypointsPrediction",
20+
"LidarPoint",
2021
"LidarScene",
2122
"LineAnnotation",
2223
"LinePrediction",
@@ -57,6 +58,7 @@
5758
CuboidAnnotation,
5859
Keypoint,
5960
KeypointsAnnotation,
61+
LidarPoint,
6062
LineAnnotation,
6163
MultiCategoryAnnotation,
6264
Point,
@@ -82,6 +84,7 @@
8284
ERROR_ITEMS,
8385
ERROR_PAYLOAD,
8486
ERRORS_KEY,
87+
I_KEY,
8588
IMAGE_KEY,
8689
IMAGE_URL_KEY,
8790
INDEX_CONTINUOUS_ENABLE_KEY,
@@ -97,6 +100,7 @@
97100
MODEL_TAGS_KEY,
98101
NAME_KEY,
99102
NUCLEUS_ENDPOINT,
103+
POINTS_KEY,
100104
PREDICTIONS_IGNORED_KEY,
101105
PREDICTIONS_PROCESSED_KEY,
102106
REFERENCE_IDS_KEY,
@@ -978,6 +982,36 @@ def delete_model(self, model_id: str) -> dict:
978982
)
979983
return response
980984

985+
def download_pointcloud_task(
986+
self, task_id: str, frame_num: int
987+
) -> List[Union[Point3D, LidarPoint]]:
988+
"""
989+
Download the lidar point cloud data for a give task and frame number.
990+
991+
Parameters:
992+
task_id: download point cloud for this particular task
993+
frame_num: download point cloud for this particular frame
994+
995+
Returns:
996+
List of Point3D objects
997+
998+
"""
999+
1000+
response = self.make_request(
1001+
payload={},
1002+
route=f"task/{task_id}/frame/{frame_num}",
1003+
requests_command=requests.get,
1004+
)
1005+
points = response.get(POINTS_KEY, None)
1006+
if points is None or len(points) == 0:
1007+
raise Exception("Response has invalid payload")
1008+
1009+
sample_point = points[0]
1010+
if I_KEY in sample_point.keys():
1011+
return [LidarPoint.from_json(pt) for pt in points[:10]]
1012+
1013+
return [Point3D.from_json(pt) for pt in points]
1014+
9811015
@deprecated("Prefer calling Dataset.create_custom_index instead.")
9821016
def create_custom_index(
9831017
self, dataset_id: str, embeddings_urls: list, embedding_dim: int

nucleus/annotation.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from typing import Dict, List, Optional, Sequence, Type, Union
66
from urllib.parse import urlparse
77

8+
import numpy as np
9+
810
from .constants import (
911
ANNOTATION_ID_KEY,
1012
ANNOTATIONS_KEY,
@@ -15,6 +17,7 @@
1517
EMBEDDING_VECTOR_KEY,
1618
GEOMETRY_KEY,
1719
HEIGHT_KEY,
20+
I_KEY,
1821
INDEX_KEY,
1922
KEYPOINTS_KEY,
2023
KEYPOINTS_NAMES_KEY,
@@ -588,6 +591,38 @@ def from_json(cls, payload: Dict[str, float]):
588591
def to_payload(self) -> dict:
589592
return {X_KEY: self.x, Y_KEY: self.y, Z_KEY: self.z}
590593

594+
def to_list(self):
595+
return [self.x, self.y, self.z]
596+
597+
598+
@dataclass
599+
class LidarPoint(Point3D):
600+
"""A Lidar point in 3D space and intensity.
601+
602+
Parameters:
603+
x (float): The x coordinate of the point.
604+
y (float): The y coordinate of the point.
605+
z (float): The z coordinate of the point.
606+
i (float): The intensity value returned by the lidar scan point.
607+
"""
608+
609+
i: float
610+
611+
@classmethod
612+
def from_json(cls, payload: Dict[str, float]):
613+
return cls(
614+
payload[X_KEY], payload[Y_KEY], payload[Z_KEY], payload[I_KEY]
615+
)
616+
617+
def to_payload(self) -> dict:
618+
return {X_KEY: self.x, Y_KEY: self.y, Z_KEY: self.z, I_KEY: self.i}
619+
620+
def to_list(self):
621+
return [self.x, self.y, self.z, self.i]
622+
623+
def to_numpy(self):
624+
return np.array(self.to_list())
625+
591626

592627
@dataclass # pylint: disable=R0902
593628
class CuboidAnnotation(Annotation): # pylint: disable=R0902

nucleus/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
OBJECT_IDS_KEY = "object_ids"
109109
P1_KEY = "p1"
110110
P2_KEY = "p2"
111+
POINTS_KEY = "points"
111112
POINTCLOUD_KEY = "pointcloud"
112113
POINTCLOUD_LOCATION_KEY = "pointcloud_location"
113114
POINTCLOUD_URL_KEY = "pointcloud_url"
@@ -144,6 +145,7 @@
144145
VISIBLE_KEY = "visible"
145146
WIDTH_KEY = "width"
146147
YAW_KEY = "yaw"
148+
I_KEY = "i"
147149
W_KEY = "w"
148150
X_KEY = "x"
149151
Y_KEY = "y"

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ exclude = '''
2121

2222
[tool.poetry]
2323
name = "scale-nucleus"
24-
version = "0.15.6"
24+
version = "0.15.7"
2525
description = "The official Python client library for Nucleus, the Data Platform for AI"
2626
license = "MIT"
2727
authors = ["Scale AI Nucleus Team <nucleusapi@scaleapi.com>"]

0 commit comments

Comments
 (0)