---
title: Upload your first scene
slug: api-guide/upload-your-first-scene
docTags: 
createdAt: 2024-12-06T10:04:28.454Z
---

When uploading raw data to the Kognic Platform, you need to do so in the form of a **scene**.
A scene is a collection of data from different sources, such as images, point clouds, and other sensor data.

This guide will walk you through the process of uploading your first scene, either in 2D (camera only) or 3D (camera and LiDAR/RADAR).

## Prerequisites

You have successfully followed the [Quickstart](docId\:b6im5U-kiWn9UkybzJX6D) guide and have the `kognic-io` library installed. For users with access to multiple workspaces you need to [specify a workspace to upload data too.](docId\:xMGM2k-Teox9jtN_otqBM)

## Code examples

:::::ExpandableHeading
### Uploading a 2D scene

To upload a 2D scene, you need to have the raw images available on your local machine (or create a [callback](docId\:yUnPNPwUhZlGG9Wb9Qnk8) for remote data).
It is a two-step process:

1. Build the scene object in Python
2. Upload the scene object to the Kognic Platform

Below follows examples for a few different cases.

::::Tabs
:::Tab{title="One Image"}
```python
from kognic.io.client import KognicIOClient
from kognic.io.model.scene.cameras import Cameras, Frame
from kognic.io.model.scene.resources import Image

# 1. Build scene object
scene = Cameras(
    external_id="my-first-scene",
    frame=Frame(images=[Image(filename="path/to/image.jpg")])
)

# 2. Upload scene
client = KognicIOClient()
scene_uuid = client.cameras.create(scene).scene_uuid
print("Scene uploaded, got uuid:", scene_uuid)
```
:::

:::Tab{title="Multiple Images"}
```python
from kognic.io.client import KognicIOClient
from kognic.io.model.scene.cameras import Cameras, Frame
from kognic.io.model.scene.resources import Image

# 1. Build scene object
scene = Cameras(
    external_id="my-first-scene",
    frame=Frame(
        images=[
          # Sensor names must be unique
          Image(sensor_name = "CAM1", filename="path/to/image1.jpg"),
          Image(sensor_name = "CAM2", filename="path/to/image2.jpg")
        ],
    )
)

# 2. Upload scene
client = KognicIOClient()
scene_uuid = client.cameras.create(scene).scene_uuid
print("Scene uploaded, got uuid:", scene_uuid)
```
:::

:::Tab{title="Sequence"}
```python
from kognic.io.client import KognicIOClient
from kognic.io.model.scene.cameras_sequence import CamerasSequence, Frame
from kognic.io.model.scene.resources import Image

# 1. Build scene object
scene = CamerasSequence(
    external_id="my-first-scene",
    frames=[
        # Relative timestamps must be unique and strictly increasing
        Frame(
            relative_timestamp=0,
            frame_id="1",
            images=[Image(filename="path/to/image1.jpg")],
        ),
        Frame(
            relative_timestamp=100,
            frame_id="2",
            images=[Image(filename="path/to/image2.jpg")],
        ),
        Frame(
            relative_timestamp=200,
            frame_id="3",
            images=[Image(filename="path/to/image3.jpg")],
        ),
    ]
)

# 2. Upload scene
client = KognicIOClient()
scene_uuid = client.cameras_sequence.create(scene).scene_uuid
print("Scene uploaded, got uuid:", scene_uuid)
```
:::
::::


:::::

:::::ExpandableHeading
### Uploading a 2D/3D scene

To upload a 2D/3D scene, you need to have the raw images and point clouds available on your local machine (or create a [callback](docId\:yUnPNPwUhZlGG9Wb9Qnk8) for remote data).
In addition you need to have calibration data available.
It is a three-step process:

1. Create a [calibration](docId:4mFC9aTWcxuPfLNE7V1Iz)&#x20;
2. Build the scene object in Python, referencing the calibration from the previous step
3. Upload the scene object to the Kognic Platform

Below follows examples for a few different cases.

::::Tabs
:::Tab{title="One Image"}
```python
from kognic.io.client import KognicIOClient
from kognic.io.model.calibration import SensorCalibration, PinholeCalibration, LidarCalibration
from kognic.io.model.scene.lidars_and_cameras import LidarsAndCameras, Frame
from kognic.io.model.scene.resources import Image, PointCloud

client = KognicIOClient()

# 1. Create calibration (see calibration section for more details)
sensor_calibration = SensorCalibration(
    external_id = "my-first-calibration",
    calibration = {
        "CAM": PinholeCalibration(...),
        "lidar": LidarCalibration(...)
    }
)
created_calibration = client.calibration.create_calibration(sensor_calibration)

# 2. Build scene object
scene = LidarsAndCameras(
    external_id=f"my-first-scene",
    calibration_id = created_calibration.id,
    frame=Frame(
        images=[Image(sensor_name = "CAM", filename="path/to/image.jpg")],
        point_clouds=[PointCloud(sensor_name = "lidar", filename="path/to/pointcloud.pcd")]
    )
)

# 3. Upload scene
scene_uuid = client.lidars_and_cameras.create(scene).scene_uuid
print("Scene uploaded, got uuid:", scene_uuid)
```
:::

:::Tab{title="Multiple Images"}
```python
from kognic.io.client import KognicIOClient
from kognic.io.model.calibration import SensorCalibration, PinholeCalibration, LidarCalibration
from kognic.io.model.scene.lidars_and_cameras import LidarsAndCameras, Frame
from kognic.io.model.scene.resources import Image, PointCloud

client = KognicIOClient()

# 1. Create calibration (see calibration section for more details)
sensor_calibration = SensorCalibration(
    external_id = "my-first-calibration",
    calibration = {
        "CAM1": PinholeCalibration(...),
        "CAM2": PinholeCalibration(...),
        "lidar": LidarCalibration(...)
    }
)
created_calibration = client.calibration.create_calibration(sensor_calibration)

# 2. Build scene object
scene = LidarsAndCameras(
    external_id="my-first-scene",
    calibration_id = created_calibration.id,
    frame=Frame(
        images=[
          Image(sensor_name = "CAM1", filename="path/to/image1.jpg"),
          Image(sensor_name = "CAM2", filename="path/to/image2.jpg"),
        ],
        point_clouds=[PointCloud(sensor_name = "lidar", filename="path/to/pointcloud.pcd")]
    )
)

# 3. Upload scene
client = KognicIOClient()
scene_uuid = client.lidars_and_cameras.create(scene).scene_uuid
print("Scene uploaded, got uuid:", scene_uuid)
```
:::

:::Tab{title="Sequence"}
```python
from kognic.io.client import KognicIOClient
from kognic.io.model.calibration import SensorCalibration, PinholeCalibration, LidarCalibration
from kognic.io.model.scene.lidars_and_cameras_sequence import LidarsAndCamerasSequence, Frame
from kognic.io.model.scene.resources import Image, PointCloud

client = KognicIOClient()

# 1. Create calibration (see calibration section for more details)
calibration = { "CAM": PinholeCalibration(...), "lidar": LidarCalibration(...) }
sensor_calibration = SensorCalibration(
    external_id = "my-first-calibration",
    calibration = {
        "CAM": PinholeCalibration(...),
        "lidar": LidarCalibration(...)
    }
)
created_calibration = client.calibration.create_calibration(sensor_calibration)

# 2. Build scene object
scene = LidarsAndCamerasSequence(
    external_id="my-first-scene",
    calibration_id = created_calibration.id,
    frames=[
        # Relative timestamps must be unique and strictly increasing
        Frame(
            relative_timestamp=0,
            frame_id="1",
            images=[Image(sensor_name = "CAM", filename="path/to/image1.jpg")],
            point_clouds=[PointCloud(sensor_name = "lidar", filename="path/to/pointcloud1.pcd")]
        ),
        Frame(
            relative_timestamp=100,
            frame_id="2",
            images=[Image(sensor_name = "CAM", filename="path/to/image2.jpg")],
            point_clouds=[PointCloud(sensor_name = "lidar", filename="path/to/pointcloud2.pcd")]
        ),
        Frame(
            relative_timestamp=200,
            frame_id="3",
            images=[Image(sensor_name = "CAM", filename="path/to/image3.jpg")],
            point_clouds=[PointCloud(sensor_name = "lidar", filename="path/to/pointcloud3.pcd")]
        ),
    ]
)

# 3. Upload scene
scene_uuid = client.lidars_and_cameras_sequence.create(scene).scene_uuid
print("Scene uploaded, got uuid:", scene_uuid)
```
:::
::::

:::hint{type="info"}
Multiple point clouds is also supported, but not shown in the examples above since that requires a bit more data. See the [Motion compensation](docId\:rhbSetWlNtFlfO6FMD_1e) section for more details.
:::


:::::

:::ExpandableHeading
### Uploading using ZOD Data

We have exemplar code and a tutorial for uploading scenes using [Zenseact Open Dataset (ZOD)](https://zod.zenseact.com/) data, including 2D, 3D, and aggregated 3D scenes. [Check out the guide document and exemplar code here!](docId\:Cz51X_3_lqOnBcPFtoHmq)

If you have the ZOD data downloaded, and have Kognic API credentials, the examples will run out of the box to create functional scenes!
:::

::::ExpandableHeading
### Creating  scenes from files in a bucket

:::hint{type="info"}
Supported in `kognic-io>=2.5.1`
:::

To use this feature need to have configured a [data integration](docId\:L93_PNIEAhqPK-6j-OuEF) .

If you have your data in a Kognic supported format in a bucket, and have set up a data integration for the bucket, you can create your scene like this, providing paths to files in your bucket instead of downloading and uploading data through the script. This example is a full 2D+3D scene, but can be reduced to a 2D-only scene by removing pointclouds, IMU data and Ego vehicle poses.

Doing it this way uses a newer scene model which does not require you to specify the scene type; it is inferred from the presence of images and pointclouds, and scenes created this way are always 'sequence' type scenes.

A code example and more information can be found at [Scene examples](docId\:HxbEKMQTar-nCcl7pmGxr).

IMU data uploaded this way is expected as JSON in the following format:

```javascript
[
 {
  "postion": {
   "x": 0.0,
   "y": 0.0,
   "z": 0.0
  },
  "rotationQuaternion": {
   "w": 0.0,
   "x": 0.0,
   "y": 0.0,
   "z": 0.0
  }
  "timestamp": <unix timestamp in nano seconds>
 },
 ...
]
```
::::

