""" # -*- coding: utf-8 -*- ----------------------------------------------------------------------------------- # Author: Nguyen Mau Dung # DoC: 2020.08.17 # email: nguyenmaudung93.kstn@gmail.com ----------------------------------------------------------------------------------- # Description: The utils of the kitti dataset """ from __future__ import print_function import os import sys import numpy as np import cv2 src_dir = os.path.dirname(os.path.realpath(__file__)) # while not src_dir.endswith("sfa"): # src_dir = os.path.dirname(src_dir) if src_dir not in sys.path: sys.path.append(src_dir) import config.kitti_config as cnf class Object3d(object): ''' 3d object label ''' def __init__(self, label_file_line): data = label_file_line.split(' ') data[1:] = [float(x) for x in data[1:]] # extract label, truncation, occlusion self.type = data[0] # 'Car', 'Pedestrian', ... self.cls_id = self.cls_type_to_id(self.type) self.truncation = data[1] # truncated pixel ratio [0..1] self.occlusion = int(data[2]) # 0=visible, 1=partly occluded, 2=fully occluded, 3=unknown self.alpha = data[3] # object observation angle [-pi..pi] # extract 2d bounding box in 0-based coordinates self.xmin = data[4] # left self.ymin = data[5] # top self.xmax = data[6] # right self.ymax = data[7] # bottom self.box2d = np.array([self.xmin, self.ymin, self.xmax, self.ymax]) # extract 3d bounding box information self.h = data[8] # box height self.w = data[9] # box width self.l = data[10] # box length (in meters) self.t = (data[11], data[12], data[13]) # location (x,y,z) in camera coord. self.dis_to_cam = np.linalg.norm(self.t) self.ry = data[14] # yaw angle (around Y-axis in camera coordinates) [-pi..pi] self.score = data[15] if data.__len__() == 16 else -1.0 self.level_str = None self.level = self.get_obj_level() def cls_type_to_id(self, cls_type): if cls_type not in cnf.CLASS_NAME_TO_ID.keys(): return -1 return cnf.CLASS_NAME_TO_ID[cls_type] def get_obj_level(self): height = float(self.box2d[3]) - float(self.box2d[1]) + 1 if height >= 40 and self.truncation <= 0.15 and self.occlusion <= 0: self.level_str = 'Easy' return 1 # Easy elif height >= 25 and self.truncation <= 0.3 and self.occlusion <= 1: self.level_str = 'Moderate' return 2 # Moderate elif height >= 25 and self.truncation <= 0.5 and self.occlusion <= 2: self.level_str = 'Hard' return 3 # Hard else: self.level_str = 'UnKnown' return 4 def print_object(self): print('Type, truncation, occlusion, alpha: %s, %d, %d, %f' % \ (self.type, self.truncation, self.occlusion, self.alpha)) print('2d bbox (x0,y0,x1,y1): %f, %f, %f, %f' % \ (self.xmin, self.ymin, self.xmax, self.ymax)) print('3d bbox h,w,l: %f, %f, %f' % \ (self.h, self.w, self.l)) print('3d bbox location, ry: (%f, %f, %f), %f' % \ (self.t[0], self.t[1], self.t[2], self.ry)) def to_kitti_format(self): kitti_str = '%s %.2f %d %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f' \ % (self.type, self.truncation, int(self.occlusion), self.alpha, self.box2d[0], self.box2d[1], self.box2d[2], self.box2d[3], self.h, self.w, self.l, self.t[0], self.t[1], self.t[2], self.ry, self.score) return kitti_str def read_label(label_filename): lines = [line.rstrip() for line in open(label_filename)] objects = [Object3d(line) for line in lines] return objects class Calibration(object): ''' Calibration matrices and utils 3d XYZ in