예제 #1
0
def get_min_max_3d_box_corners(boxes, name=None):
    """Given a set of upright boxes, return its 2 min and max corner points

  Args:
    boxes: tf Tensor [N, 7]. The inner dims are [center{x,y,z}, length, width,
      height, heading].
    name: the name scope.

  Returns:
    corners: tf Tensor [N, 8, 3].
  """
    with tf.compat.v1.name_scope(name, 'GetMinMax3dBoxCorners', [boxes]):
        center_x, center_y, center_z, length, width, height, heading = tf.unstack(
            boxes, axis=-1)

        # [N, 3, 3]
        rotation = transform_utils.get_yaw_rotation(heading)
        # [N, 3]
        translation = tf.stack([center_x, center_y, center_z], axis=-1)

        l2 = length * 0.5
        w2 = width * 0.5
        h2 = height * 0.5

        # [N, 2, 3]
        corners = tf.reshape(tf.stack([-l2, -w2, -h2, l2, w2, h2], axis=-1),
                             [-1, 2, 3])
        # [N, 2, 3]
        corners = tf.einsum('nij,nkj->nki', rotation,
                            corners) + tf.expand_dims(translation, axis=-2)
        return corners
def is_within_box_3d(point, box, name=None):
    center = box[:, 0:3]  # xc,yc,zc
    dim = box[:, 3:6]  # L,W,H
    heading = box[:, 6]
    # [M, 3, 3]
    rotation = transform_utils.get_yaw_rotation(heading)  # rotation matrix
    # [M, 4, 4]
    transform = transform_utils.get_transform(rotation,
                                              center)  # transform matrix
    # [M, 4, 4]
    transform = tf.linalg.inv(transform)
    # [M, 3, 3]
    rotation = transform[:, 0:3, 0:3]
    # [M, 3]
    translation = transform[:, 0:3, 3]  # translation matrix

    # [N, M, 3]
    point_in_box_frame = tf.einsum('nj,mij->nmi', point,
                                   rotation) + translation  #
    # [N, M, 3]
    point_in_box = tf.logical_and(point_in_box_frame <= dim * 0.5,
                                  point_in_box_frame >= -dim * 0.5)
    # [N, M]
    point_in_box = tf.cast(tf.reduce_prod(input_tensor=tf.cast(point_in_box,
                                                               dtype=tf.uint8),
                                          axis=-1),
                           dtype=tf.bool)
    return point_in_box
예제 #3
0
    def test_transform_point_among_frames(self):
        p = tf.constant([[1.0, 0, 0]], dtype=tf.float32)
        from_frame_pose = transform_utils.get_transform(
            transform_utils.get_yaw_rotation(math.pi * 0.5),
            tf.constant([0.0, 0.0, 2.0], dtype=tf.float32))
        to_frame_pose = transform_utils.get_transform(
            transform_utils.get_yaw_rotation(math.pi * 0.1),
            tf.constant([0.0, 0.0, 0.0], dtype=tf.float32))

        p = p[tf.newaxis, tf.newaxis, tf.newaxis, ...]
        from_frame_pose = from_frame_pose[tf.newaxis, tf.newaxis, tf.newaxis,
                                          ...]
        to_frame_pose = to_frame_pose[tf.newaxis, tf.newaxis, tf.newaxis, ...]
        pp = box_utils.transform_point(p, from_frame_pose, to_frame_pose)

        with self.test_session():
            self.assertAllClose(
                pp[0, 0, 0, ...].eval(),
                [[math.cos(math.pi * 0.4),
                  math.sin(math.pi * 0.4), 2.0]])
예제 #4
0
    def test_transform_box_among_frames(self):
        b = tf.constant([[1.0, 0, 0, 2.0, 2.0, 2.0, math.pi * 0.1]],
                        dtype=tf.float32)
        from_frame_pose = transform_utils.get_transform(
            transform_utils.get_yaw_rotation(math.pi * 0.5),
            tf.constant([0.0, 0.0, 1.0], dtype=tf.float32))
        to_frame_pose = transform_utils.get_transform(
            transform_utils.get_yaw_rotation(math.pi * 0.25),
            tf.constant([0.0, 0.0, 0.0], dtype=tf.float32))

        b = b[tf.newaxis, tf.newaxis, tf.newaxis, ...]
        from_frame_pose = from_frame_pose[tf.newaxis, tf.newaxis, tf.newaxis,
                                          ...]
        to_frame_pose = to_frame_pose[tf.newaxis, tf.newaxis, tf.newaxis, ...]

        bb = box_utils.transform_box(b, from_frame_pose, to_frame_pose)

        with self.test_session():
            self.assertAllClose(bb[0, 0, 0, ...].eval(), [[
                math.cos(math.pi * 0.25),
                math.sin(math.pi * 0.25), 1.0, 2.0, 2.0, 2.0, math.pi * 0.35
            ]])
예제 #5
0
def is_within_box_3d(point, box, name=None):
    """Checks whether a point is in a 3d box given a set of points and boxes.

  Args:
    point: [N, 3] tensor. Inner dims are: [x, y, z].
    box: [M, 7] tensor. Inner dims are: [center_x, center_y, center_z, length,
      width, height, heading].
    name: tf name scope.

  Returns:
    point_in_box; [N, M] boolean tensor.
  """

    with tf.compat.v1.name_scope(name, 'IsWithinBox3D', [point, box]):
        center = box[:, 0:3]
        dim = box[:, 3:6]
        heading = box[:, 6]
        # [M, 3, 3]
        rotation = transform_utils.get_yaw_rotation(heading)
        # [M, 4, 4]
        transform = transform_utils.get_transform(rotation, center)
        # [M, 4, 4]
        transform = tf.linalg.inv(transform)
        # [M, 3, 3]
        rotation = transform[:, 0:3, 0:3]
        # [M, 3]
        translation = transform[:, 0:3, 3]

        # [N, M, 3]
        point_in_box_frame = tf.einsum('nj,mij->nmi', point,
                                       rotation) + translation
        # [N, M, 3]
        point_in_box = tf.logical_and(
            tf.logical_and(point_in_box_frame <= dim * 0.5,
                           point_in_box_frame >= -dim * 0.5),
            tf.reduce_all(tf.not_equal(dim, 0), axis=-1, keepdims=True))
        # [N, M]
        point_in_box = tf.cast(tf.reduce_prod(input_tensor=tf.cast(
            point_in_box, dtype=tf.uint8),
                                              axis=-1),
                               dtype=tf.bool)

        return point_in_box
예제 #6
0
def get_upright_3d_box_corners(boxes, name=None):
    """Given a set of upright boxes, return its 8 corners.

  Given a set of boxes, returns its 8 corners. The corners are ordered layers
  (bottom, top) first and then counter-clockwise within each layer.

  Args:
    boxes: tf Tensor [N, 7]. The inner dims are [center{x,y,z}, length, width,
      height, heading].
    name: the name scope.

  Returns:
    corners: tf Tensor [N, 8, 3].
  """
    with tf.compat.v1.name_scope(name, 'GetUpright3dBoxCorners', [boxes]):
        center_x, center_y, center_z, length, width, height, heading = tf.unstack(
            boxes, axis=-1)

        # [N, 3, 3]
        rotation = transform_utils.get_yaw_rotation(heading)
        # [N, 3]
        translation = tf.stack([center_x, center_y, center_z], axis=-1)

        l2 = length * 0.5
        w2 = width * 0.5
        h2 = height * 0.5

        # [N, 8, 3]
        corners = tf.reshape(
            tf.stack([
                l2, w2, -h2, -l2, w2, -h2, -l2, -w2, -h2, l2, -w2, -h2, l2, w2,
                h2, -l2, w2, h2, -l2, -w2, h2, l2, -w2, h2
            ],
                     axis=-1), [-1, 8, 3])
        # [N, 8, 3]
        corners = tf.einsum('nij,nkj->nki', rotation,
                            corners) + tf.expand_dims(translation, axis=-2)

        return corners
def get_min_max_3d_box_corners(boxes,
                               vehicleToWorldTransform,
                               worldToReferencePointTransform,
                               useGlobalPoseTransform,
                               name=None):
    """Given a set of upright boxes, return its 2 min and max corner points
     in world (global) space frame

  Args:
    boxes: tf Tensor [N, 7]. The inner dims are [center{x,y,z}, length, width,
      height, heading].
    vehicleToWorldTransform: None or a 4x4 transformation if needed from local to global space
    name: the name scope.

  Returns:
    corners: tf Tensor [N, 3, 2].
  """
    with tf.compat.v1.name_scope(name, 'GetMinMax3dBoxCorners', [boxes]):
        center_x, center_y, center_z, length, width, height, heading = tf.unstack(
            boxes, axis=-1)

        if useGlobalPoseTransform:
            vehicleToWorldRotation = vehicleToWorldTransform[0:3, 0:3]
            vehicleToWorldTranslation = vehicleToWorldTransform[0:3, 3]
            worldToReferenceRotation = worldToReferencePointTransform[0:3, 0:3]
            worldToReferenceTranslation = worldToReferencePointTransform[0:3,
                                                                         3]

        # Step 1: get the box corners in local space
        # [N, 3, 3]
        rotation = transform_utils.get_yaw_rotation(heading)
        # [N, 3]
        translation = tf.stack([center_x, center_y, center_z], axis=-1)

        l2 = length * 0.5
        w2 = width * 0.5
        h2 = height * 0.5

        # [N, 8, 3]
        corners = tf.reshape(
            tf.stack([
                l2, w2, -h2, -l2, w2, -h2, -l2, -w2, -h2, l2, -w2, -h2, l2, w2,
                h2, -l2, w2, h2, -l2, -w2, h2, l2, -w2, h2
            ],
                     axis=-1), [-1, 8, 3])
        # [N, 8, 3]
        # Step 2: transform the box corners from AABB to OOBB in local space
        corners = tf.einsum('nij,nkj->nki', rotation,
                            corners) + tf.expand_dims(translation, axis=-2)

        if useGlobalPoseTransform:
            # [N, 8, 3]
            # Step 3: transform the box corners from OOBB in local space to OOBB in world space
            corners = tf.einsum('jk,nik->nij', vehicleToWorldRotation,
                                corners) + tf.expand_dims(
                                    vehicleToWorldTranslation, axis=-2)

            # Step 4: transform from 00BB in world space to OOBB in reference frame (i.e. relative to the first reference vehicle position)
            corners = tf.einsum('jk,nik->nij', worldToReferenceRotation,
                                corners) + tf.expand_dims(
                                    worldToReferenceTranslation, axis=-2)

        corners = corners.numpy()
        #print(corners)
        min_corners = corners.min(axis=1)
        max_corners = corners.max(axis=1)
        #print(min_corners)
        #print(max_corners)
        minMaxCorners = np.stack([min_corners, max_corners],
                                 axis=1).transpose(0, 2, 1)
        return minMaxCorners