-
Notifications
You must be signed in to change notification settings - Fork 67
/
make_nuscenes_labels.py
162 lines (106 loc) · 5.25 KB
/
make_nuscenes_labels.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import os
import sys
import numpy as np
from PIL import Image
from tqdm import tqdm
from collections import OrderedDict
from shapely.strtree import STRtree
from nuscenes import NuScenes
from nuscenes.map_expansion.map_api import NuScenesMap
sys.path.append(os.path.abspath(os.path.join(__file__, '../..')))
from src.utils.configs import get_default_configuration
from src.data.utils import get_visible_mask, get_occlusion_mask, transform, \
encode_binary_labels
import src.data.nuscenes.utils as nusc_utils
def process_scene(nuscenes, map_data, scene, config):
# Get the map corresponding to the current sample data
log = nuscenes.get('log', scene['log_token'])
scene_map_data = map_data[log['location']]
# Iterate over samples
first_sample_token = scene['first_sample_token']
for sample in nusc_utils.iterate_samples(nuscenes, first_sample_token):
process_sample(nuscenes, scene_map_data, sample, config)
def process_sample(nuscenes, map_data, sample, config):
# Load the lidar point cloud associated with this sample
lidar_data = nuscenes.get('sample_data', sample['data']['LIDAR_TOP'])
lidar_pcl = nusc_utils.load_point_cloud(nuscenes, lidar_data)
# Transform points into world coordinate system
lidar_transform = nusc_utils.get_sensor_transform(nuscenes, lidar_data)
lidar_pcl = transform(lidar_transform, lidar_pcl)
# Iterate over sample data
for camera in nusc_utils.CAMERA_NAMES:
sample_data = nuscenes.get('sample_data', sample['data'][camera])
process_sample_data(nuscenes, map_data, sample_data, lidar_pcl, config)
def process_sample_data(nuscenes, map_data, sample_data, lidar, config):
# Render static road geometry masks
map_masks = nusc_utils.get_map_masks(nuscenes,
map_data,
sample_data,
config.map_extents,
config.map_resolution)
# Render dynamic object masks
obj_masks = nusc_utils.get_object_masks(nuscenes,
sample_data,
config.map_extents,
config.map_resolution)
masks = np.concatenate([map_masks, obj_masks], axis=0)
# Ignore regions of the BEV which are outside the image
sensor = nuscenes.get('calibrated_sensor',
sample_data['calibrated_sensor_token'])
intrinsics = np.array(sensor['camera_intrinsic'])
masks[-1] |= ~get_visible_mask(intrinsics, sample_data['width'],
config.map_extents, config.map_resolution)
# Transform lidar points into camera coordinates
cam_transform = nusc_utils.get_sensor_transform(nuscenes, sample_data)
cam_points = transform(np.linalg.inv(cam_transform), lidar)
masks[-1] |= get_occlusion_mask(cam_points, config.map_extents,
config.map_resolution)
# Encode masks as integer bitmask
labels = encode_binary_labels(masks)
# Save outputs to disk
output_path = os.path.join(os.path.expandvars(config.label_root),
sample_data['token'] + '.png')
Image.fromarray(labels.astype(np.int32), mode='I').save(output_path)
def load_map_data(dataroot, location):
# Load the NuScenes map object
nusc_map = NuScenesMap(dataroot, location)
map_data = OrderedDict()
for layer in nusc_utils.STATIC_CLASSES:
# Retrieve all data associated with the current layer
records = getattr(nusc_map, layer)
polygons = list()
# Drivable area records can contain multiple polygons
if layer == 'drivable_area':
for record in records:
# Convert each entry in the record into a shapely object
for token in record['polygon_tokens']:
poly = nusc_map.extract_polygon(token)
if poly.is_valid:
polygons.append(poly)
else:
for record in records:
# Convert each entry in the record into a shapely object
poly = nusc_map.extract_polygon(record['polygon_token'])
if poly.is_valid:
polygons.append(poly)
# Store as an R-Tree for fast intersection queries
map_data[layer] = STRtree(polygons)
return map_data
if __name__ == '__main__':
# Load the default configuration
config = get_default_configuration()
config.merge_from_file('configs/datasets/nuscenes.yml')
# Load NuScenes dataset
dataroot = os.path.expandvars(config.dataroot)
nuscenes = NuScenes(config.nuscenes_version, dataroot)
# Preload NuScenes map data
map_data = { location : load_map_data(dataroot, location)
for location in nusc_utils.LOCATIONS }
# Create a directory for the generated labels
output_root = os.path.expandvars(config.label_root)
os.makedirs(output_root, exist_ok=True)
# print(nuscenes.scene)
# Iterate over NuScene scenes
print("\nGenerating labels...")
for scene in tqdm(nuscenes.scene):
process_scene(nuscenes, map_data, scene, config)