nutonomy / nuscenes-devkit

The devkit of the nuScenes dataset.
https://www.nuScenes.org
Other
2.24k stars 617 forks source link

Consecutive scenes #900

Closed Alt216 closed 1 year ago

Alt216 commented 1 year ago

Hi, is there a way to get consecutive scenes from the same map?

Also how can we determine the length of a particular scene.

whyekit-motional commented 1 year ago

@Alt216 you could try something like this:

from typing import List

import numpy as np
from nuscenes.nuscenes import NuScenes

def get_scenes_per_log(nusc: NuScenes):
    scenes_per_log = {}
    for scene in nusc.scene:
        log_token = scene['log_token']
        scene_token = scene['token']

        if log_token not in scenes_per_log:
            scenes_per_log[log_token] = [scene_token]
        else:
            scenes_of_log = scenes_per_log[log_token]
            scenes_of_log.append(scene_token)
            scenes_per_log[log_token] = scenes_of_log

    assert len(nusc.scene) == sum([len(scenes) for scenes in scenes_per_log.values()])
    assert len(nusc.log) == len(scenes_per_log)

    return scenes_per_log

def sort_scenes_by_timestamp(nusc: NuScenes, list_of_scene_tokens: List[str]):
    """
    Sort a given list of scene tokens in temporal order. Assume scenes do not overlap within a log 
    (this should be the case in nuScenes).
    """
    # Get the timestamp of each scene's first sample.
    scene_first_sample_timestamps = []
    for scene_token in list_of_scene_tokens:
        scene = nusc.get('scene', scene_token)
        scene_first_sample_token = scene['first_sample_token']
        scene_first_sample = nusc.get('sample', scene_first_sample_token)
        scene_first_sample_timestamps.append(scene_first_sample['timestamp'])

    # Sort the scenes based on the timestamp of their respective first samples.
    sorted_idxs = np.argsort(scene_first_sample_timestamps)
    return [list_of_scene_tokens[i] for i in sorted_idxs]

nusc_ = NuScenes(version='v1.0-mini', dataroot='/data/sets/nuscenes', verbose=False)

some_scenes_per_log = get_scenes_per_log(nusc_)

some_scenes_per_log_sorted = {}
for log_token, scene_tokens_of_log in some_scenes_per_log.items():
    some_scenes_per_log_sorted[log_token] = sort_scenes_by_timestamp(nusc_, scene_tokens_of_log)

print(some_scenes_per_log_sorted)

The above code snippet will return a dictionary in which each key is a log token, and each value is a list of scene tokens (sorted in temporal order) which belong to the corresponding log token, e.g.:

{
    "7e25a2c8ea1f41c5b0da1e69ecfa71a2": [
        "cc8c0bf57f984915a77078b10eb33198"
    ],
    "53cf9c55dd8644bea67b9f009fc1ee38": [
        "fcbccedd61424f1b85dcbf8f897f9754"
    ],
    "881dd2f8aaec49b681eb54be5bf3b3e2": [
        "6f83169d067343658251f72e1dd17dbc"
    ],
    "6f7fe59adf984e55a82571ab4f17e4e2": [
        "bebf5f5b2a674631ab5c88fd1aa9e87a"
    ],
    "3a43824b84534c98bda1d07548db5817": [
        "2fc3753772e241f2ab2cd16a784cc680"
    ],
    "8ff48ad1df8e4966a2151730c92b7f3c": [
        "c5224b9b454b4ded9b5d2d2634bbda8a"
    ],
    "5bd40b613ac740cd9dbacdfbc3d68201": [
        "325cef682f064c55a255f2625c533b75"
    ],
    "8fefc430cbfa4c2191978c0df302eb98": [
        "d25718445d89453381c659b9c8734939",
        "de7d80a1f5fb4c3e82ce8a4f213b450a",
        "e233467e827140efa4b42d2b4c435855"
    ]
}

To get the length of each scene, you could simply get the difference between the timestamp of the last sample in a scene, and the first sample in the same scene (I'll leave that as an exercise for you to implement the code)