Ejemplo n.º 1
0
def IsWithinBBox(points, bbox):
    """Checks if points are within a 2-d bbox.

  The function returns true if points are strictly inside the box. It also
  returns true when the points are exactly on the box edges.

  Args:
    points: a float Tensor of shape [..., 2] of points to be tested. The last
      coordinates are (x, y).
    bbox: a float Tensor of shape [..., 4, 2] of bboxes. The last coordinates
      are the four corners of the bbox and (x, y). The corners are assumed to be
      given in counter-clockwise order.

  Returns:
    Tensor: If ``pshape = tf.shape(points)[:-1]`` and
    ``bshape = tf.shape(bbox)[:-2]``, returns a boolean tensor of shape
    ``tf.concat(pshape, bshape)``, where each element is true if the point is
    inside to the corresponding box.  If a point falls exactly on an edge of the
    bbox, it is also true.
  """
    bshape = py_utils.GetShape(bbox)[:-2]
    pshape = py_utils.GetShape(points)[:-1]
    bbox = py_utils.HasShape(bbox, tf.concat([bshape, [4, 2]], axis=0))
    points = py_utils.HasShape(points, tf.concat([pshape, [2]], axis=0))
    # Enumerate all 4 edges:
    v1, v2, v3, v4 = (bbox[..., 0, :], bbox[..., 1, :], bbox[...,
                                                             2, :], bbox[...,
                                                                         3, :])
    v1v2v3_check = tf.reduce_all(_IsCounterClockwiseDirection(v1, v2, v3))
    v2v3v4_check = tf.reduce_all(_IsCounterClockwiseDirection(v2, v3, v4))
    v4v1v2_check = tf.reduce_all(_IsCounterClockwiseDirection(v4, v1, v2))
    v3v4v1_check = tf.reduce_all(_IsCounterClockwiseDirection(v3, v4, v1))
    with tf.control_dependencies([
            py_utils.Assert(v1v2v3_check, [v1, v2, v3]),
            py_utils.Assert(v2v3v4_check, [v3, v3, v4]),
            py_utils.Assert(v4v1v2_check, [v4, v1, v2]),
            py_utils.Assert(v3v4v1_check, [v3, v4, v1])
    ]):
        is_inside = tf.math.logical_and(
            tf.math.logical_and(_IsOnLeftHandSideOrOn(points, v1, v2),
                                _IsOnLeftHandSideOrOn(points, v2, v3)),
            tf.math.logical_and(_IsOnLeftHandSideOrOn(points, v3, v4),
                                _IsOnLeftHandSideOrOn(points, v4, v1)))
    has_non_zero_area = tf.greater(_BBoxArea(bbox), 0)
    is_inside = tf.logical_and(tf.cast(is_inside, tf.bool), has_non_zero_area)
    # Swap the last two dimensions.
    is_inside = tf.einsum('...ij->...ji', tf.cast(is_inside, tf.int32))
    return tf.cast(is_inside, tf.bool)
Ejemplo n.º 2
0
def IsWithinBBox(points, bbox):
  """Checks if points are within a 2-d bbox.

  The function returns true if points are strictly inside the box. It also
  returns true when the points are exactly on the box edges.

  Args:
    points: a float Tensor of shape [..., 2] of points to be tested. The last
      coordinates are (x, y).
    bbox: a float Tensor of shape [..., 4, 2] of bboxes. The last coordinates
      are the four corners of the bbox and (x, y). The corners are assumed to be
      given in counter-clockwise order.

  Returns:
    If pshape = tf.shape(points)[:-1] and bshape = tf.shape(bbox)[:-2],
    a tensor of shape tf.concat(pshape, bshape), of booleans, where
    each element is true if the point is inside to the corresponding box.
    If a point falls exactly on an edge of the bbox, it is also true.
  """
  bshape = py_utils.GetShape(bbox)[:-2]
  pshape = py_utils.GetShape(points)[:-1]
  bbox = py_utils.HasShape(bbox, bshape + [4, 2])
  points = py_utils.HasShape(points, pshape + [2])
  # Enumerate all 4 edges:
  v1, v2, v3, v4 = (bbox[..., 0, :], bbox[..., 1, :], bbox[..., 2, :],
                    bbox[..., 3, :])
  v1v2v3_check = tf.reduce_all(_IsCounterClockwiseDirection(v1, v2, v3))
  v2v3v4_check = tf.reduce_all(_IsCounterClockwiseDirection(v2, v3, v4))
  v4v1v2_check = tf.reduce_all(_IsCounterClockwiseDirection(v4, v1, v2))
  v3v4v1_check = tf.reduce_all(_IsCounterClockwiseDirection(v3, v4, v1))
  with tf.control_dependencies([
      py_utils.Assert(v1v2v3_check, [v1, v2, v3]),
      py_utils.Assert(v2v3v4_check, [v3, v3, v4]),
      py_utils.Assert(v4v1v2_check, [v4, v1, v2]),
      py_utils.Assert(v3v4v1_check, [v3, v4, v1])
  ]):
    is_inside = tf.logical_and(
        tf.logical_and(
            _IsOnLeftHandSideOrOn(points, v1, v2),
            _IsOnLeftHandSideOrOn(points, v2, v3)),
        tf.logical_and(
            _IsOnLeftHandSideOrOn(points, v3, v4),
            _IsOnLeftHandSideOrOn(points, v4, v1)))
  return is_inside