|
|
from typing import Type |
|
|
|
|
|
import numpy as np |
|
|
|
|
|
import utils.transform as box_transform |
|
|
import utils.rotation as object_rotation |
|
|
|
|
|
|
|
|
class Box3D: |
|
|
def __init__( |
|
|
self, |
|
|
x=None, |
|
|
y=None, |
|
|
z=None, |
|
|
h=None, |
|
|
w=None, |
|
|
l=None, |
|
|
pitch=None, |
|
|
yaw=None, |
|
|
roll=None, |
|
|
s=None, |
|
|
): |
|
|
self.x = x |
|
|
self.y = y |
|
|
self.z = z |
|
|
self.h = h |
|
|
self.w = w |
|
|
self.l = l |
|
|
self.pitch = pitch |
|
|
self.yaw = yaw |
|
|
self.roll = roll |
|
|
self.s = s |
|
|
self.corners_3d_cam = None |
|
|
|
|
|
def __str__(self): |
|
|
return "x: {}, y: {}, z: {}, heading: {}, length: {}, width: {}, height: {}, score: {}".format( |
|
|
self.x, self.y, self.z, self.yaw, self.l, self.w, self.h, self.s |
|
|
) |
|
|
|
|
|
@classmethod |
|
|
def bbox2dict(cls, bbox): |
|
|
return { |
|
|
"center_x": bbox.x, |
|
|
"center_y": bbox.y, |
|
|
"center_z": bbox.z, |
|
|
"height": bbox.h, |
|
|
"width": bbox.w, |
|
|
"length": bbox.l, |
|
|
"yaw": bbox.yaw, |
|
|
} |
|
|
|
|
|
@classmethod |
|
|
def bbox2array(cls, bbox): |
|
|
if bbox.s is None: |
|
|
return np.array([bbox.x, bbox.y, bbox.z, bbox.yaw, bbox.l, bbox.w, bbox.h]) |
|
|
else: |
|
|
return np.array( |
|
|
[bbox.x, bbox.y, bbox.z, bbox.yaw, bbox.l, bbox.w, bbox.h, bbox.s] |
|
|
) |
|
|
|
|
|
@classmethod |
|
|
def bbox2array_raw(cls, bbox): |
|
|
if bbox.s is None: |
|
|
return np.array([bbox.h, bbox.w, bbox.l, bbox.x, bbox.y, bbox.z, bbox.yaw]) |
|
|
else: |
|
|
return np.array( |
|
|
[bbox.h, bbox.w, bbox.l, bbox.x, bbox.y, bbox.z, bbox.yaw, bbox.s] |
|
|
) |
|
|
|
|
|
@classmethod |
|
|
def array2bbox_xyzlwhyaw(cls, data): |
|
|
|
|
|
|
|
|
bbox = Box3D() |
|
|
bbox.x, bbox.y, bbox.z, bbox.l, bbox.w, bbox.h, bbox.yaw = data[:7] |
|
|
if len(data) == 8: |
|
|
bbox.s = data[-1] |
|
|
return bbox |
|
|
|
|
|
@classmethod |
|
|
def array2bbox_raw(cls, data): |
|
|
|
|
|
|
|
|
bbox = Box3D() |
|
|
bbox.h, bbox.w, bbox.l, bbox.x, bbox.y, bbox.z, bbox.yaw = data[:7] |
|
|
if len(data) == 8: |
|
|
bbox.s = data[-1] |
|
|
return bbox |
|
|
|
|
|
@classmethod |
|
|
def array2bbox(cls, data): |
|
|
|
|
|
|
|
|
bbox = Box3D() |
|
|
bbox.x, bbox.y, bbox.z, bbox.yaw, bbox.l, bbox.w, bbox.h = data[:7] |
|
|
if len(data) == 8: |
|
|
bbox.s = data[-1] |
|
|
return bbox |
|
|
|
|
|
@classmethod |
|
|
def array2bbox_9dof( |
|
|
cls, location: np.ndarray, rotation: np.ndarray, size: np.ndarray |
|
|
): |
|
|
|
|
|
|
|
|
bbox = Box3D() |
|
|
bbox.x, bbox.y, bbox.z = location |
|
|
bbox.pitch, bbox.ry, bbox.roll = rotation |
|
|
bbox.l, bbox.w, bbox.h = size |
|
|
|
|
|
|
|
|
bbox.corners_3d_cam: np.ndarray = box_transform.get_box_in_world( |
|
|
location, rotation, size |
|
|
) |
|
|
|
|
|
return bbox |
|
|
|
|
|
@classmethod |
|
|
def box2corners3d_lidar(cls, bbox): |
|
|
"""Convert the box to the 8 corners in the lidar coordinate |
|
|
|
|
|
Note that carla lidar coordinate is |
|
|
+x -> left |
|
|
+y -> front |
|
|
+z -> up |
|
|
4 -------- 5 |
|
|
/| /| |
|
|
7 -------- 6 . |
|
|
| | | | |
|
|
. 0 -------- 1 |
|
|
|/ |/ |
|
|
3 -------- 2 |
|
|
""" |
|
|
|
|
|
|
|
|
size = np.array([bbox.l, bbox.w, bbox.h]) |
|
|
box3d: np.ndarray = box_transform.create_bb_points(size) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
R: np.ndarray = object_rotation.rotz(bbox.yaw) |
|
|
|
|
|
box3d = np.dot(R, box3d[:, :3].transpose()) |
|
|
|
|
|
|
|
|
box3d[0, :] = box3d[0, :] + bbox.x |
|
|
box3d[1, :] = box3d[1, :] + bbox.y |
|
|
box3d[2, :] = box3d[2, :] + bbox.z |
|
|
|
|
|
|
|
|
box3d = box3d.transpose() |
|
|
box3d = np.concatenate((box3d, np.ones((8, 1))), axis=1) |
|
|
|
|
|
return box3d |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|