def _generate(self, feature_map_shape_list, im_height, im_width): """Generates a collection of bounding boxes to be used as anchors. Currently we require the input image shape to be statically defined. That is, im_height and im_width should be integers rather than tensors. Args: feature_map_shape_list: list of pairs of convnet layer resolutions in the format [(height_0, width_0), (height_1, width_1), ...]. For example, setting feature_map_shape_list=[(8, 8), (7, 7)] asks for anchors that correspond to an 8x8 layer followed by a 7x7 layer. im_height: the height of the image to generate the grid for. im_width: the width of the image to generate the grid for. Returns: boxes_list: a list of BoxLists each holding anchor boxes corresponding to the input feature map shapes. Raises: ValueError: if im_height and im_width are not integers. """ if not isinstance(im_height, int) or not isinstance(im_width, int): raise ValueError( 'MultiscaleGridAnchorGenerator currently requires ' 'input image shape to be statically defined.') anchor_grid_list = [] for feat_shape, grid_info in zip(feature_map_shape_list, self._anchor_grid_info): # TODO(rathodv) check the feature_map_shape_list is consistent with # self._anchor_grid_info level = grid_info['level'] stride = 2**level scales, aspect_ratios, base_anchor_size, anchor_stride = grid_info[ 'info'] feat_h = feat_shape[0] feat_w = feat_shape[1] anchor_offset = [0, 0] if im_height % 2.0**level == 0: anchor_offset[0] = stride / 2.0 if im_width % 2.0**level == 0: anchor_offset[1] = stride / 2.0 ag = grid_anchor_generator.GridAnchorGenerator( scales, aspect_ratios, base_anchor_size=base_anchor_size, anchor_stride=anchor_stride, anchor_offset=anchor_offset) (anchor_grid, ) = ag.generate(feature_map_shape_list=[(feat_h, feat_w)]) if self._normalize_coordinates: anchor_grid = box_list_ops.to_normalized_coordinates( anchor_grid, im_height, im_width, check_range=False) anchor_grid_list.append(anchor_grid) return anchor_grid_list
def test_to_normalized_coordinates_already_normalized(self): coordinates = tf.constant([[0, 0, 1, 1], [0.25, 0.25, 0.75, 0.75]], tf.float32) img = tf.ones((128, 100, 100, 3)) boxlist = box_list.BoxList(coordinates) normalized_boxlist = box_list_ops.to_normalized_coordinates( boxlist, tf.shape(img)[1], tf.shape(img)[2]) with self.test_session() as sess: with self.assertRaisesOpError('assertion failed'): sess.run(normalized_boxlist.get())
def test_to_normalized_coordinates(self): coordinates = tf.constant([[0, 0, 100, 100], [25, 25, 75, 75]], tf.float32) img = tf.ones((128, 100, 100, 3)) boxlist = box_list.BoxList(coordinates) normalized_boxlist = box_list_ops.to_normalized_coordinates( boxlist, tf.shape(img)[1], tf.shape(img)[2]) expected_boxes = [[0, 0, 1, 1], [0.25, 0.25, 0.75, 0.75]] with self.test_session() as sess: normalized_boxes = sess.run(normalized_boxlist.get()) self.assertAllClose(normalized_boxes, expected_boxes)
def test_convert_to_absolute_and_back(self): coordinates = np.random.uniform(size=(100, 4)) coordinates = np.sort(coordinates) coordinates[99, :] = [0, 0, 1, 1] img = tf.ones((128, 202, 202, 3)) boxlist = box_list.BoxList(tf.constant(coordinates, tf.float32)) boxlist = box_list_ops.to_absolute_coordinates(boxlist, tf.shape(img)[1], tf.shape(img)[2]) boxlist = box_list_ops.to_normalized_coordinates(boxlist, tf.shape(img)[1], tf.shape(img)[2]) with self.test_session() as sess: out = sess.run(boxlist.get()) self.assertAllClose(out, coordinates)