127 lines
4.7 KiB
Python
127 lines
4.7 KiB
Python
|
# Copyright (c) 2018 NVIDIA Corporation. All rights reserved.
|
||
|
# This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
|
||
|
# https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
|
||
|
|
||
|
from enum import IntEnum, unique
|
||
|
import numpy as np
|
||
|
import cv2
|
||
|
|
||
|
# Related to the object's local coordinate system
|
||
|
# @unique
|
||
|
class CuboidVertexType(IntEnum):
|
||
|
FrontTopRight = 0
|
||
|
FrontTopLeft = 1
|
||
|
FrontBottomLeft = 2
|
||
|
FrontBottomRight = 3
|
||
|
RearTopRight = 4
|
||
|
RearTopLeft = 5
|
||
|
RearBottomLeft = 6
|
||
|
RearBottomRight = 7
|
||
|
Center = 8
|
||
|
TotalCornerVertexCount = 8 # Corner vertexes doesn't include the center point
|
||
|
TotalVertexCount = 9
|
||
|
|
||
|
|
||
|
# List of the vertex indexes in each line edges of the cuboid
|
||
|
CuboidLineIndexes = [
|
||
|
# Front face
|
||
|
[CuboidVertexType.FrontTopLeft, CuboidVertexType.FrontTopRight],
|
||
|
[CuboidVertexType.FrontTopRight, CuboidVertexType.FrontBottomRight],
|
||
|
[CuboidVertexType.FrontBottomRight, CuboidVertexType.FrontBottomLeft],
|
||
|
[CuboidVertexType.FrontBottomLeft, CuboidVertexType.FrontTopLeft],
|
||
|
# Back face
|
||
|
[CuboidVertexType.RearTopLeft, CuboidVertexType.RearTopRight],
|
||
|
[CuboidVertexType.RearTopRight, CuboidVertexType.RearBottomRight],
|
||
|
[CuboidVertexType.RearBottomRight, CuboidVertexType.RearBottomLeft],
|
||
|
[CuboidVertexType.RearBottomLeft, CuboidVertexType.RearTopLeft],
|
||
|
# Left face
|
||
|
[CuboidVertexType.FrontBottomLeft, CuboidVertexType.RearBottomLeft],
|
||
|
[CuboidVertexType.FrontTopLeft, CuboidVertexType.RearTopLeft],
|
||
|
# Right face
|
||
|
[CuboidVertexType.FrontBottomRight, CuboidVertexType.RearBottomRight],
|
||
|
[CuboidVertexType.FrontTopRight, CuboidVertexType.RearTopRight],
|
||
|
]
|
||
|
|
||
|
|
||
|
# ========================= Cuboid3d =========================
|
||
|
class Cuboid3d:
|
||
|
"""This class contains a 3D cuboid."""
|
||
|
|
||
|
# Create a box with a certain size
|
||
|
def __init__(
|
||
|
self,
|
||
|
size3d=[1.0, 1.0, 1.0],
|
||
|
center_location=[0, 0, 0],
|
||
|
coord_system=None,
|
||
|
parent_object=None,
|
||
|
):
|
||
|
|
||
|
# NOTE: This local coordinate system is similar
|
||
|
# to the intrinsic transform matrix of a 3d object
|
||
|
self.center_location = center_location
|
||
|
self.coord_system = coord_system
|
||
|
self.size3d = size3d
|
||
|
self._vertices = [0, 0, 0] * CuboidVertexType.TotalVertexCount
|
||
|
|
||
|
self.generate_vertexes()
|
||
|
|
||
|
def get_vertex(self, vertex_type):
|
||
|
"""Returns the location of a vertex.
|
||
|
|
||
|
Args:
|
||
|
vertex_type: enum of type CuboidVertexType
|
||
|
|
||
|
Returns:
|
||
|
Numpy array(3) - Location of the vertex type in the cuboid
|
||
|
"""
|
||
|
return self._vertices[vertex_type]
|
||
|
|
||
|
def get_vertices(self):
|
||
|
return self._vertices
|
||
|
|
||
|
def generate_vertexes(self):
|
||
|
width, height, depth = self.size3d
|
||
|
|
||
|
# By default just use the normal OpenCV coordinate system
|
||
|
if self.coord_system is None:
|
||
|
cx, cy, cz = self.center_location
|
||
|
# X axis point to the right
|
||
|
right = cx + width / 2.0
|
||
|
left = cx - width / 2.0
|
||
|
# Y axis point downward
|
||
|
top = cy - height / 2.0
|
||
|
bottom = cy + height / 2.0
|
||
|
# Z axis point forward
|
||
|
front = cz + depth / 2.0
|
||
|
rear = cz - depth / 2.0
|
||
|
|
||
|
# List of 8 vertices of the box
|
||
|
self._vertices = [
|
||
|
[right, top, front], # Front Top Right
|
||
|
[left, top, front], # Front Top Left
|
||
|
[left, bottom, front], # Front Bottom Left
|
||
|
[right, bottom, front], # Front Bottom Right
|
||
|
[right, top, rear], # Rear Top Right
|
||
|
[left, top, rear], # Rear Top Left
|
||
|
[left, bottom, rear], # Rear Bottom Left
|
||
|
[right, bottom, rear], # Rear Bottom Right
|
||
|
self.center_location, # Center
|
||
|
]
|
||
|
else:
|
||
|
sx, sy, sz = self.size3d
|
||
|
forward = np.array(self.coord_system.forward, dtype=float) * sy * 0.5
|
||
|
up = np.array(self.coord_system.up, dtype=float) * sz * 0.5
|
||
|
right = np.array(self.coord_system.right, dtype=float) * sx * 0.5
|
||
|
center = np.array(self.center_location, dtype=float)
|
||
|
self._vertices = [
|
||
|
center + forward + up + right, # Front Top Right
|
||
|
center + forward + up - right, # Front Top Left
|
||
|
center + forward - up - right, # Front Bottom Left
|
||
|
center + forward - up + right, # Front Bottom Right
|
||
|
center - forward + up + right, # Rear Top Right
|
||
|
center - forward + up - right, # Rear Top Left
|
||
|
center - forward - up - right, # Rear Bottom Left
|
||
|
center - forward - up + right, # Rear Bottom Right
|
||
|
self.center_location, # Center
|
||
|
]
|