def test_batch_multiclass_nms_with_batch_size_1(self): boxes = tf.constant([[[[0, 0, 1, 1], [0, 0, 4, 5]], [[0, 0.1, 1, 1.1], [0, 0.1, 2, 1.1]], [[0, -0.1, 1, 0.9], [0, -0.1, 1, 0.9]], [[0, 10, 1, 11], [0, 10, 1, 11]], [[0, 10.1, 1, 11.1], [0, 10.1, 1, 11.1]], [[0, 100, 1, 101], [0, 100, 1, 101]], [[0, 1000, 1, 1002], [0, 999, 2, 1004]], [[0, 1000, 1, 1002.1], [0, 999, 2, 1002.7]]]], tf.float32) scores = tf.constant([[[.9, 0.01], [.75, 0.05], [.6, 0.01], [.95, 0], [.5, 0.01], [.3, 0.01], [.01, .85], [.01, .5]]]) score_thresh = 0.1 iou_thresh = .5 max_output_size = 4 exp_nms_corners = [[[0, 10, 1, 11], [0, 0, 1, 1], [0, 999, 2, 1004], [0, 100, 1, 101]]] exp_nms_scores = [[.95, .9, .85, .3]] exp_nms_classes = [[0, 0, 1, 0]] nms_dict = post_processing.batch_multiclass_non_max_suppression( boxes, scores, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size) with self.test_session() as sess: nms_output = sess.run(nms_dict) self.assertAllClose(nms_output['detection_boxes'], exp_nms_corners) self.assertAllClose(nms_output['detection_scores'], exp_nms_scores) self.assertAllClose(nms_output['detection_classes'], exp_nms_classes) self.assertEqual(nms_output['num_detections'], [4])
def graph_fn(): boxes = tf.constant( [[[[0, 0, 1, 1]], [[0, 0.1, 1, 1.1]], [[0, -0.1, 1, 0.9]], [[0, 10, 1, 11]], [[0, 10.1, 1, 11.1]], [[0, 100, 1, 101]], [[0, 1000, 1, 1002]], [[0, 1000, 1, 1002.1]]]], tf.float32) scores = tf.constant([[[.9, 0.01], [.75, 0.05], [.6, 0.01], [.95, 0], [.5, 0.01], [.3, 0.01], [.01, .85], [.01, .5]]]) score_thresh = 0.1 iou_thresh = .5 max_output_size = 4 max_classes_per_detection = 1 use_class_agnostic_nms = True (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, nmsed_additional_fields, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes, scores, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size, use_class_agnostic_nms=use_class_agnostic_nms, use_static_shapes=use_static_shapes, max_classes_per_detection=max_classes_per_detection) self.assertIsNone(nmsed_masks) self.assertIsNone(nmsed_additional_fields) return (nmsed_boxes, nmsed_scores, nmsed_classes, num_detections)
def test_batch_multiclass_nms_with_masks_and_num_valid_boxes(self): boxes = tf.constant([[[[0, 0, 1, 1], [0, 0, 4, 5]], [[0, 0.1, 1, 1.1], [0, 0.1, 2, 1.1]], [[0, -0.1, 1, 0.9], [0, -0.1, 1, 0.9]], [[0, 10, 1, 11], [0, 10, 1, 11]]], [[[0, 10.1, 1, 11.1], [0, 10.1, 1, 11.1]], [[0, 100, 1, 101], [0, 100, 1, 101]], [[0, 1000, 1, 1002], [0, 999, 2, 1004]], [[0, 1000, 1, 1002.1], [0, 999, 2, 1002.7]]]], tf.float32) scores = tf.constant([[[.9, 0.01], [.75, 0.05], [.6, 0.01], [.95, 0]], [[.5, 0.01], [.3, 0.01], [.01, .85], [.01, .5]]]) masks = tf.constant([[[[[0, 1], [2, 3]], [[1, 2], [3, 4]]], [[[2, 3], [4, 5]], [[3, 4], [5, 6]]], [[[4, 5], [6, 7]], [[5, 6], [7, 8]]], [[[6, 7], [8, 9]], [[7, 8], [9, 10]]]], [[[[8, 9], [10, 11]], [[9, 10], [11, 12]]], [[[10, 11], [12, 13]], [[11, 12], [13, 14]]], [[[12, 13], [14, 15]], [[13, 14], [15, 16]]], [[[14, 15], [16, 17]], [[15, 16], [17, 18]]]]], tf.float32) num_valid_boxes = tf.constant([1, 1], tf.int32) score_thresh = 0.1 iou_thresh = .5 max_output_size = 4 exp_nms_corners = [[[0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 10.1, 1, 11.1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]] exp_nms_scores = [[.9, 0, 0, 0], [.5, 0, 0, 0]] exp_nms_classes = [[0, 0, 0, 0], [0, 0, 0, 0]] exp_nms_masks = [[[[0, 1], [2, 3]], [[0, 0], [0, 0]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]], [[[8, 9], [10, 11]], [[0, 0], [0, 0]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]]] (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes, scores, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size, num_valid_boxes=num_valid_boxes, masks=masks) with self.test_session() as sess: (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, num_detections) = sess.run([ nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, num_detections ]) self.assertAllClose(nmsed_boxes, exp_nms_corners) self.assertAllClose(nmsed_scores, exp_nms_scores) self.assertAllClose(nmsed_classes, exp_nms_classes) self.assertAllClose(num_detections, [1, 1]) self.assertAllClose(nmsed_masks, exp_nms_masks)
def graph_fn(boxes, scores, clip_window): (nmsed_boxes, nmsed_scores, nmsed_classes, _, _, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes, scores, score_thresh, iou_thresh, max_size_per_class=max_output_size, clip_window=clip_window, use_static_shapes=True) return nmsed_boxes, nmsed_scores, nmsed_classes, num_detections
def _post_process(boxes, scores, additional_fields=None): """Applies post process to get the final detections. Args: boxes: A [batch_size, num_anchors, q, 4] float32 tensor containing detections. If `q` is 1 then same boxes are used for all classes otherwise, if `q` is equal to number of classes, class-specific boxes are used. scores: A [batch_size, num_anchors, num_classes] float32 tensor containing the scores for each of the `num_anchors` detections. The scores have to be non-negative when use_static_shapes is set True. Returns: num_detections: A [batch_size] int32 tensor indicating the number of valid detections per batch item. Only the top num_detections[i] entries in nms_boxes[i], nms_scores[i] and nms_class[i] are valid. The rest of the entries are zero paddings. nmsed_boxes: A [batch_size, max_detections, 4] float32 tensor containing the non-max suppressed boxes. nmsed_scores: A [batch_size, max_detections] float32 tensor containing the scores for the boxes. nmsed_classes: A [batch_size, max_detections] float32 tensor containing the class for boxes. """ boxes = tf.expand_dims(boxes, axis=2) (nmsed_boxes, nmsed_scores, nmsed_classes, _, nmsed_additional_fields, num_detections) = batch_multiclass_non_max_suppression( boxes, scores, score_thresh=options.score_thresh, iou_thresh=options.iou_thresh, max_size_per_class=options.max_size_per_class, max_total_size=options.max_total_size, additional_fields=additional_fields) return num_detections, nmsed_boxes, nmsed_scores, nmsed_classes + 1, nmsed_additional_fields
def test_batch_multiclass_nms_with_per_image_clip_window(self): boxes = tf.constant([[[[0, 0, 1, 1], [0, 0, 4, 5]], [[0, 0.1, 1, 1.1], [0, 0.1, 2, 1.1]], [[0, -0.1, 1, 0.9], [0, -0.1, 1, 0.9]], [[0, 10, 1, 11], [0, 10, 1, 11]]], [[[0, 10.1, 1, 11.1], [0, 10.1, 1, 11.1]], [[0, 100, 1, 101], [0, 100, 1, 101]], [[0, 1000, 1, 1002], [0, 999, 2, 1004]], [[0, 1000, 1, 1002.1], [0, 999, 2, 1002.7]]]], tf.float32) scores = tf.constant([[[.9, 0.01], [.75, 0.05], [.6, 0.01], [.95, 0]], [[.5, 0.01], [.3, 0.01], [.01, .85], [.01, .5]]]) clip_window = tf.constant([[0., 0., 5., 5.], [0., 0., 200., 200.]]) score_thresh = 0.1 iou_thresh = .5 max_output_size = 4 exp_nms_corners = np.array([[[0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 10.1, 1, 11.1], [0, 100, 1, 101], [0, 0, 0, 0], [0, 0, 0, 0]]]) exp_nms_scores = np.array([[.9, 0., 0., 0.], [.5, .3, 0, 0]]) exp_nms_classes = np.array([[0, 0, 0, 0], [0, 0, 0, 0]]) (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, nmsed_additional_fields, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes, scores, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size, clip_window=clip_window) self.assertIsNone(nmsed_masks) self.assertIsNone(nmsed_additional_fields) # Check static shapes self.assertAllEqual(nmsed_boxes.shape.as_list(), exp_nms_corners.shape) self.assertAllEqual(nmsed_scores.shape.as_list(), exp_nms_scores.shape) self.assertAllEqual(nmsed_classes.shape.as_list(), exp_nms_classes.shape) self.assertEqual(num_detections.shape.as_list(), [2]) with self.test_session() as sess: (nmsed_boxes, nmsed_scores, nmsed_classes, num_detections) = sess.run([nmsed_boxes, nmsed_scores, nmsed_classes, num_detections]) self.assertAllClose(nmsed_boxes, exp_nms_corners) self.assertAllClose(nmsed_scores, exp_nms_scores) self.assertAllClose(nmsed_classes, exp_nms_classes) self.assertAllClose(num_detections, [1, 2])
def graph_fn(boxes, scores): (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, nmsed_additional_fields, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes, scores, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size) self.assertIsNone(nmsed_masks) self.assertIsNone(nmsed_additional_fields) return (nmsed_boxes, nmsed_scores, nmsed_classes, num_detections)
def graph_fn(boxes, scores, keypoints, size, num_valid_boxes): additional_fields = {'keypoints': keypoints, 'size': size} (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, nmsed_additional_fields, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes, scores, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size, num_valid_boxes=num_valid_boxes, additional_fields=additional_fields) self.assertIsNone(nmsed_masks) return (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_additional_fields['keypoints'], nmsed_additional_fields['size'], num_detections)
def det_post_process(params, class_outputs, box_outputs, scales): from object_detection.core.post_processing import \ batch_multiclass_non_max_suppression cls_outputs_all, box_outputs_all = [], [] for level in range(params['min_level'], params['max_level'] + 1): cls_outputs_all.append( tf.reshape(class_outputs[level], [params['batch_size'], -1, params['num_classes']])) box_outputs_all.append( tf.reshape(box_outputs[level], [params['batch_size'], -1, 4])) cls_outputs_all = tf.concat(cls_outputs_all, 1) box_outputs_all = tf.concat(box_outputs_all, 1) probs = tf.math.sigmoid(cls_outputs_all) # Generate location of anchors. eval_anchors = tf.transpose( anchors.Anchors(params['min_level'], params['max_level'], params['num_scales'], params['aspect_ratios'], params['anchor_scale'], params['image_size']).boxes) ycenter_a = (eval_anchors[0] + eval_anchors[2]) / 2 xcenter_a = (eval_anchors[1] + eval_anchors[3]) / 2 ha = eval_anchors[2] - eval_anchors[0] wa = eval_anchors[3] - eval_anchors[1] # Generate absolute bboxes in the units of pixels of the image. box_outputs_per_sample = tf.transpose(box_outputs_all[0]) ty, tx, th, tw = (box_outputs_per_sample[0], box_outputs_per_sample[1], box_outputs_per_sample[2], box_outputs_per_sample[3]) w, h = tf.math.exp(tw) * wa, tf.math.exp(th) * ha ycenter, xcenter = ty * ha + ycenter_a, tx * wa + xcenter_a ymin, ymax = ycenter - h / 2.0, ycenter + h / 2.0 xmin, xmax = xcenter - w / 2.0, xcenter + w / 2.0 boxes = tf.transpose(tf.stack([ymin, xmin, ymax, xmax])) # Generate the outputs boxes_all = tf.reshape(boxes, [params['batch_size'], -1, 1, 4]) probs_all = tf.reshape( probs, [params['batch_size'], -1, params['num_classes']]) (boxes_tf, scores_tf, classes_tf, _, _, num_detections_tf) = \ batch_multiclass_non_max_suppression( boxes=boxes_all, scores=probs_all, score_thresh=0.5, iou_thresh=0.5, max_size_per_class=anchors.MAX_DETECTIONS_PER_IMAGE, max_total_size=anchors.MAX_DETECTIONS_PER_IMAGE, use_combined_nms=False, use_class_agnostic_nms=True) boxes_tf *= scales return [boxes_tf, scores_tf, classes_tf, num_detections_tf]
def graph_fn(boxes, scores, masks): (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, nmsed_additional_fields, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes, scores, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size, masks=masks) self.assertIsNone(nmsed_additional_fields) # Check static shapes self.assertAllEqual(nmsed_boxes.shape.as_list(), exp_nms_corners.shape) self.assertAllEqual(nmsed_scores.shape.as_list(), exp_nms_scores.shape) self.assertAllEqual(nmsed_classes.shape.as_list(), exp_nms_classes.shape) self.assertAllEqual(nmsed_masks.shape.as_list(), exp_nms_masks.shape) self.assertEqual(num_detections.shape.as_list(), [2]) return (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, num_detections)
def test_combined_nms_with_batch_size_2(self): """Test use_combined_nms.""" boxes = tf.constant([[[[0, 0, 0.1, 0.1], [0, 0, 0.1, 0.1]], [[0, 0.01, 1, 0.11], [0, 0.6, 0.1, 0.7]], [[0, -0.01, 0.1, 0.09], [0, -0.1, 0.1, 0.09]], [[0, 0.11, 0.1, 0.2], [0, 0.11, 0.1, 0.2]]], [[[0, 0, 0.2, 0.2], [0, 0, 0.2, 0.2]], [[0, 0.02, 0.2, 0.22], [0, 0.02, 0.2, 0.22]], [[0, -0.02, 0.2, 0.19], [0, -0.02, 0.2, 0.19]], [[0, 0.21, 0.2, 0.3], [0, 0.21, 0.2, 0.3]]]], tf.float32) scores = tf.constant([[[.1, 0.9], [.75, 0.8], [.6, 0.3], [0.95, 0.1]], [[.1, 0.9], [.75, 0.8], [.6, .3], [.95, .1]]]) score_thresh = 0.1 iou_thresh = .5 max_output_size = 3 exp_nms_corners = np.array([[[0, 0.11, 0.1, 0.2], [0, 0, 0.1, 0.1], [0, 0.6, 0.1, 0.7]], [[0, 0.21, 0.2, 0.3], [0, 0, 0.2, 0.2], [0, 0.02, 0.2, 0.22]]]) exp_nms_scores = np.array([[.95, .9, 0.8], [.95, .9, .75]]) exp_nms_classes = np.array([[0, 1, 1], [0, 1, 0]]) (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, nmsed_additional_fields, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes, scores, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size, use_static_shapes=True, use_combined_nms=True) self.assertIsNone(nmsed_masks) self.assertIsNone(nmsed_additional_fields) with self.test_session() as sess: (nmsed_boxes, nmsed_scores, nmsed_classes, num_detections) = sess.run( [nmsed_boxes, nmsed_scores, nmsed_classes, num_detections]) self.assertAllClose(nmsed_boxes, exp_nms_corners) self.assertAllClose(nmsed_scores, exp_nms_scores) self.assertAllClose(nmsed_classes, exp_nms_classes) self.assertListEqual(num_detections.tolist(), [3, 3])
def _post_process(self, boxes, scores, score_thresh=1e-6, iou_thresh=0.5, max_size_per_class=100, max_total_size=300): """Applies post process to get the final detections. Args: boxes: A [batch_size, num_anchors, q, 4] float32 tensor containing detections. If `q` is 1 then same boxes are used for all classes otherwise, if `q` is equal to number of classes, class-specific boxes are used. scores: A [batch_size, num_anchors, num_classes] float32 tensor containing the scores for each of the `num_anchors` detections. The scores have to be non-negative when use_static_shapes is set True. score_thresh: scalar threshold for score (low scoring boxes are removed). iou_thresh: scalar threshold for IOU (new boxes that have high IOU overlap with previously selected boxes are removed). max_size_per_class: maximum number of retained boxes per class. max_total_size: maximum number of boxes retained over all classes. By default returns all boxes retained after capping boxes per class. Returns: num_detections: A [batch_size] int32 tensor indicating the number of valid detections per batch item. Only the top num_detections[i] entries in nms_boxes[i], nms_scores[i] and nms_class[i] are valid. The rest of the entries are zero paddings. nmsed_boxes: A [batch_size, max_detections, 4] float32 tensor containing the non-max suppressed boxes. nmsed_scores: A [batch_size, max_detections] float32 tensor containing the scores for the boxes. nmsed_classes: A [batch_size, max_detections] float32 tensor containing the class for boxes. """ boxes = tf.expand_dims(boxes, axis=2) (nmsed_boxes, nmsed_scores, nmsed_classes, _, _, num_detections) = batch_multiclass_non_max_suppression( boxes, scores, score_thresh=score_thresh, iou_thresh=iou_thresh, max_size_per_class=max_size_per_class, max_total_size=max_total_size) return num_detections, nmsed_boxes, nmsed_scores, nmsed_classes + 1
def test_batch_classagnostic_nms_with_batch_size_1(self, use_static_shapes=False ): boxes = tf.constant( [[[[0, 0, 1, 1]], [[0, 0.1, 1, 1.1]], [[0, -0.1, 1, 0.9]], [[0, 10, 1, 11]], [[0, 10.1, 1, 11.1]], [[0, 100, 1, 101]], [[0, 1000, 1, 1002]], [[0, 1000, 1, 1002.1]]]], tf.float32) scores = tf.constant([[[.9, 0.01], [.75, 0.05], [.6, 0.01], [.95, 0], [.5, 0.01], [.3, 0.01], [.01, .85], [.01, .5]]]) score_thresh = 0.1 iou_thresh = .5 max_output_size = 4 max_classes_per_detection = 1 use_class_agnostic_nms = True exp_nms_corners = [[[0, 10, 1, 11], [0, 0, 1, 1], [0, 1000, 1, 1002], [0, 100, 1, 101]]] exp_nms_scores = [[.95, .9, .85, .3]] exp_nms_classes = [[0, 0, 1, 0]] (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, nmsed_additional_fields, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes, scores, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size, use_class_agnostic_nms=use_class_agnostic_nms, use_static_shapes=use_static_shapes, max_classes_per_detection=max_classes_per_detection) self.assertIsNone(nmsed_masks) self.assertIsNone(nmsed_additional_fields) with self.test_session() as sess: (nmsed_boxes, nmsed_scores, nmsed_classes, num_detections) = sess.run( [nmsed_boxes, nmsed_scores, nmsed_classes, num_detections]) self.assertAllClose(nmsed_boxes, exp_nms_corners) self.assertAllClose(nmsed_scores, exp_nms_scores) self.assertAllClose(nmsed_classes, exp_nms_classes) self.assertEqual(num_detections, [4])
def test_batch_multiclass_nms_with_batch_size_1(self): boxes = tf.constant([[[[0, 0, 1, 1], [0, 0, 4, 5]], [[0, 0.1, 1, 1.1], [0, 0.1, 2, 1.1]], [[0, -0.1, 1, 0.9], [0, -0.1, 1, 0.9]], [[0, 10, 1, 11], [0, 10, 1, 11]], [[0, 10.1, 1, 11.1], [0, 10.1, 1, 11.1]], [[0, 100, 1, 101], [0, 100, 1, 101]], [[0, 1000, 1, 1002], [0, 999, 2, 1004]], [[0, 1000, 1, 1002.1], [0, 999, 2, 1002.7]]]], tf.float32) scores = tf.constant([[[.9, 0.01], [.75, 0.05], [.6, 0.01], [.95, 0], [.5, 0.01], [.3, 0.01], [.01, .85], [.01, .5]]]) score_thresh = 0.1 iou_thresh = .5 max_output_size = 4 exp_nms_corners = [[[0, 10, 1, 11], [0, 0, 1, 1], [0, 999, 2, 1004], [0, 100, 1, 101]]] exp_nms_scores = [[.95, .9, .85, .3]] exp_nms_classes = [[0, 0, 1, 0]] (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, nmsed_additional_fields, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes, scores, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size) self.assertIsNone(nmsed_masks) self.assertIsNone(nmsed_additional_fields) with self.test_session() as sess: (nmsed_boxes, nmsed_scores, nmsed_classes, num_detections) = sess.run([nmsed_boxes, nmsed_scores, nmsed_classes, num_detections]) self.assertAllClose(nmsed_boxes, exp_nms_corners) self.assertAllClose(nmsed_scores, exp_nms_scores) self.assertAllClose(nmsed_classes, exp_nms_classes) self.assertEqual(num_detections, [4])
def graph_fn(boxes, scores, keypoints, size): additional_fields = {'keypoints': keypoints, 'size': size} (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, nmsed_additional_fields, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes, scores, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size, additional_fields=additional_fields) self.assertIsNone(nmsed_masks) # Check static shapes self.assertAllEqual(nmsed_boxes.shape.as_list(), exp_nms_corners.shape) self.assertAllEqual(nmsed_scores.shape.as_list(), exp_nms_scores.shape) self.assertAllEqual(nmsed_classes.shape.as_list(), exp_nms_classes.shape) self.assertEqual(len(nmsed_additional_fields), len(exp_nms_additional_fields)) for key in exp_nms_additional_fields: self.assertAllEqual(nmsed_additional_fields[key].shape.as_list(), exp_nms_additional_fields[key].shape) self.assertEqual(num_detections.shape.as_list(), [2]) return (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_additional_fields['keypoints'], nmsed_additional_fields['size'], num_detections)
def test_batch_multiclass_nms_with_additional_fields_and_num_valid_boxes( self): boxes = tf.constant([[[[0, 0, 1, 1], [0, 0, 4, 5]], [[0, 0.1, 1, 1.1], [0, 0.1, 2, 1.1]], [[0, -0.1, 1, 0.9], [0, -0.1, 1, 0.9]], [[0, 10, 1, 11], [0, 10, 1, 11]]], [[[0, 10.1, 1, 11.1], [0, 10.1, 1, 11.1]], [[0, 100, 1, 101], [0, 100, 1, 101]], [[0, 1000, 1, 1002], [0, 999, 2, 1004]], [[0, 1000, 1, 1002.1], [0, 999, 2, 1002.7]]]], tf.float32) scores = tf.constant([[[.9, 0.01], [.75, 0.05], [.6, 0.01], [.95, 0]], [[.5, 0.01], [.3, 0.01], [.01, .85], [.01, .5]]]) additional_fields = { 'keypoints': tf.constant( [[[[6, 7], [8, 9]], [[0, 1], [2, 3]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]], [[[13, 14], [15, 16]], [[8, 9], [10, 11]], [[10, 11], [12, 13]], [[0, 0], [0, 0]]]], tf.float32) } num_valid_boxes = tf.constant([1, 1], tf.int32) score_thresh = 0.1 iou_thresh = .5 max_output_size = 4 exp_nms_corners = [[[0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 10.1, 1, 11.1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]] exp_nms_scores = [[.9, 0, 0, 0], [.5, 0, 0, 0]] exp_nms_classes = [[0, 0, 0, 0], [0, 0, 0, 0]] exp_nms_additional_fields = { 'keypoints': np.array([[[[6, 7], [8, 9]], [[0, 0], [0, 0]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]], [[[13, 14], [15, 16]], [[0, 0], [0, 0]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]]]) } (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, nmsed_additional_fields, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes, scores, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size, num_valid_boxes=num_valid_boxes, additional_fields=additional_fields) self.assertIsNone(nmsed_masks) with self.test_session() as sess: (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_additional_fields, num_detections) = sess.run([nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_additional_fields, num_detections]) self.assertAllClose(nmsed_boxes, exp_nms_corners) self.assertAllClose(nmsed_scores, exp_nms_scores) self.assertAllClose(nmsed_classes, exp_nms_classes) for key in exp_nms_additional_fields: self.assertAllClose(nmsed_additional_fields[key], exp_nms_additional_fields[key]) self.assertAllClose(num_detections, [1, 1])
def test_batch_multiclass_nms_with_masks_and_num_valid_boxes(self): boxes = tf.constant([[[[0, 0, 1, 1], [0, 0, 4, 5]], [[0, 0.1, 1, 1.1], [0, 0.1, 2, 1.1]], [[0, -0.1, 1, 0.9], [0, -0.1, 1, 0.9]], [[0, 10, 1, 11], [0, 10, 1, 11]]], [[[0, 10.1, 1, 11.1], [0, 10.1, 1, 11.1]], [[0, 100, 1, 101], [0, 100, 1, 101]], [[0, 1000, 1, 1002], [0, 999, 2, 1004]], [[0, 1000, 1, 1002.1], [0, 999, 2, 1002.7]]]], tf.float32) scores = tf.constant([[[.9, 0.01], [.75, 0.05], [.6, 0.01], [.95, 0]], [[.5, 0.01], [.3, 0.01], [.01, .85], [.01, .5]]]) masks = tf.constant([[[[[0, 1], [2, 3]], [[1, 2], [3, 4]]], [[[2, 3], [4, 5]], [[3, 4], [5, 6]]], [[[4, 5], [6, 7]], [[5, 6], [7, 8]]], [[[6, 7], [8, 9]], [[7, 8], [9, 10]]]], [[[[8, 9], [10, 11]], [[9, 10], [11, 12]]], [[[10, 11], [12, 13]], [[11, 12], [13, 14]]], [[[12, 13], [14, 15]], [[13, 14], [15, 16]]], [[[14, 15], [16, 17]], [[15, 16], [17, 18]]]]], tf.float32) num_valid_boxes = tf.constant([1, 1], tf.int32) score_thresh = 0.1 iou_thresh = .5 max_output_size = 4 exp_nms_corners = [[[0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 10.1, 1, 11.1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]] exp_nms_scores = [[.9, 0, 0, 0], [.5, 0, 0, 0]] exp_nms_classes = [[0, 0, 0, 0], [0, 0, 0, 0]] exp_nms_masks = [[[[0, 1], [2, 3]], [[0, 0], [0, 0]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]], [[[8, 9], [10, 11]], [[0, 0], [0, 0]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]]] (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, nmsed_additional_fields, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes, scores, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size, num_valid_boxes=num_valid_boxes, masks=masks) self.assertIsNone(nmsed_additional_fields) with self.test_session() as sess: (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, num_detections) = sess.run([nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, num_detections]) self.assertAllClose(nmsed_boxes, exp_nms_corners) self.assertAllClose(nmsed_scores, exp_nms_scores) self.assertAllClose(nmsed_classes, exp_nms_classes) self.assertAllClose(num_detections, [1, 1]) self.assertAllClose(nmsed_masks, exp_nms_masks)
def test_batch_multiclass_nms_with_dynamic_batch_size(self): boxes_placeholder = tf.placeholder(tf.float32, shape=(None, None, 2, 4)) scores_placeholder = tf.placeholder(tf.float32, shape=(None, None, 2)) masks_placeholder = tf.placeholder(tf.float32, shape=(None, None, 2, 2, 2)) boxes = np.array([[[[0, 0, 1, 1], [0, 0, 4, 5]], [[0, 0.1, 1, 1.1], [0, 0.1, 2, 1.1]], [[0, -0.1, 1, 0.9], [0, -0.1, 1, 0.9]], [[0, 10, 1, 11], [0, 10, 1, 11]]], [[[0, 10.1, 1, 11.1], [0, 10.1, 1, 11.1]], [[0, 100, 1, 101], [0, 100, 1, 101]], [[0, 1000, 1, 1002], [0, 999, 2, 1004]], [[0, 1000, 1, 1002.1], [0, 999, 2, 1002.7]]]]) scores = np.array([[[.9, 0.01], [.75, 0.05], [.6, 0.01], [.95, 0]], [[.5, 0.01], [.3, 0.01], [.01, .85], [.01, .5]]]) masks = np.array([[[[[0, 1], [2, 3]], [[1, 2], [3, 4]]], [[[2, 3], [4, 5]], [[3, 4], [5, 6]]], [[[4, 5], [6, 7]], [[5, 6], [7, 8]]], [[[6, 7], [8, 9]], [[7, 8], [9, 10]]]], [[[[8, 9], [10, 11]], [[9, 10], [11, 12]]], [[[10, 11], [12, 13]], [[11, 12], [13, 14]]], [[[12, 13], [14, 15]], [[13, 14], [15, 16]]], [[[14, 15], [16, 17]], [[15, 16], [17, 18]]]]]) score_thresh = 0.1 iou_thresh = .5 max_output_size = 4 exp_nms_corners = np.array([[[0, 10, 1, 11], [0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 999, 2, 1004], [0, 10.1, 1, 11.1], [0, 100, 1, 101], [0, 0, 0, 0]]]) exp_nms_scores = np.array([[.95, .9, 0, 0], [.85, .5, .3, 0]]) exp_nms_classes = np.array([[0, 0, 0, 0], [1, 0, 0, 0]]) exp_nms_masks = np.array([[[[6, 7], [8, 9]], [[0, 1], [2, 3]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]], [[[13, 14], [15, 16]], [[8, 9], [10, 11]], [[10, 11], [12, 13]], [[0, 0], [0, 0]]]]) (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, nmsed_additional_fields, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes_placeholder, scores_placeholder, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size, masks=masks_placeholder) self.assertIsNone(nmsed_additional_fields) # Check static shapes self.assertAllEqual(nmsed_boxes.shape.as_list(), [None, 4, 4]) self.assertAllEqual(nmsed_scores.shape.as_list(), [None, 4]) self.assertAllEqual(nmsed_classes.shape.as_list(), [None, 4]) self.assertAllEqual(nmsed_masks.shape.as_list(), [None, 4, 2, 2]) self.assertEqual(num_detections.shape.as_list(), [None]) with self.test_session() as sess: (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, num_detections) = sess.run([nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, num_detections], feed_dict={boxes_placeholder: boxes, scores_placeholder: scores, masks_placeholder: masks}) self.assertAllClose(nmsed_boxes, exp_nms_corners) self.assertAllClose(nmsed_scores, exp_nms_scores) self.assertAllClose(nmsed_classes, exp_nms_classes) self.assertAllClose(num_detections, [2, 3]) self.assertAllClose(nmsed_masks, exp_nms_masks)
def test_batch_multiclass_nms_with_additional_fields_and_num_valid_boxes( self): boxes = tf.constant([[[[0, 0, 1, 1], [0, 0, 4, 5]], [[0, 0.1, 1, 1.1], [0, 0.1, 2, 1.1]], [[0, -0.1, 1, 0.9], [0, -0.1, 1, 0.9]], [[0, 10, 1, 11], [0, 10, 1, 11]]], [[[0, 10.1, 1, 11.1], [0, 10.1, 1, 11.1]], [[0, 100, 1, 101], [0, 100, 1, 101]], [[0, 1000, 1, 1002], [0, 999, 2, 1004]], [[0, 1000, 1, 1002.1], [0, 999, 2, 1002.7]]]], tf.float32) scores = tf.constant([[[.9, 0.01], [.75, 0.05], [.6, 0.01], [.95, 0]], [[.5, 0.01], [.3, 0.01], [.01, .85], [.01, .5]]]) additional_fields = { 'keypoints': tf.constant([[[[6, 7], [8, 9]], [[0, 1], [2, 3]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]], [[[13, 14], [15, 16]], [[8, 9], [10, 11]], [[10, 11], [12, 13]], [[0, 0], [0, 0]]]], tf.float32) } additional_fields['size'] = tf.constant( [[[[7], [9]], [[1], [3]], [[0], [0]], [[0], [0]]], [[[14], [16]], [[9], [11]], [[11], [13]], [[0], [0]]]], tf.float32) num_valid_boxes = tf.constant([1, 1], tf.int32) score_thresh = 0.1 iou_thresh = .5 max_output_size = 4 exp_nms_corners = [[[0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 10.1, 1, 11.1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]] exp_nms_scores = [[.9, 0, 0, 0], [.5, 0, 0, 0]] exp_nms_classes = [[0, 0, 0, 0], [0, 0, 0, 0]] exp_nms_additional_fields = { 'keypoints': np.array([[[[6, 7], [8, 9]], [[0, 0], [0, 0]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]], [[[13, 14], [15, 16]], [[0, 0], [0, 0]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]]]) } exp_nms_additional_fields['size'] = np.array([[[[7], [9]], [[0], [0]], [[0], [0]], [[0], [0]]], [[[14], [16]], [[0], [0]], [[0], [0]], [[0], [0]]]]) (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, nmsed_additional_fields, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes, scores, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size, num_valid_boxes=num_valid_boxes, additional_fields=additional_fields) self.assertIsNone(nmsed_masks) with self.test_session() as sess: (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_additional_fields, num_detections) = sess.run([ nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_additional_fields, num_detections ]) self.assertAllClose(nmsed_boxes, exp_nms_corners) self.assertAllClose(nmsed_scores, exp_nms_scores) self.assertAllClose(nmsed_classes, exp_nms_classes) for key in exp_nms_additional_fields: self.assertAllClose(nmsed_additional_fields[key], exp_nms_additional_fields[key]) self.assertAllClose(num_detections, [1, 1])
def test_batch_multiclass_nms_with_dynamic_batch_size(self): boxes_placeholder = tf.placeholder(tf.float32, shape=(None, None, 2, 4)) scores_placeholder = tf.placeholder(tf.float32, shape=(None, None, 2)) masks_placeholder = tf.placeholder(tf.float32, shape=(None, None, 2, 2, 2)) boxes = np.array([[[[0, 0, 1, 1], [0, 0, 4, 5]], [[0, 0.1, 1, 1.1], [0, 0.1, 2, 1.1]], [[0, -0.1, 1, 0.9], [0, -0.1, 1, 0.9]], [[0, 10, 1, 11], [0, 10, 1, 11]]], [[[0, 10.1, 1, 11.1], [0, 10.1, 1, 11.1]], [[0, 100, 1, 101], [0, 100, 1, 101]], [[0, 1000, 1, 1002], [0, 999, 2, 1004]], [[0, 1000, 1, 1002.1], [0, 999, 2, 1002.7]]]]) scores = np.array([[[.9, 0.01], [.75, 0.05], [.6, 0.01], [.95, 0]], [[.5, 0.01], [.3, 0.01], [.01, .85], [.01, .5]]]) masks = np.array([[[[[0, 1], [2, 3]], [[1, 2], [3, 4]]], [[[2, 3], [4, 5]], [[3, 4], [5, 6]]], [[[4, 5], [6, 7]], [[5, 6], [7, 8]]], [[[6, 7], [8, 9]], [[7, 8], [9, 10]]]], [[[[8, 9], [10, 11]], [[9, 10], [11, 12]]], [[[10, 11], [12, 13]], [[11, 12], [13, 14]]], [[[12, 13], [14, 15]], [[13, 14], [15, 16]]], [[[14, 15], [16, 17]], [[15, 16], [17, 18]]]]]) score_thresh = 0.1 iou_thresh = .5 max_output_size = 4 exp_nms_corners = np.array([[[0, 10, 1, 11], [0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 999, 2, 1004], [0, 10.1, 1, 11.1], [0, 100, 1, 101], [0, 0, 0, 0]]]) exp_nms_scores = np.array([[.95, .9, 0, 0], [.85, .5, .3, 0]]) exp_nms_classes = np.array([[0, 0, 0, 0], [1, 0, 0, 0]]) exp_nms_masks = np.array([[[[6, 7], [8, 9]], [[0, 1], [2, 3]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]], [[[13, 14], [15, 16]], [[8, 9], [10, 11]], [[10, 11], [12, 13]], [[0, 0], [0, 0]]]]) (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, nmsed_additional_fields, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes_placeholder, scores_placeholder, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size, masks=masks_placeholder) self.assertIsNone(nmsed_additional_fields) # Check static shapes self.assertAllEqual(nmsed_boxes.shape.as_list(), [None, 4, 4]) self.assertAllEqual(nmsed_scores.shape.as_list(), [None, 4]) self.assertAllEqual(nmsed_classes.shape.as_list(), [None, 4]) self.assertAllEqual(nmsed_masks.shape.as_list(), [None, 4, 2, 2]) self.assertEqual(num_detections.shape.as_list(), [None]) with self.test_session() as sess: (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, num_detections) = sess.run( [ nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, num_detections ], feed_dict={ boxes_placeholder: boxes, scores_placeholder: scores, masks_placeholder: masks }) self.assertAllClose(nmsed_boxes, exp_nms_corners) self.assertAllClose(nmsed_scores, exp_nms_scores) self.assertAllClose(nmsed_classes, exp_nms_classes) self.assertAllClose(num_detections, [2, 3]) self.assertAllClose(nmsed_masks, exp_nms_masks)
def test_batch_multiclass_nms_with_additional_fields(self): boxes = tf.constant([[[[0, 0, 1, 1], [0, 0, 4, 5]], [[0, 0.1, 1, 1.1], [0, 0.1, 2, 1.1]], [[0, -0.1, 1, 0.9], [0, -0.1, 1, 0.9]], [[0, 10, 1, 11], [0, 10, 1, 11]]], [[[0, 10.1, 1, 11.1], [0, 10.1, 1, 11.1]], [[0, 100, 1, 101], [0, 100, 1, 101]], [[0, 1000, 1, 1002], [0, 999, 2, 1004]], [[0, 1000, 1, 1002.1], [0, 999, 2, 1002.7]]]], tf.float32) scores = tf.constant([[[.9, 0.01], [.75, 0.05], [.6, 0.01], [.95, 0]], [[.5, 0.01], [.3, 0.01], [.01, .85], [.01, .5]]]) additional_fields = { 'keypoints': tf.constant( [[[[6, 7], [8, 9]], [[0, 1], [2, 3]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]], [[[13, 14], [15, 16]], [[8, 9], [10, 11]], [[10, 11], [12, 13]], [[0, 0], [0, 0]]]], tf.float32) } score_thresh = 0.1 iou_thresh = .5 max_output_size = 4 exp_nms_corners = np.array([[[0, 10, 1, 11], [0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 999, 2, 1004], [0, 10.1, 1, 11.1], [0, 100, 1, 101], [0, 0, 0, 0]]]) exp_nms_scores = np.array([[.95, .9, 0, 0], [.85, .5, .3, 0]]) exp_nms_classes = np.array([[0, 0, 0, 0], [1, 0, 0, 0]]) exp_nms_additional_fields = { 'keypoints': np.array([[[[0, 0], [0, 0]], [[6, 7], [8, 9]], [[0, 0], [0, 0]], [[0, 0], [0, 0]]], [[[10, 11], [12, 13]], [[13, 14], [15, 16]], [[8, 9], [10, 11]], [[0, 0], [0, 0]]]]) } (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_masks, nmsed_additional_fields, num_detections ) = post_processing.batch_multiclass_non_max_suppression( boxes, scores, score_thresh, iou_thresh, max_size_per_class=max_output_size, max_total_size=max_output_size, additional_fields=additional_fields) self.assertIsNone(nmsed_masks) # Check static shapes self.assertAllEqual(nmsed_boxes.shape.as_list(), exp_nms_corners.shape) self.assertAllEqual(nmsed_scores.shape.as_list(), exp_nms_scores.shape) self.assertAllEqual(nmsed_classes.shape.as_list(), exp_nms_classes.shape) self.assertEqual(len(nmsed_additional_fields), len(exp_nms_additional_fields)) for key in exp_nms_additional_fields: self.assertAllEqual(nmsed_additional_fields[key].shape.as_list(), exp_nms_additional_fields[key].shape) self.assertEqual(num_detections.shape.as_list(), [2]) with self.test_session() as sess: (nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_additional_fields, num_detections) = sess.run([nmsed_boxes, nmsed_scores, nmsed_classes, nmsed_additional_fields, num_detections]) self.assertAllClose(nmsed_boxes, exp_nms_corners) self.assertAllClose(nmsed_scores, exp_nms_scores) self.assertAllClose(nmsed_classes, exp_nms_classes) for key in exp_nms_additional_fields: self.assertAllClose(nmsed_additional_fields[key], exp_nms_additional_fields[key]) self.assertAllClose(num_detections, [2, 3])