예제 #1
0
    def match_single_image_info(self, image_info):
        """Match detections to groundtruth for a single image.

    Detections are matched to available groundtruth in the image based on the
    IOU threshold from the constructor.  The classes of the detections and
    groundtruth matches are then compared. Detections that do not have IOU above
    the required threshold or have different classes from their match are
    considered negative matches. All inputs in `image_info` originate or are
    inferred from the eval_dict passed to class method
    `get_estimator_eval_metric_ops`.

    Args:
      image_info: a tuple or list containing the following (in order):
        - gt_boxes: tf.float32 tensor of groundtruth boxes.
        - gt_classes: tf.int64 tensor of groundtruth classes associated with
            groundtruth boxes.
        - num_gt_box: scalar indicating the number of groundtruth boxes per
            image.
        - det_boxes: tf.float32 tensor of detection boxes.
        - det_classes: tf.int64 tensor of detection classes associated with
            detection boxes.
        - num_det_box: scalar indicating the number of detection boxes per
            image.
    Returns:
      is_class_matched: tf.int64 tensor identical in shape to det_boxes,
        indicating whether detection boxes matched with and had the same
        class as groundtruth annotations.
    """
        (gt_boxes, gt_classes, num_gt_box, det_boxes, det_classes,
         num_det_box) = image_info
        detection_boxes = det_boxes[:num_det_box]
        detection_classes = det_classes[:num_det_box]
        groundtruth_boxes = gt_boxes[:num_gt_box]
        groundtruth_classes = gt_classes[:num_gt_box]
        det_boxlist = box_list.BoxList(detection_boxes)
        gt_boxlist = box_list.BoxList(groundtruth_boxes)

        # Target assigner requires classes in one-hot format. An additional
        # dimension is required since gt_classes are 1-indexed; the zero index is
        # provided to all non-matches.
        one_hot_depth = tf.cast(tf.add(tf.reduce_max(groundtruth_classes), 1),
                                dtype=tf.int32)
        gt_classes_one_hot = tf.one_hot(groundtruth_classes,
                                        one_hot_depth,
                                        dtype=tf.float32)
        one_hot_cls_targets, _, _, _, _ = self._target_assigner.assign(
            det_boxlist,
            gt_boxlist,
            gt_classes_one_hot,
            unmatched_class_label=tf.zeros(shape=one_hot_depth,
                                           dtype=tf.float32))
        # Transform from one-hot back to indexes.
        cls_targets = tf.argmax(one_hot_cls_targets, axis=1)
        is_class_matched = tf.cast(tf.equal(tf.cast(cls_targets, tf.int64),
                                            detection_classes),
                                   dtype=tf.int64)
        return is_class_matched
예제 #2
0
 def test_very_small_Width_nan_after_encoding(self):
   boxes = [[10.0, 10.0, 10.0000001, 20.0]]
   anchors = [[15.0, 12.0, 30.0, 18.0]]
   expected_rel_codes = [[-0.833333, 0., -21.128731, 0.510826]]
   boxes = box_list.BoxList(tf.constant(boxes))
   anchors = box_list.BoxList(tf.constant(anchors))
   coder = faster_rcnn_box_coder.FasterRcnnBoxCoder()
   rel_codes = coder.encode(boxes, anchors)
   with self.test_session() as sess:
     rel_codes_out, = sess.run([rel_codes])
     self.assertAllClose(rel_codes_out, expected_rel_codes)
예제 #3
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)
예제 #4
0
 def test_correct_relative_codes_with_small_width(self):
     boxes = [[10.0, 10.0, 10.0000001, 20.0]]
     anchors = [[15.0, 12.0, 30.0, 18.0]]
     scale_factors = None
     expected_rel_codes = [[-1.317616, 0., -20.670586]]
     boxes = box_list.BoxList(tf.constant(boxes))
     anchors = box_list.BoxList(tf.constant(anchors))
     coder = square_box_coder.SquareBoxCoder(scale_factors=scale_factors)
     rel_codes = coder.encode(boxes, anchors)
     with self.test_session() as sess:
         (rel_codes_out, ) = sess.run([rel_codes])
         self.assertAllClose(rel_codes_out, expected_rel_codes)
예제 #5
0
 def test_get_correct_relative_codes_after_encoding(self):
   boxes = [[10.0, 10.0, 20.0, 15.0], [0.2, 0.1, 0.5, 0.4]]
   anchors = [[15.0, 12.0, 30.0, 18.0], [0.1, 0.0, 0.7, 0.9]]
   expected_rel_codes = [[-0.5, -0.416666, -0.405465, -0.182321],
                         [-0.083333, -0.222222, -0.693147, -1.098612]]
   boxes = box_list.BoxList(tf.constant(boxes))
   anchors = box_list.BoxList(tf.constant(anchors))
   coder = faster_rcnn_box_coder.FasterRcnnBoxCoder()
   rel_codes = coder.encode(boxes, anchors)
   with self.test_session() as sess:
     rel_codes_out, = sess.run([rel_codes])
     self.assertAllClose(rel_codes_out, expected_rel_codes)
예제 #6
0
  def testGetCorrectRelativeCodesAfterEncoding(self):
    box_corners = [[0.0, 0.0, 0.5, 0.5], [0.0, 0.0, 0.5, 0.5]]
    boxes = box_list.BoxList(tf.constant(box_corners))
    expected_rel_codes = [[0.0, 0.0, 0.0, 0.0], [-5.0, -5.0, -5.0, -3.0]]
    prior_means = tf.constant([[0.0, 0.0, 0.5, 0.5], [0.5, 0.5, 1.0, 0.8]])
    priors = box_list.BoxList(prior_means)

    coder = mean_stddev_box_coder.MeanStddevBoxCoder(stddev=0.1)
    rel_codes = coder.encode(boxes, priors)
    with self.test_session() as sess:
      rel_codes_out = sess.run(rel_codes)
      self.assertAllClose(rel_codes_out, expected_rel_codes)
 def test_get_correct_pairwise_similarity_based_on_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],
                           [0.0, 0.0, 20.0, 20.0]])
   exp_output = [[2.0 / 16.0, 0, 6.0 / 400.0], [1.0 / 16.0, 0.0, 5.0 / 400.0]]
   boxes1 = box_list.BoxList(corners1)
   boxes2 = box_list.BoxList(corners2)
   iou_similarity_calculator = region_similarity_calculator.IouSimilarity()
   iou_similarity = iou_similarity_calculator.compare(boxes1, boxes2)
   with self.test_session() as sess:
     iou_output = sess.run(iou_similarity)
     self.assertAllClose(iou_output, exp_output)
예제 #8
0
 def test_correct_relative_codes_with_non_default_scale(self):
     boxes = [[10.0, 10.0, 20.0, 15.0], [0.2, 0.1, 0.5, 0.4]]
     anchors = [[15.0, 12.0, 30.0, 18.0], [0.1, 0.0, 0.7, 0.9]]
     scale_factors = [2, 3, 4]
     expected_rel_codes = [[-1.581139, -0.790569, -1.175573],
                           [-0.136083, -0.816497, -3.583519]]
     boxes = box_list.BoxList(tf.constant(boxes))
     anchors = box_list.BoxList(tf.constant(anchors))
     coder = square_box_coder.SquareBoxCoder(scale_factors=scale_factors)
     rel_codes = coder.encode(boxes, anchors)
     with self.test_session() as sess:
         (rel_codes_out, ) = sess.run([rel_codes])
         self.assertAllClose(rel_codes_out, expected_rel_codes)
 def test_get_correct_pairwise_similarity_based_on_squared_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_similarity_calc = region_similarity_calculator.NegSqDistSimilarity()
   dist_similarity = dist_similarity_calc.compare(boxes1, boxes2)
   with self.test_session() as sess:
     dist_output = sess.run(dist_similarity)
     self.assertAllClose(dist_output, exp_output)
예제 #10
0
    def test_correct_relative_codes_with_default_scale(self):
        boxes = [[10.0, 10.0, 20.0, 15.0], [0.2, 0.1, 0.5, 0.4]]
        anchors = [[15.0, 12.0, 30.0, 18.0], [0.1, 0.0, 0.7, 0.9]]
        scale_factors = None
        expected_rel_codes = [[-0.790569, -0.263523, -0.293893],
                              [-0.068041, -0.272166, -0.89588]]

        boxes = box_list.BoxList(tf.constant(boxes))
        anchors = box_list.BoxList(tf.constant(anchors))
        coder = square_box_coder.SquareBoxCoder(scale_factors=scale_factors)
        rel_codes = coder.encode(boxes, anchors)
        with self.test_session() as sess:
            (rel_codes_out, ) = sess.run([rel_codes])
            self.assertAllClose(rel_codes_out, expected_rel_codes)
예제 #11
0
 def test_get_correct_relative_codes_after_encoding_with_scaling(self):
   boxes = [[10.0, 10.0, 20.0, 15.0], [0.2, 0.1, 0.5, 0.4]]
   anchors = [[15.0, 12.0, 30.0, 18.0], [0.1, 0.0, 0.7, 0.9]]
   scale_factors = [2, 3, 4, 5]
   expected_rel_codes = [[-1., -1.25, -1.62186, -0.911608],
                         [-0.166667, -0.666667, -2.772588, -5.493062]]
   boxes = box_list.BoxList(tf.constant(boxes))
   anchors = box_list.BoxList(tf.constant(anchors))
   coder = faster_rcnn_box_coder.FasterRcnnBoxCoder(
       scale_factors=scale_factors)
   rel_codes = coder.encode(boxes, anchors)
   with self.test_session() as sess:
     rel_codes_out, = sess.run([rel_codes])
     self.assertAllClose(rel_codes_out, expected_rel_codes)
예제 #12
0
    def _decode(self, rel_codes, anchors):
        """Decodes relative codes to boxes.

    Args:
      rel_codes: a tensor representing N anchor-encoded boxes.
      anchors: BoxList of anchors.

    Returns:
      boxes: BoxList holding N bounding boxes.
    """
        ycenter_a, xcenter_a, ha, wa = anchors.get_center_coordinates_and_sizes(
        )
        la = tf.sqrt(ha * wa)

        ty, tx, tl = tf.unstack(tf.transpose(rel_codes))
        if self._scale_factors:
            ty /= self._scale_factors[0]
            tx /= self._scale_factors[1]
            tl /= self._scale_factors[2]
        l = tf.exp(tl) * la
        ycenter = ty * la + ycenter_a
        xcenter = tx * la + xcenter_a
        ymin = ycenter - l / 2.
        xmin = xcenter - l / 2.
        ymax = ycenter + l / 2.
        xmax = xcenter + l / 2.
        return box_list.BoxList(
            tf.transpose(tf.stack([ymin, xmin, ymax, xmax])))
예제 #13
0
    def _decode(self, rel_codes, anchors):
        """Decode relative codes to boxes.

    Args:
      rel_codes: a tensor representing N anchor-encoded boxes.
      anchors: BoxList of anchors.

    Returns:
      boxes: BoxList holding N bounding boxes.
    """
        ycenter_a, xcenter_a, ha, wa = anchors.get_center_coordinates_and_sizes(
        )

        ty, tx, th, tw = tf.unstack(tf.transpose(rel_codes))
        if self._scale_factors:
            ty /= self._scale_factors[0]
            tx /= self._scale_factors[1]
            th /= self._scale_factors[2]
            tw /= self._scale_factors[3]
        w = tf.exp(tw) * wa
        h = tf.exp(th) * ha
        ycenter = ty * ha + ycenter_a
        xcenter = tx * wa + xcenter_a
        ymin = ycenter - h / 2.
        xmin = xcenter - w / 2.
        ymax = ycenter + h / 2.
        xmax = xcenter + w / 2.
        return box_list.BoxList(
            tf.transpose(tf.stack([ymin, xmin, ymax, xmax])))
예제 #14
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)
예제 #15
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
예제 #16
0
 def test_very_small_width_nan_after_encoding(self):
     boxes = [[10., 10., 10.0000001, 20.]]
     keypoints = [[[10., 10.], [10.0000001, 20.]]]
     anchors = [[15., 12., 30., 18.]]
     expected_rel_codes = [[
         -0.833333, 0., -21.128731, 0.510826, -0.833333, -0.833333,
         -0.833333, 0.833333
     ]]
     boxes = box_list.BoxList(tf.constant(boxes))
     boxes.add_field(fields.BoxListFields.keypoints, tf.constant(keypoints))
     anchors = box_list.BoxList(tf.constant(anchors))
     coder = keypoint_box_coder.KeypointBoxCoder(2)
     rel_codes = coder.encode(boxes, anchors)
     with self.test_session() as sess:
         rel_codes_out, = sess.run([rel_codes])
         self.assertAllClose(rel_codes_out, expected_rel_codes)
예제 #17
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'])
예제 #18
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)
예제 #19
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)
예제 #20
0
def concatenate(boxlists, fields=None, scope=None):
    """Concatenate list of BoxLists.

  This op concatenates a list of input BoxLists into a larger BoxList.  It also
  handles concatenation of BoxList fields as long as the field tensor shapes
  are equal except for the first dimension.

  Args:
    boxlists: list of BoxList objects
    fields: optional list of fields to also concatenate.  By default, all
      fields from the first BoxList in the list are included in the
      concatenation.
    scope: name scope.

  Returns:
    a BoxList with number of boxes equal to
      sum([boxlist.num_boxes() for boxlist in BoxList])
  Raises:
    ValueError: if boxlists is invalid (i.e., is not a list, is empty, or
      contains non BoxList objects), or if requested fields are not contained in
      all boxlists
  """
    with tf.name_scope(scope, 'Concatenate'):
        if not isinstance(boxlists, list):
            raise ValueError('boxlists should be a list')
        if not boxlists:
            raise ValueError('boxlists should have nonzero length')
        for boxlist in boxlists:
            if not isinstance(boxlist, box_list.BoxList):
                raise ValueError(
                    'all elements of boxlists should be BoxList objects')
        concatenated = box_list.BoxList(
            tf.concat([boxlist.get() for boxlist in boxlists], 0))
        if fields is None:
            fields = boxlists[0].get_extra_fields()
        for field in fields:
            first_field_shape = boxlists[0].get_field(
                field).get_shape().as_list()
            first_field_shape[0] = -1
            if None in first_field_shape:
                raise ValueError(
                    'field %s must have fully defined shape except for the'
                    ' 0th dimension.' % field)
            for boxlist in boxlists:
                if not boxlist.has_field(field):
                    raise ValueError(
                        'boxlist must contain all requested fields')
                field_shape = boxlist.get_field(field).get_shape().as_list()
                field_shape[0] = -1
                if field_shape != first_field_shape:
                    raise ValueError(
                        'field %s must have same shape for all boxlists '
                        'except for the 0th dimension.' % field)
            concatenated_field = tf.concat(
                [boxlist.get_field(field) for boxlist in boxlists], 0)
            concatenated.add_field(field, concatenated_field)
        return concatenated
예제 #21
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)
  def test_get_correct_pairwise_similarity_based_on_thresholded_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],
                            [0.0, 0.0, 20.0, 20.0]])
    scores = tf.constant([.3, .6])
    iou_threshold = .013

    exp_output = tf.constant([[0.3, 0., 0.3], [0.6, 0., 0.]])
    boxes1 = box_list.BoxList(corners1)
    boxes1.add_field(fields.BoxListFields.scores, scores)
    boxes2 = box_list.BoxList(corners2)
    iou_similarity_calculator = (
        region_similarity_calculator.ThresholdedIouSimilarity(
            iou_threshold=iou_threshold))
    iou_similarity = iou_similarity_calculator.compare(boxes1, boxes2)
    with self.test_session() as sess:
      iou_output = sess.run(iou_similarity)
      self.assertAllClose(iou_output, exp_output)
 def test_get_correct_pairwise_similarity_based_on_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_similarity_calculator = region_similarity_calculator.IoaSimilarity()
   ioa_similarity_1 = ioa_similarity_calculator.compare(boxes1, boxes2)
   ioa_similarity_2 = ioa_similarity_calculator.compare(boxes2, boxes1)
   with self.test_session() as sess:
     iou_output_1, iou_output_2 = sess.run(
         [ioa_similarity_1, ioa_similarity_2])
     self.assertAllClose(iou_output_1, exp_output_1)
     self.assertAllClose(iou_output_2, exp_output_2)
예제 #24
0
def tile_anchors(grid_height, grid_width, scales, aspect_ratios,
                 base_anchor_size, anchor_stride, anchor_offset):
    """Create a tiled set of anchors strided along a grid in image space.

  This op creates a set of anchor boxes by placing a "basis" collection of
  boxes with user-specified scales and aspect ratios centered at evenly
  distributed points along a grid.  The basis collection is specified via the
  scale and aspect_ratios arguments.  For example, setting scales=[.1, .2, .2]
  and aspect ratios = [2,2,1/2] means that we create three boxes: one with scale
  .1, aspect ratio 2, one with scale .2, aspect ratio 2, and one with scale .2
  and aspect ratio 1/2.  Each box is multiplied by "base_anchor_size" before
  placing it over its respective center.

  Grid points are specified via grid_height, grid_width parameters as well as
  the anchor_stride and anchor_offset parameters.

  Args:
    grid_height: size of the grid in the y direction (int or int scalar tensor)
    grid_width: size of the grid in the x direction (int or int scalar tensor)
    scales: a 1-d  (float) tensor representing the scale of each box in the
      basis set.
    aspect_ratios: a 1-d (float) tensor representing the aspect ratio of each
      box in the basis set.  The length of the scales and aspect_ratios tensors
      must be equal.
    base_anchor_size: base anchor size as [height, width]
      (float tensor of shape [2])
    anchor_stride: difference in centers between base anchors for adjacent grid
                   positions (float tensor of shape [2])
    anchor_offset: center of the anchor with scale and aspect ratio 1 for the
                   upper left element of the grid, this should be zero for
                   feature networks with only VALID padding and even receptive
                   field size, but may need some additional calculation if other
                   padding is used (float tensor of shape [2])
  Returns:
    a BoxList holding a collection of N anchor boxes
  """
    ratio_sqrts = tf.sqrt(aspect_ratios)
    heights = scales / ratio_sqrts * base_anchor_size[0]
    widths = scales * ratio_sqrts * base_anchor_size[1]

    # Get a grid of box centers
    y_centers = tf.cast(tf.range(grid_height), dtype=tf.float32)
    y_centers = y_centers * anchor_stride[0] + anchor_offset[0]
    x_centers = tf.cast(tf.range(grid_width), dtype=tf.float32)
    x_centers = x_centers * anchor_stride[1] + anchor_offset[1]
    x_centers, y_centers = ops.meshgrid(x_centers, y_centers)

    widths_grid, x_centers_grid = ops.meshgrid(widths, x_centers)
    heights_grid, y_centers_grid = ops.meshgrid(heights, y_centers)
    bbox_centers = tf.stack([y_centers_grid, x_centers_grid], axis=3)
    bbox_sizes = tf.stack([heights_grid, widths_grid], axis=3)
    bbox_centers = tf.reshape(bbox_centers, [-1, 2])
    bbox_sizes = tf.reshape(bbox_sizes, [-1, 2])
    bbox_corners = _center_size_bbox_to_corners_bbox(bbox_centers, bbox_sizes)
    return box_list.BoxList(bbox_corners)
예제 #25
0
    def test_batch_decode(self):
        mock_anchor_corners = tf.constant(
            [[0, 0.1, 0.2, 0.3], [0.2, 0.4, 0.4, 0.6]], tf.float32)
        mock_anchors = box_list.BoxList(mock_anchor_corners)
        mock_box_coder = MockBoxCoder()

        expected_boxes = [[[0.0, 0.1, 0.5, 0.6], [0.5, 0.6, 0.7, 0.8]],
                          [[0.1, 0.2, 0.3, 0.4], [0.7, 0.8, 0.9, 1.0]]]

        encoded_boxes_list = [
            mock_box_coder.encode(box_list.BoxList(tf.constant(boxes)),
                                  mock_anchors) for boxes in expected_boxes
        ]
        encoded_boxes = tf.stack(encoded_boxes_list)
        decoded_boxes = box_coder.batch_decode(encoded_boxes, mock_box_coder,
                                               mock_anchors)

        with self.test_session() as sess:
            decoded_boxes_result = sess.run(decoded_boxes)
            self.assertAllClose(expected_boxes, decoded_boxes_result)
예제 #26
0
 def test_get_correct_relative_codes_after_encoding(self):
     boxes = [[10., 10., 20., 15.], [0.2, 0.1, 0.5, 0.4]]
     keypoints = [[[15., 12.], [10., 15.]], [[0.5, 0.3], [0.2, 0.4]]]
     num_keypoints = len(keypoints[0])
     anchors = [[15., 12., 30., 18.], [0.1, 0.0, 0.7, 0.9]]
     expected_rel_codes = [[
         -0.5, -0.416666, -0.405465, -0.182321, -0.5, -0.5, -0.833333, 0.
     ],
                           [
                               -0.083333, -0.222222, -0.693147, -1.098612,
                               0.166667, -0.166667, -0.333333, -0.055556
                           ]]
     boxes = box_list.BoxList(tf.constant(boxes))
     boxes.add_field(fields.BoxListFields.keypoints, tf.constant(keypoints))
     anchors = box_list.BoxList(tf.constant(anchors))
     coder = keypoint_box_coder.KeypointBoxCoder(num_keypoints)
     rel_codes = coder.encode(boxes, anchors)
     with self.test_session() as sess:
         rel_codes_out, = sess.run([rel_codes])
         self.assertAllClose(rel_codes_out, expected_rel_codes)
예제 #27
0
 def test_correct_boxes_with_non_default_scale(self):
     anchors = [[15.0, 12.0, 30.0, 18.0], [0.1, 0.0, 0.7, 0.9]]
     rel_codes = [[-1., -1.25, -1.62186], [-0.166667, -0.666667, -2.772588]]
     scale_factors = [2, 3, 4]
     expected_boxes = [[14.594306, 7.884875, 20.918861, 14.209432],
                       [0.155051, 0.102989, 0.522474, 0.470412]]
     anchors = box_list.BoxList(tf.constant(anchors))
     coder = square_box_coder.SquareBoxCoder(scale_factors=scale_factors)
     boxes = coder.decode(rel_codes, anchors)
     with self.test_session() as sess:
         (boxes_out, ) = sess.run([boxes.get()])
         self.assertAllClose(boxes_out, expected_boxes)
예제 #28
0
  def testGetCorrectBoxesAfterDecoding(self):
    rel_codes = tf.constant([[0.0, 0.0, 0.0, 0.0], [-5.0, -5.0, -5.0, -3.0]])
    expected_box_corners = [[0.0, 0.0, 0.5, 0.5], [0.0, 0.0, 0.5, 0.5]]
    prior_means = tf.constant([[0.0, 0.0, 0.5, 0.5], [0.5, 0.5, 1.0, 0.8]])
    priors = box_list.BoxList(prior_means)

    coder = mean_stddev_box_coder.MeanStddevBoxCoder(stddev=0.1)
    decoded_boxes = coder.decode(rel_codes, priors)
    decoded_box_corners = decoded_boxes.get()
    with self.test_session() as sess:
      decoded_out = sess.run(decoded_box_corners)
      self.assertAllClose(decoded_out, expected_box_corners)
예제 #29
0
 def _generate(self, feature_map_shape_list, im_height, im_width):
   return [
       box_list.BoxList(
           tf.constant(
               [
                   [0, 0, .5, .5],
                   [0, .5, .5, 1],
                   [.5, 0, 1, .5],
                   [1., 1., 1.5, 1.5]  # Anchor that is outside clip_window.
               ],
               tf.float32))
   ]
예제 #30
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)