2222 TYPE_KEY ,
2323 UPLOAD_TO_SCALE_KEY ,
2424 URL_KEY ,
25+ VIDEO_FRAME_URL_KEY ,
2526 W_KEY ,
2627 X_KEY ,
2728 Y_KEY ,
@@ -120,34 +121,42 @@ def to_payload(self) -> dict:
120121class DatasetItemType (Enum ):
121122 IMAGE = "image"
122123 POINTCLOUD = "pointcloud"
124+ VIDEO = "video"
123125
124126
125127@dataclass # pylint: disable=R0902
126128class DatasetItem : # pylint: disable=R0902
127- """A dataset item is an image or pointcloud that has associated metadata.
129+ """A dataset item is an image, pointcloud or video frame that has associated metadata.
128130
129131 Note: for 3D data, please include a :class:`CameraParams` object under a key named
130132 "camera_params" within the metadata dictionary. This will allow for projecting
131133 3D annotations to any image within a scene.
132134
133135 Args:
134- image_location (Optional[str]): Required if pointcloud_location not present: The
135- location containing the image for the given row of data. This can be a
136- local path, or a remote URL. Remote formats supported include any URL
137- (``http://`` or ``https://``) or URIs for AWS S3, Azure, or GCS
138- (i.e. ``s3://``, ``gcs://``).
139-
140- pointcloud_location (Optional[str]): Required if image_location not
141- present: The remote URL containing the pointcloud JSON. Remote
142- formats supported include any URL (``http://`` or ``https://``) or
143- URIs for AWS S3, Azure, or GCS (i.e. ``s3://``, ``gcs://``).
136+ image_location (Optional[str]): Required if pointcloud_location and
137+ video_frame_location are not present: The location containing the image for
138+ the given row of data. This can be a local path, or a remote URL. Remote
139+ formats supported include any URL (``http://`` or ``https://``) or URIs for
140+ AWS S3, Azure, or GCS (i.e. ``s3://``, ``gcs://``).
141+
142+ pointcloud_location (Optional[str]): Required if image_location and
143+ video_frame_location are not present: The remote URL containing the
144+ pointcloud JSON. Remote formats supported include any URL (``http://``
145+ or ``https://``) or URIs for AWS S3, Azure, or GCS (i.e. ``s3://``,
146+ ``gcs://``).
147+
148+ video_frame_location (Optional[str]): Required if image_location and
149+ pointcloud_location are not present: The remote URL containing the
150+ video frame image. Remote formats supported include any URL (``http://``
151+ or ``https://``) or URIs for AWS S3, Azure, or GCS (i.e. ``s3://``,
152+ ``gcs://``).
144153
145154 reference_id (Optional[str]): A user-specified identifier to reference the
146155 item.
147156
148157 metadata (Optional[dict]): Extra information about the particular
149158 dataset item. ints, floats, string values will be made searchable in
150- the query bar by the key in this dict For example, ``{"animal":
159+ the query bar by the key in this dict. For example, ``{"animal":
151160 "dog"}`` will become searchable via ``metadata.animal = "dog"``.
152161
153162 Categorical data can be passed as a string and will be treated
@@ -190,9 +199,10 @@ class DatasetItem: # pylint: disable=R0902
190199 upload_to_scale (Optional[bool]): Set this to false in order to use
191200 `privacy mode <https://nucleus.scale.com/docs/privacy-mode>`_.
192201
193- Setting this to false means the actual data within the item (i.e. the
194- image or pointcloud) will not be uploaded to scale meaning that you can
195- send in links that are only accessible to certain users, and not to Scale.
202+ Setting this to false means the actual data within the item will not be
203+ uploaded to scale meaning that you can send in links that are only accessible
204+ to certain users, and not to Scale. Skipping upload to Scale is currently only
205+ implemented for images.
196206 """
197207
198208 image_location : Optional [str ] = None
@@ -202,23 +212,33 @@ class DatasetItem: # pylint: disable=R0902
202212 metadata : Optional [dict ] = None
203213 pointcloud_location : Optional [str ] = None
204214 upload_to_scale : Optional [bool ] = True
215+ video_frame_location : Optional [str ] = None
205216
206217 def __post_init__ (self ):
207218 assert self .reference_id != "DUMMY_VALUE" , "reference_id is required."
208- assert bool (self .image_location ) != bool (
209- self .pointcloud_location
210- ), "Must specify exactly one of the image_location, pointcloud_location parameters"
211- if self .pointcloud_location and not self .upload_to_scale :
219+ assert (
220+ bool (self .image_location )
221+ + bool (self .pointcloud_location )
222+ + bool (self .video_frame_location )
223+ == 1
224+ ), "Must specify exactly one of the image_location, pointcloud_location, video_frame_location parameters"
225+ if (
226+ self .pointcloud_location or self .video_frame_location
227+ ) and not self .upload_to_scale :
212228 raise NotImplementedError (
213- "Skipping upload to Scale is not currently implemented for pointclouds."
229+ "Skipping upload to Scale is not currently implemented for pointclouds and videos ."
214230 )
215231 self .local = (
216232 is_local_path (self .image_location ) if self .image_location else None
217233 )
218234 self .type = (
219235 DatasetItemType .IMAGE
220236 if self .image_location
221- else DatasetItemType .POINTCLOUD
237+ else (
238+ DatasetItemType .POINTCLOUD
239+ if self .pointcloud_location
240+ else DatasetItemType .VIDEO
241+ )
222242 )
223243 camera_params = (
224244 self .metadata .get (CAMERA_PARAMS_KEY , None )
@@ -238,6 +258,7 @@ def from_json(cls, payload: dict):
238258 return cls (
239259 image_location = image_url ,
240260 pointcloud_location = payload .get (POINTCLOUD_URL_KEY , None ),
261+ video_frame_location = payload .get (VIDEO_FRAME_URL_KEY , None ),
241262 reference_id = payload .get (REFERENCE_ID_KEY , None ),
242263 metadata = payload .get (METADATA_KEY , {}),
243264 upload_to_scale = payload .get (UPLOAD_TO_SCALE_KEY , True ),
@@ -260,13 +281,15 @@ def to_payload(self, is_scene=False) -> dict:
260281 payload [URL_KEY ] = self .image_location
261282 elif self .pointcloud_location :
262283 payload [URL_KEY ] = self .pointcloud_location
284+ elif self .video_frame_location :
285+ payload [URL_KEY ] = self .video_frame_location
263286 payload [TYPE_KEY ] = self .type .value
264287 if self .camera_params :
265288 payload [CAMERA_PARAMS_KEY ] = self .camera_params .to_payload ()
266289 else :
267290 assert (
268291 self .image_location
269- ), "Must specify image_location for DatasetItems not in a LidarScene"
292+ ), "Must specify image_location for DatasetItems not in a LidarScene or VideoScene "
270293 payload [IMAGE_URL_KEY ] = self .image_location
271294 payload [UPLOAD_TO_SCALE_KEY ] = self .upload_to_scale
272295
0 commit comments