예제 #1
0
    def test_prune_non_overlapping_boxes(self):
        corners1 = tf.constant([[4.0, 3.0, 7.0, 5.0], [5.0, 6.0, 10.0, 7.0]])
        corners2 = tf.constant([[3.0, 4.0, 6.0, 8.0], [14.0, 14.0, 15.0, 15.0],
                                [0.0, 0.0, 20.0, 20.0]])
        boxes1 = box_list.BoxList(corners1)
        boxes2 = box_list.BoxList(corners2)
        minoverlap = 0.5

        exp_output_1 = boxes1
        exp_output_2 = box_list.BoxList(tf.constant(0.0, shape=[0, 4]))
        output_1, keep_indices_1 = box_list_ops.prune_non_overlapping_boxes(
            boxes1, boxes2, min_overlap=minoverlap)
        output_2, keep_indices_2 = box_list_ops.prune_non_overlapping_boxes(
            boxes2, boxes1, min_overlap=minoverlap)
        with self.test_session() as sess:
            (output_1_, keep_indices_1_, output_2_, keep_indices_2_,
             exp_output_1_, exp_output_2_) = sess.run([
                 output_1.get(), keep_indices_1,
                 output_2.get(), keep_indices_2,
                 exp_output_1.get(),
                 exp_output_2.get()
             ])
            self.assertAllClose(output_1_, exp_output_1_)
            self.assertAllClose(output_2_, exp_output_2_)
            self.assertAllEqual(keep_indices_1_, [0, 1])
            self.assertAllEqual(keep_indices_2_, [])
예제 #2
0
    def test_box_list_invalid_inputs(self):
        data0 = tf.constant([[[0, 0, 1, 1], [3, 4, 5, 5]]], tf.float32)
        data1 = tf.constant([[0, 0, 1], [1, 1, 2], [3, 4, 5]], tf.float32)
        data2 = tf.constant([[0, 0, 1], [1, 1, 2], [3, 4, 5]], tf.int32)

        with self.assertRaises(ValueError):
            _ = box_list.BoxList(data0)
        with self.assertRaises(ValueError):
            _ = box_list.BoxList(data1)
        with self.assertRaises(ValueError):
            _ = box_list.BoxList(data2)
예제 #3
0
 def test_pairwise_distances(self):
     corners1 = tf.constant([[0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 0.0, 2.0]])
     corners2 = tf.constant([[3.0, 4.0, 1.0, 0.0], [-4.0, 0.0, 0.0, 3.0],
                             [0.0, 0.0, 0.0, 0.0]])
     exp_output = [[26, 25, 0], [18, 27, 6]]
     boxes1 = box_list.BoxList(corners1)
     boxes2 = box_list.BoxList(corners2)
     dist_matrix = box_list_ops.sq_dist(boxes1, boxes2)
     with self.test_session() as sess:
         dist_output = sess.run(dist_matrix)
         self.assertAllClose(dist_output, exp_output)
예제 #4
0
 def test_gather_with_invalid_inputs(self):
     corners = tf.constant(
         [4 * [0.0], 4 * [1.0], 4 * [2.0], 4 * [3.0], 4 * [4.0]])
     indices_float32 = tf.constant([0, 2, 4], tf.float32)
     boxes = box_list.BoxList(corners)
     with self.assertRaises(ValueError):
         _ = box_list_ops.gather(boxes, indices_float32)
     indices_2d = tf.constant([[0, 2, 4]], tf.int32)
     boxes = box_list.BoxList(corners)
     with self.assertRaises(ValueError):
         _ = box_list_ops.gather(boxes, indices_2d)
예제 #5
0
 def test_intersection(self):
     corners1 = tf.constant([[4.0, 3.0, 7.0, 5.0], [5.0, 6.0, 10.0, 7.0]])
     corners2 = tf.constant([[3.0, 4.0, 6.0, 8.0], [14.0, 14.0, 15.0, 15.0],
                             [0.0, 0.0, 20.0, 20.0]])
     exp_output = [[2.0, 0.0, 6.0], [1.0, 0.0, 5.0]]
     boxes1 = box_list.BoxList(corners1)
     boxes2 = box_list.BoxList(corners2)
     intersect = box_list_ops.intersection(boxes1, boxes2)
     with self.test_session() as sess:
         intersect_output = sess.run(intersect)
         self.assertAllClose(intersect_output, exp_output)
예제 #6
0
 def test_matched_iou(self):
     corners1 = tf.constant([[4.0, 3.0, 7.0, 5.0], [5.0, 6.0, 10.0, 7.0]])
     corners2 = tf.constant([[3.0, 4.0, 6.0, 8.0], [14.0, 14.0, 15.0,
                                                    15.0]])
     exp_output = [2.0 / 16.0, 0]
     boxes1 = box_list.BoxList(corners1)
     boxes2 = box_list.BoxList(corners2)
     iou = box_list_ops.matched_iou(boxes1, boxes2)
     with self.test_session() as sess:
         iou_output = sess.run(iou)
         self.assertAllClose(iou_output, exp_output)
예제 #7
0
    def test_change_coordinate_frame(self):
        corners = tf.constant([[0.25, 0.5, 0.75, 0.75], [0.5, 0.0, 1.0, 1.0]])
        window = tf.constant([0.25, 0.25, 0.75, 0.75])
        boxes = box_list.BoxList(corners)

        expected_corners = tf.constant([[0, 0.5, 1.0, 1.0],
                                        [0.5, -0.5, 1.5, 1.5]])
        expected_boxes = box_list.BoxList(expected_corners)
        output = box_list_ops.change_coordinate_frame(boxes, window)

        with self.test_session() as sess:
            output_, expected_boxes_ = sess.run(
                [output.get(), expected_boxes.get()])
            self.assertAllClose(output_, expected_boxes_)
예제 #8
0
 def test_ioa(self):
     corners1 = tf.constant([[4.0, 3.0, 7.0, 5.0], [5.0, 6.0, 10.0, 7.0]])
     corners2 = tf.constant([[3.0, 4.0, 6.0, 8.0], [14.0, 14.0, 15.0, 15.0],
                             [0.0, 0.0, 20.0, 20.0]])
     exp_output_1 = [[2.0 / 12.0, 0, 6.0 / 400.0],
                     [1.0 / 12.0, 0.0, 5.0 / 400.0]]
     exp_output_2 = [[2.0 / 6.0, 1.0 / 5.0], [0, 0], [6.0 / 6.0, 5.0 / 5.0]]
     boxes1 = box_list.BoxList(corners1)
     boxes2 = box_list.BoxList(corners2)
     ioa_1 = box_list_ops.ioa(boxes1, boxes2)
     ioa_2 = box_list_ops.ioa(boxes2, boxes1)
     with self.test_session() as sess:
         ioa_output_1, ioa_output_2 = sess.run([ioa_1, ioa_2])
         self.assertAllClose(ioa_output_1, exp_output_1)
         self.assertAllClose(ioa_output_2, exp_output_2)
예제 #9
0
def scale(boxlist, y_scale, x_scale, scope=None):
    """scale box coordinates in x and y dimensions.

    Args:
      boxlist: BoxList holding N boxes
      y_scale: (float) scalar tensor
      x_scale: (float) scalar tensor
      scope: name scope.

    Returns:
      boxlist: BoxList holding N boxes
    """
    with tf.name_scope(scope, 'Scale'):
        y_scale = tf.cast(y_scale, tf.float32)
        x_scale = tf.cast(x_scale, tf.float32)
        y_min, x_min, y_max, x_max = tf.split(value=boxlist.get(),
                                              num_or_size_splits=4,
                                              axis=1)
        y_min = y_scale * y_min
        y_max = y_scale * y_max
        x_min = x_scale * x_min
        x_max = x_scale * x_max
        scaled_boxlist = box_list.BoxList(
            tf.concat([y_min, x_min, y_max, x_max], 1))
        return _copy_extra_fields(scaled_boxlist, boxlist)
예제 #10
0
 def test_as_tensor_dict_missing_field(self):
     boxlist = box_list.BoxList(tf.constant(
         [[0.1, 0.1, 0.4, 0.4], [0.1, 0.1, 0.5, 0.5]], tf.float32))
     boxlist.add_field('classes', tf.constant([0, 1]))
     boxlist.add_field('scores', tf.constant([0.75, 0.2]))
     with self.assertRaises(ValueError):
         boxlist.as_tensor_dict(['foo', 'bar'])
예제 #11
0
def change_coordinate_frame(boxlist, window, scope=None):
    """Change coordinate frame of the boxlist to be relative to window's frame.

    Given a window of the form [ymin, xmin, ymax, xmax],
    changes bounding box coordinates from boxlist to be relative to this window
    (e.g., the min corner maps to (0,0) and the max corner maps to (1,1)).

    An example use case is data augmentation: where we are given groundtruth
    boxes (boxlist) and would like to randomly crop the image to some
    window (window). In this case we need to change the coordinate frame of
    each groundtruth box to be relative to this new window.

    Args:
      boxlist: A BoxList object holding N boxes.
      window: A rank 1 tensor [4].
      scope: name scope.

    Returns:
      Returns a BoxList object with N boxes.
    """
    with tf.name_scope(scope, 'ChangeCoordinateFrame'):
        win_height = window[2] - window[0]
        win_width = window[3] - window[1]
        boxlist_new = scale(
            box_list.BoxList(boxlist.get() -
                             [window[0], window[1], window[0], window[1]]),
            1.0 / win_height, 1.0 / win_width)
        boxlist_new = _copy_extra_fields(boxlist_new, boxlist)
        return boxlist_new
예제 #12
0
 def test_ioaworks_on_empty_inputs(self):
     corners1 = tf.constant([[4.0, 3.0, 7.0, 5.0], [5.0, 6.0, 10.0, 7.0]])
     corners2 = tf.constant([[3.0, 4.0, 6.0, 8.0], [14.0, 14.0, 15.0, 15.0],
                             [0.0, 0.0, 20.0, 20.0]])
     boxes1 = box_list.BoxList(corners1)
     boxes2 = box_list.BoxList(corners2)
     boxes_empty = box_list.BoxList(tf.zeros((0, 4)))
     ioa_empty_1 = box_list_ops.ioa(boxes1, boxes_empty)
     ioa_empty_2 = box_list_ops.ioa(boxes_empty, boxes2)
     ioa_empty_3 = box_list_ops.ioa(boxes_empty, boxes_empty)
     with self.test_session() as sess:
         ioa_output_1, ioa_output_2, ioa_output_3 = sess.run(
             [ioa_empty_1, ioa_empty_2, ioa_empty_3])
         self.assertAllEqual(ioa_output_1.shape, (2, 0))
         self.assertAllEqual(ioa_output_2.shape, (0, 3))
         self.assertAllEqual(ioa_output_3.shape, (0, 0))
예제 #13
0
 def test_area(self):
     corners = tf.constant([[0.0, 0.0, 10.0, 20.0], [1.0, 2.0, 3.0, 4.0]])
     exp_output = [200.0, 4.0]
     boxes = box_list.BoxList(corners)
     areas = box_list_ops.area(boxes)
     with self.test_session() as sess:
         areas_output = sess.run(areas)
         self.assertAllClose(areas_output, exp_output)
예제 #14
0
 def test_transpose_coordinates(self):
     boxes = [[10.0, 10.0, 20.0, 15.0], [0.2, 0.1, 0.5, 0.4]]
     boxes = box_list.BoxList(tf.constant(boxes))
     boxes.transpose_coordinates()
     expected_corners = [[10.0, 10.0, 15.0, 20.0], [0.1, 0.2, 0.4, 0.5]]
     with self.test_session() as sess:
         corners_out = sess.run(boxes.get())
         self.assertAllClose(corners_out, expected_corners)
예제 #15
0
 def test_get_correct_center_coordinates_and_sizes(self):
     boxes = [[10.0, 10.0, 20.0, 15.0], [0.2, 0.1, 0.5, 0.4]]
     boxes = box_list.BoxList(tf.constant(boxes))
     centers_sizes = boxes.get_center_coordinates_and_sizes()
     expected_centers_sizes = [[15, 0.35],
                               [12.5, 0.25], [10, 0.3], [5, 0.3]]
     with self.test_session() as sess:
         centers_sizes_out = sess.run(centers_sizes)
         self.assertAllClose(centers_sizes_out, expected_centers_sizes)
예제 #16
0
    def test_num_boxes(self):
        data = tf.constant(
            [[0, 0, 1, 1], [1, 1, 2, 3], [3, 4, 5, 5]], tf.float32)
        expected_num_boxes = 3

        boxes = box_list.BoxList(data)
        with self.test_session() as sess:
            num_boxes_output = sess.run(boxes.num_boxes())
            self.assertEquals(num_boxes_output, expected_num_boxes)
예제 #17
0
    def test_gather_with_invalid_field(self):
        corners = tf.constant([4 * [0.0], 4 * [1.0]])
        indices = tf.constant([0, 1], tf.int32)
        weights = tf.constant([[.1], [.3]], tf.float32)

        boxes = box_list.BoxList(corners)
        boxes.add_field('weights', weights)
        with self.assertRaises(ValueError):
            box_list_ops.gather(boxes, indices, ['foo', 'bar'])
예제 #18
0
 def test_gather(self):
     corners = tf.constant(
         [4 * [0.0], 4 * [1.0], 4 * [2.0], 4 * [3.0], 4 * [4.0]])
     indices = tf.constant([0, 2, 4], tf.int32)
     expected_subset = [4 * [0.0], 4 * [2.0], 4 * [4.0]]
     boxes = box_list.BoxList(corners)
     subset = box_list_ops.gather(boxes, indices)
     with self.test_session() as sess:
         subset_output = sess.run(subset.get())
         self.assertAllClose(subset_output, expected_subset)
예제 #19
0
 def test_boolean_mask(self):
     corners = tf.constant(
         [4 * [0.0], 4 * [1.0], 4 * [2.0], 4 * [3.0], 4 * [4.0]])
     indicator = tf.constant([True, False, True, False, True], tf.bool)
     expected_subset = [4 * [0.0], 4 * [2.0], 4 * [4.0]]
     boxes = box_list.BoxList(corners)
     subset = box_list_ops.boolean_mask(boxes, indicator)
     with self.test_session() as sess:
         subset_output = sess.run(subset.get())
         self.assertAllClose(subset_output, expected_subset)
예제 #20
0
 def test_height_width(self):
     corners = tf.constant([[0.0, 0.0, 10.0, 20.0], [1.0, 2.0, 3.0, 4.0]])
     exp_output_heights = [10., 2.]
     exp_output_widths = [20., 2.]
     boxes = box_list.BoxList(corners)
     heights, widths = box_list_ops.height_width(boxes)
     with self.test_session() as sess:
         output_heights, output_widths = sess.run([heights, widths])
         self.assertAllClose(output_heights, exp_output_heights)
         self.assertAllClose(output_widths, exp_output_widths)
예제 #21
0
 def test_prune_small_boxes(self):
     boxes = tf.constant([[4.0, 3.0, 7.0, 5.0], [5.0, 6.0, 10.0, 7.0],
                          [3.0, 4.0, 6.0, 8.0], [14.0, 14.0, 15.0, 15.0],
                          [0.0, 0.0, 20.0, 20.0]])
     exp_boxes = [[3.0, 4.0, 6.0, 8.0], [0.0, 0.0, 20.0, 20.0]]
     boxes = box_list.BoxList(boxes)
     pruned_boxes = box_list_ops.prune_small_boxes(boxes, 3)
     with self.test_session() as sess:
         pruned_boxes = sess.run(pruned_boxes.get())
         self.assertAllEqual(pruned_boxes, exp_boxes)
예제 #22
0
    def test_create_box_list_with_dynamic_shape(self):
        data = tf.constant(
            [[0, 0, 1, 1], [1, 1, 2, 3], [3, 4, 5, 5]], tf.float32)
        indices = tf.reshape(tf.where(tf.greater([1, 0, 1], 0)), [-1])
        data = tf.gather(data, indices)
        assert data.get_shape().as_list() == [None, 4]
        expected_num_boxes = 2

        boxes = box_list.BoxList(data)
        with self.test_session() as sess:
            num_boxes_output = sess.run(boxes.num_boxes())
            self.assertEquals(num_boxes_output, expected_num_boxes)
예제 #23
0
    def test_scale(self):
        corners = tf.constant([[0, 0, 100, 200], [50, 120, 100, 140]],
                              dtype=tf.float32)
        boxes = box_list.BoxList(corners)
        boxes.add_field('extra_data', tf.constant([[1], [2]]))

        y_scale = tf.constant(1.0 / 100)
        x_scale = tf.constant(1.0 / 200)
        scaled_boxes = box_list_ops.scale(boxes, y_scale, x_scale)
        exp_output = [[0, 0, 1, 1], [0.5, 0.6, 1.0, 0.7]]
        with self.test_session() as sess:
            scaled_corners_out = sess.run(scaled_boxes.get())
            self.assertAllClose(scaled_corners_out, exp_output)
            extra_data_out = sess.run(scaled_boxes.get_field('extra_data'))
            self.assertAllEqual(extra_data_out, [[1], [2]])
예제 #24
0
 def test_prune_small_boxes_prunes_boxes_with_negative_side(self):
     boxes = tf.constant([
         [4.0, 3.0, 7.0, 5.0],
         [5.0, 6.0, 10.0, 7.0],
         [3.0, 4.0, 6.0, 8.0],
         [14.0, 14.0, 15.0, 15.0],
         [0.0, 0.0, 20.0, 20.0],
         [2.0, 3.0, 1.5, 7.0],  # negative height
         [2.0, 3.0, 5.0, 1.7]
     ])  # negative width
     exp_boxes = [[3.0, 4.0, 6.0, 8.0], [0.0, 0.0, 20.0, 20.0]]
     boxes = box_list.BoxList(boxes)
     pruned_boxes = box_list_ops.prune_small_boxes(boxes, 3)
     with self.test_session() as sess:
         pruned_boxes = sess.run(pruned_boxes.get())
         self.assertAllEqual(pruned_boxes, exp_boxes)
예제 #25
0
    def test_boolean_mask_with_field(self):
        corners = tf.constant(
            [4 * [0.0], 4 * [1.0], 4 * [2.0], 4 * [3.0], 4 * [4.0]])
        indicator = tf.constant([True, False, True, False, True], tf.bool)
        weights = tf.constant([[.1], [.3], [.5], [.7], [.9]], tf.float32)
        expected_subset = [4 * [0.0], 4 * [2.0], 4 * [4.0]]
        expected_weights = [[.1], [.5], [.9]]

        boxes = box_list.BoxList(corners)
        boxes.add_field('weights', weights)
        subset = box_list_ops.boolean_mask(boxes, indicator, ['weights'])
        with self.test_session() as sess:
            subset_output, weights_output = sess.run(
                [subset.get(), subset.get_field('weights')])
            self.assertAllClose(subset_output, expected_subset)
            self.assertAllClose(weights_output, expected_weights)
예제 #26
0
    def test_gather_with_dynamic_indexing(self):
        corners = tf.constant(
            [4 * [0.0], 4 * [1.0], 4 * [2.0], 4 * [3.0], 4 * [4.0]])
        weights = tf.constant([.5, .3, .7, .1, .9], tf.float32)
        indices = tf.reshape(tf.where(tf.greater(weights, 0.4)), [-1])
        expected_subset = [4 * [0.0], 4 * [2.0], 4 * [4.0]]
        expected_weights = [.5, .7, .9]

        boxes = box_list.BoxList(corners)
        boxes.add_field('weights', weights)
        subset = box_list_ops.gather(boxes, indices, ['weights'])
        with self.test_session() as sess:
            subset_output, weights_output = sess.run(
                [subset.get(), subset.get_field('weights')])
            self.assertAllClose(subset_output, expected_subset)
            self.assertAllClose(weights_output, expected_weights)
예제 #27
0
    def test_gather_with_field(self):
        corners = tf.constant(
            [4 * [0.0], 4 * [1.0], 4 * [2.0], 4 * [3.0], 4 * [4.0]])
        indices = tf.constant([0, 2, 4], tf.int32)
        weights = tf.constant([[.1], [.3], [.5], [.7], [.9]], tf.float32)
        expected_subset = [4 * [0.0], 4 * [2.0], 4 * [4.0]]
        expected_weights = [[.1], [.5], [.9]]

        boxes = box_list.BoxList(corners)
        boxes.add_field('weights', weights)
        subset = box_list_ops.gather(boxes, indices, ['weights'])
        with self.test_session() as sess:
            subset_output, weights_output = sess.run(
                [subset.get(), subset.get_field('weights')])
            self.assertAllClose(subset_output, expected_subset)
            self.assertAllClose(weights_output, expected_weights)
예제 #28
0
    def test_as_tensor_dict(self):
        boxlist = box_list.BoxList(tf.constant(
            [[0.1, 0.1, 0.4, 0.4], [0.1, 0.1, 0.5, 0.5]], tf.float32))
        boxlist.add_field('classes', tf.constant([0, 1]))
        boxlist.add_field('scores', tf.constant([0.75, 0.2]))
        tensor_dict = boxlist.as_tensor_dict()

        expected_boxes = [[0.1, 0.1, 0.4, 0.4], [0.1, 0.1, 0.5, 0.5]]
        expected_classes = [0, 1]
        expected_scores = [0.75, 0.2]

        with self.test_session() as sess:
            tensor_dict_out = sess.run(tensor_dict)
            self.assertAllEqual(3, len(tensor_dict_out))
            self.assertAllClose(expected_boxes, tensor_dict_out['boxes'])
            self.assertAllEqual(expected_classes, tensor_dict_out['classes'])
            self.assertAllClose(expected_scores, tensor_dict_out['scores'])
예제 #29
0
def boolean_mask(boxlist, indicator, fields=None, scope=None):
    """Select boxes from BoxList according to indicator and return new BoxList.

    `boolean_mask` returns the subset of boxes that are marked as "True" by the
    indicator tensor. By default, `boolean_mask` returns boxes corresponding to
    the input index list, as well as all additional fields stored in the boxlist
    (indexing into the first dimension).  However one can optionally only draw
    from a subset of fields.

    Args:
      boxlist: BoxList holding N boxes
      indicator: a rank-1 boolean tensor
      fields: (optional) list of fields to also gather from.  If None (default),
        all fields are gathered from.  Pass an empty fields list to only gather
        the box coordinates.
      scope: name scope.

    Returns:
      subboxlist: a BoxList corresponding to the subset of the input BoxList
        specified by indicator
    Raises:
      ValueError: if `indicator` is not a rank-1 boolean tensor.
    """
    with tf.name_scope(scope, 'BooleanMask'):
        if indicator.shape.ndims != 1:
            raise ValueError('indicator should have rank 1')
        if indicator.dtype != tf.bool:
            raise ValueError('indicator should be a boolean tensor')
        subboxlist = box_list.BoxList(tf.boolean_mask(boxlist.get(),
                                                      indicator))
        if fields is None:
            fields = boxlist.get_extra_fields()
        for field in fields:
            if not boxlist.has_field(field):
                raise ValueError('boxlist must contain all specified fields')
            subfieldlist = tf.boolean_mask(boxlist.get_field(field), indicator)
            subboxlist.add_field(field, subfieldlist)
        return subboxlist
예제 #30
0
def gather(boxlist, indices, fields=None, scope=None):
    """Gather boxes from BoxList according to indices and return new BoxList.

    By default, `gather` returns boxes corresponding to the input index list, as
    well as all additional fields stored in the boxlist (indexing into the
    first dimension).  However one can optionally only gather from a
    subset of fields.

    Args:
      boxlist: BoxList holding N boxes
      indices: a rank-1 tensor of type int32 / int64
      fields: (optional) list of fields to also gather from.  If None (default),
        all fields are gathered from.  Pass an empty fields list to only gather
        the box coordinates.
      scope: name scope.

    Returns:
      subboxlist: a BoxList corresponding to the subset of the input BoxList
      specified by indices
    Raises:
      ValueError: if specified field is not contained in boxlist or if the
        indices are not of type int32
    """
    with tf.name_scope(scope, 'Gather'):
        if len(indices.shape.as_list()) != 1:
            raise ValueError('indices should have rank 1')
        if indices.dtype != tf.int32 and indices.dtype != tf.int64:
            raise ValueError('indices should be an int32 / int64 tensor')
        subboxlist = box_list.BoxList(tf.gather(boxlist.get(), indices))
        if fields is None:
            fields = boxlist.get_extra_fields()
        for field in fields:
            if not boxlist.has_field(field):
                raise ValueError('boxlist must contain all specified fields')
            subfieldlist = tf.gather(boxlist.get_field(field), indices)
            subboxlist.add_field(field, subfieldlist)
        return subboxlist