Source code for d3d.dataset.kitti360.utils

import xml.etree.ElementTree as ET
from collections import defaultdict, namedtuple
from enum import IntFlag
from pathlib import Path

import numpy as np
from addict import Dict as edict

[docs]class Kitti360Class(IntFlag): # XXX: actually is CityscapeClass """ Categories and attributes of an annotation in KITTI-360 dataset. The ids are encoded into 2bytes integer:: 0xFF │└: category └─: label """ void = 0x00 unlabeled = 0x10 ego_vehicle = 0x20 rectification_border = 0x30 out_of_roi = 0x40 static = 0x50 dynamic = 0x60 ground = 0x70 unknown_construction = 0x80 unknown_vehicle = 0x90 unknown_object = 0xa0 flat = 0x01 road = 0x11 sidewalk = 0x21 parking = 0x31 rail_track = 0x41 construction = 0x02 building = 0x12 wall = 0x22 fence = 0x32 guard_rail = 0x42 bridge = 0x52 tunnel = 0x62 garage = 0x70 gate = 0x80 stop = 0x90 object_ = 0x03 pole = 0x13 polegroup = 0x23 traffic_light = 0x33 traffic_sign = 0x43 smallpole = 0x50 lamp = 0x60 trash_bin = 0x70 vending_machine = 0x80 box = 0x90 nature = 0x04 vegetation = 0x14 terrain = 0x24 sky = 0x05 human = 0x06 person = 0x16 rider = 0x26 vehicle = 0x07 car = 0x17 truck = 0x27 bus = 0x37 caravan = 0x47 trailer = 0x57 train = 0x67 motorcycle = 0x77 bicycle = 0x87 license_plate = 0x97
# Following definitions are from https://github.com/autonomousvision/kitti360Scripts/blob/master/kitti360scripts/helpers/labels.py _Label = namedtuple( 'Label' , [ 'name' , # The identifier of this label, e.g. 'car', 'person', ... . # We use them to uniquely name a class 'id' , # An integer ID that is associated with this label. # The IDs are used to represent the label in ground truth images # An ID of -1 means that this label does not have an ID and thus # is ignored when creating ground truth images (e.g. license plate). # Do not modify these IDs, since exactly these IDs are expected by the # evaluation server. 'kittiId' , # An integer ID that is associated with this label for KITTI-360 # NOT FOR RELEASING 'trainId' , # Feel free to modify these IDs as suitable for your method. Then create # ground truth images with train IDs, using the tools provided in the # 'preparation' folder. However, make sure to validate or submit results # to our evaluation server using the regular IDs above! # For trainIds, multiple labels might have the same ID. Then, these labels # are mapped to the same class in the ground truth images. For the inverse # mapping, we use the label that is defined first in the list below. # For example, mapping all void-type classes to the same ID in training, # might make sense for some approaches. # Max value is 255! 'category' , # The name of the category that this label belongs to 'categoryId' , # The ID of this category. Used to create ground truth images # on category level. 'hasInstances', # Whether this label distinguishes between single instances or not 'ignoreInEval', # Whether pixels having this class as ground truth label are ignored # during evaluations or not 'color' , # The color of this label ] ) _labels = [ # name id kittiId, trainId category catId hasInstances ignoreInEval color _Label( Kitti360Class.unlabeled , 0 , -1 , 255 , "void" , 0 , False , True , ( 0, 0, 0) ), _Label( Kitti360Class.ego_vehicle , 1 , -1 , 255 , "void" , 0 , False , True , ( 0, 0, 0) ), _Label( Kitti360Class.rectification_border , 2 , -1 , 255 , "void" , 0 , False , True , ( 0, 0, 0) ), _Label( Kitti360Class.out_of_roi , 3 , -1 , 255 , "void" , 0 , False , True , ( 0, 0, 0) ), _Label( Kitti360Class.static , 4 , -1 , 255 , "void" , 0 , False , True , ( 0, 0, 0) ), _Label( Kitti360Class.dynamic , 5 , -1 , 255 , "void" , 0 , False , True , (111, 74, 0) ), _Label( Kitti360Class.ground , 6 , -1 , 255 , "void" , 0 , False , True , ( 81, 0, 81) ), _Label( Kitti360Class.road , 7 , 1 , 0 , "flat" , 1 , False , False , (128, 64,128) ), _Label( Kitti360Class.sidewalk , 8 , 3 , 1 , "flat" , 1 , False , False , (244, 35,232) ), _Label( Kitti360Class.parking , 9 , 2 , 255 , "flat" , 1 , False , True , (250,170,160) ), _Label( Kitti360Class.rail_track , 10 , 10, 255 , "flat" , 1 , False , True , (230,150,140) ), _Label( Kitti360Class.building , 11 , 11, 2 , "construction" , 2 , True , False , ( 70, 70, 70) ), _Label( Kitti360Class.wall , 12 , 7 , 3 , "construction" , 2 , False , False , (102,102,156) ), _Label( Kitti360Class.fence , 13 , 8 , 4 , "construction" , 2 , False , False , (190,153,153) ), _Label( Kitti360Class.guard_rail , 14 , 30, 255 , "construction" , 2 , False , True , (180,165,180) ), _Label( Kitti360Class.bridge , 15 , 31, 255 , "construction" , 2 , False , True , (150,100,100) ), _Label( Kitti360Class.tunnel , 16 , 32, 255 , "construction" , 2 , False , True , (150,120, 90) ), _Label( Kitti360Class.pole , 17 , 21, 5 , "object" , 3 , True , False , (153,153,153) ), _Label( Kitti360Class.polegroup , 18 , -1 , 255 , "object" , 3 , False , True , (153,153,153) ), _Label( Kitti360Class.traffic_light , 19 , 23, 6 , "object" , 3 , True , False , (250,170, 30) ), _Label( Kitti360Class.traffic_sign , 20 , 24, 7 , "object" , 3 , True , False , (220,220, 0) ), _Label( Kitti360Class.vegetation , 21 , 5 , 8 , "nature" , 4 , False , False , (107,142, 35) ), _Label( Kitti360Class.terrain , 22 , 4 , 9 , "nature" , 4 , False , False , (152,251,152) ), _Label( Kitti360Class.sky , 23 , 9 , 10 , "sky" , 5 , False , False , ( 70,130,180) ), _Label( Kitti360Class.person , 24 , 19, 11 , "human" , 6 , True , False , (220, 20, 60) ), _Label( Kitti360Class.rider , 25 , 20, 12 , "human" , 6 , True , False , (255, 0, 0) ), _Label( Kitti360Class.car , 26 , 13, 13 , "vehicle" , 7 , True , False , ( 0, 0,142) ), _Label( Kitti360Class.truck , 27 , 14, 14 , "vehicle" , 7 , True , False , ( 0, 0, 70) ), _Label( Kitti360Class.bus , 28 , 34, 15 , "vehicle" , 7 , True , False , ( 0, 60,100) ), _Label( Kitti360Class.caravan , 29 , 16, 255 , "vehicle" , 7 , True , True , ( 0, 0, 90) ), _Label( Kitti360Class.trailer , 30 , 15, 255 , "vehicle" , 7 , True , True , ( 0, 0,110) ), _Label( Kitti360Class.train , 31 , 33, 16 , "vehicle" , 7 , True , False , ( 0, 80,100) ), _Label( Kitti360Class.motorcycle , 32 , 17, 17 , "vehicle" , 7 , True , False , ( 0, 0,230) ), _Label( Kitti360Class.bicycle , 33 , 18, 18 , "vehicle" , 7 , True , False , (119, 11, 32) ), _Label( Kitti360Class.garage , 34 , 12, 2 , "construction" , 2 , True , False , ( 64,128,128) ), _Label( Kitti360Class.gate , 35 , 6 , 4 , "construction" , 2 , False , False , (190,153,153) ), _Label( Kitti360Class.stop , 36 , 29, 255 , "construction" , 2 , True , True , (150,120, 90) ), _Label( Kitti360Class.smallpole , 37 , 22, 5 , "object" , 3 , True , False , (153,153,153) ), _Label( Kitti360Class.lamp , 38 , 25, 255 , "object" , 3 , True , False , (0, 64, 64) ), _Label( Kitti360Class.trash_bin , 39 , 26, 255 , "object" , 3 , True , False , (0, 128,192) ), _Label( Kitti360Class.vending_machine , 40 , 27, 255 , "object" , 3 , True , False , (128, 64, 0) ), _Label( Kitti360Class.box , 41 , 28, 255 , "object" , 3 , True , False , (64, 64,128) ), _Label( Kitti360Class.unknown_construction , 42 , 35, 255 , "void" , 0 , False , True , (102, 0, 0) ), _Label( Kitti360Class.unknown_vehicle , 43 , 36, 255 , "void" , 0 , False , True , ( 51, 0, 51) ), _Label( Kitti360Class.unknown_object , 44 , 37, 255 , "void" , 0 , False , True , ( 32, 32, 32) ), _Label( Kitti360Class.license_plate , -1 , -1, -1 , "vehicle" , 7 , False , True , ( 0, 0,142) ), ] kittiId2label = { label.kittiId : label for label in _labels } id2label = { label.id : label for label in _labels } def load_sick_scan(basepath, file): if isinstance(basepath, (str, Path)): scan = np.fromfile(Path(basepath, file), dtype=np.float32) else: with basepath.open(str(file)) as fin: buffer = fin.read() scan = np.frombuffer(buffer, dtype=np.float32) return scan.reshape((-1, 2)) def load_bboxes(basepath, file): """ :param poses: if poses are provided, static objects will be filtered if it's out of visible_range """ from intervaltree import Interval, IntervalTree if isinstance(basepath, (str, Path)): tree = ET.parse(Path(basepath, file)) root = tree.getroot() else: # assume ZipFile object root = ET.fromstring(basepath.read(str(file))) frame_mapping = [] object_list = [] for idx, child in enumerate(root): if not child.tag.startswith("object"): continue obj = edict() for prop in child: if prop.tag == "transform": obj.transform = np.fromstring(prop.find("data").text, dtype=float, sep=" ").reshape(4, 4) elif prop.tag == "vertices": obj.vertices = np.fromstring(prop.find("data").text, dtype=float, sep=" ").reshape(-1, 3) elif prop.tag == "faces": obj.faces = np.fromstring(prop.find("data").text, dtype=int, sep=" ").reshape(-1, 3) elif prop.tag not in ["label", "category"]: obj[prop.tag] = int(prop.text) else: obj[prop.tag] = prop.text object_list.append(obj) if obj.dynamic: frame_mapping.append(Interval(obj.timestamp, obj.timestamp+1, idx)) else: frame_mapping.append(Interval(obj.start_frame, obj.end_frame, idx)) return object_list, IntervalTree(frame_mapping)