| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| """Tests for the COCO Instance AP metric.""" |
|
|
| from absl import logging |
| import numpy as np |
| import tensorflow as tf |
|
|
| from deeplab2.evaluation import coco_instance_ap |
| from deeplab2.evaluation import test_utils |
|
|
| |
| |
| _CLASS_COLOR_MAP = { |
| (0, 0, 0): 0, |
| (0, 0, 255): 1, |
| (255, 0, 0): 2, |
| (0, 255, 0): 3, |
| (255, 0, 255): 4, |
| (0, 255, 255): 5, |
| (255, 255, 0): 6, |
| } |
|
|
|
|
| def combine_maps(semantic_map, instance_map, label_divisor): |
| combined_map = instance_map + semantic_map * label_divisor |
| return tf.cast(combined_map, tf.int32) |
|
|
|
|
| class CocoInstanceApTest(tf.test.TestCase): |
|
|
| def test_evaluates_single_image(self): |
| groundtruth_boxes = [ |
| [0.25, 0.4, 0.75, 1.0], |
| ] |
| groundtruth_classes = [8] |
| groundtruth_masks = [[ |
| [0, 0, 0, 0, 0], |
| [0, 0, 1, 1, 0], |
| [0, 0, 1, 1, 1], |
| [0, 0, 0, 0, 0], |
| ]] |
| groundtruth_is_crowd = [False] |
|
|
| detection_masks = [[ |
| [0, 0, 0, 0, 0], |
| [0, 0, 1, 1, 0], |
| [0, 0, 1, 1, 0], |
| [0, 0, 0, 0, 0], |
| ]] |
| detection_scores = [0.8] |
| detection_classes = [8] |
|
|
| groundtruth_boxes = tf.constant(groundtruth_boxes, dtype=tf.float32) |
| groundtruth_classes = tf.constant(groundtruth_classes, dtype=tf.int32) |
| groundtruth_masks = tf.constant(groundtruth_masks, dtype=tf.uint8) |
| groundtruth_is_crowd = tf.constant(groundtruth_is_crowd, dtype=tf.bool) |
|
|
| detection_masks = tf.constant(detection_masks, dtype=tf.uint8) |
| detection_scores = tf.constant(detection_scores, dtype=tf.float32) |
| detection_classes = tf.constant(detection_classes, dtype=tf.int32) |
|
|
| metric_obj = coco_instance_ap.InstanceAveragePrecision() |
| metric_obj.update_state(groundtruth_boxes, groundtruth_classes, |
| groundtruth_masks, groundtruth_is_crowd, |
| detection_masks, detection_scores, |
| detection_classes) |
| result = metric_obj.result().numpy() |
|
|
| |
| |
| expected_result = [0.7, 1, 1, 0.7, -1, -1, 0.7, 0.7, 0.7, 0.7, -1, -1] |
| np.testing.assert_array_almost_equal(result, expected_result) |
|
|
|
|
| class PanopticInstanceApTest(tf.test.TestCase): |
|
|
| def test_evaluates_single_image(self): |
| num_classes = 3 |
| things_list = [1, 2] |
| label_divisor = 256 |
| ignore_label = 0 |
| instance_class_map = { |
| 0: 0, |
| 47: 1, |
| 97: 1, |
| 133: 1, |
| 150: 1, |
| 174: 1, |
| 198: 2, |
| 215: 1, |
| 244: 1, |
| 255: 1, |
| } |
| gt_instances, gt_classes = test_utils.panoptic_segmentation_with_class_map( |
| 'team_gt_instance.png', instance_class_map) |
| gt_panoptic = combine_maps(gt_classes, gt_instances, label_divisor) |
|
|
| pred_classes = test_utils.read_segmentation_with_rgb_color_map( |
| 'team_pred_class.png', _CLASS_COLOR_MAP) |
| pred_instances = test_utils.read_test_image( |
| 'team_pred_instance.png', image_format='L') |
|
|
| pred_panoptic = combine_maps(pred_classes, pred_instances, label_divisor) |
| semantic_probability = tf.ones( |
| tf.concat([tf.shape(pred_panoptic), [num_classes]], 0)) |
| instance_score_map = tf.ones(tf.shape(pred_panoptic)) |
|
|
| metric_obj = coco_instance_ap.PanopticInstanceAveragePrecision( |
| num_classes, things_list, label_divisor, ignore_label) |
| metric_obj.update_state(gt_panoptic, pred_panoptic, semantic_probability, |
| instance_score_map) |
|
|
| result = metric_obj.result().numpy() |
| logging.info('result = %s', result) |
|
|
| expected_result = [ |
| 0.2549, 0.9356, 0.1215, -1.0, 0.2399, 0.501, 0.0812, 0.2688, 0.2688, |
| -1.0, 0.2583, 0.5 |
| ] |
| np.testing.assert_almost_equal(result, expected_result, decimal=4) |
|
|
| def test_evaluates_with_scores(self): |
| num_classes = 3 |
| things_list = list(range(num_classes)) |
| label_divisor = 256 |
| ignore_label = 0 |
| gt_classes = tf.constant([ |
| [1, 1, 2, 2], |
| [1, 1, 2, 2], |
| [0, 0, 2, 2], |
| [0, 0, 2, 2], |
| ], tf.int32) |
| pred_classes = tf.constant([ |
| [1, 1, 1, 1], |
| [1, 1, 1, 1], |
| [0, 0, 2, 2], |
| [0, 0, 2, 2], |
| ], tf.int32) |
| instances = tf.constant([ |
| [1, 1, 2, 2], |
| [1, 1, 2, 2], |
| [0, 0, 3, 3], |
| [0, 0, 3, 3], |
| ], tf.int32) |
|
|
| gt_panoptic = combine_maps(gt_classes, instances, label_divisor) |
| pred_panoptic = combine_maps(pred_classes, instances, label_divisor) |
|
|
| semantic_probability = tf.constant([ |
| [ |
| [0, 0, 0, 0], |
| [0, 0, 0, 0], |
| [1, 1, 0, 0], |
| [1, 1, 0, 0], |
| ], |
| [ |
| [1, 1, 1, 1], |
| [1, 1, 1, 1], |
| [0, 0, 0, 0], |
| [0, 0, 0, 0], |
| ], |
| [ |
| [0, 0, 0, 0], |
| [0, 0, 0, 0], |
| [0, 0, 1, 1], |
| [0, 0, 1, 1], |
| ], |
| ], tf.float32) |
| semantic_probability = tf.transpose(semantic_probability, [1, 2, 0]) |
|
|
| |
| bad_instance_scores = tf.constant([ |
| [0.4, 0.4, 0.9, 0.9], |
| [0.4, 0.4, 0.9, 0.9], |
| [0.0, 0.0, 0.8, 0.8], |
| [0.0, 0.0, 0.8, 0.8], |
| ], tf.float32) |
| metric_obj = coco_instance_ap.PanopticInstanceAveragePrecision( |
| num_classes, things_list, label_divisor, ignore_label) |
| metric_obj.update_state(gt_panoptic, pred_panoptic, semantic_probability, |
| bad_instance_scores) |
|
|
| bad_result = metric_obj.result().numpy() |
| logging.info('bad_result = %s', bad_result) |
| expected_bad_result = [ |
| 0.5025, 0.5025, 0.5025, 0.5025, -1., -1., 0.25, 0.75, 0.75, 0.75, -1., |
| -1. |
| ] |
| np.testing.assert_almost_equal(bad_result, expected_bad_result, decimal=4) |
|
|
| |
| good_instance_scores = tf.constant([ |
| [0.9, 0.9, 0.4, 0.4], |
| [0.9, 0.9, 0.4, 0.4], |
| [0.0, 0.0, 0.8, 0.8], |
| [0.0, 0.0, 0.8, 0.8], |
| ], tf.float32) |
| metric_obj.reset_states() |
| metric_obj.update_state(gt_panoptic, pred_panoptic, semantic_probability, |
| good_instance_scores) |
|
|
| good_result = metric_obj.result().numpy() |
| logging.info('good_result = %s', good_result) |
|
|
| |
| |
| expected_good_result = [ |
| 0.75248, 0.75248, 0.75248, 0.75248, -1, -1, 0.75, 0.75, 0.75, 0.75, -1, |
| -1 |
| ] |
| np.testing.assert_almost_equal(good_result, expected_good_result, decimal=4) |
|
|
| def test_ignores_crowds(self): |
| num_classes = 3 |
| things_list = list(range(num_classes)) |
| label_divisor = 256 |
| ignore_label = 0 |
| gt_classes = tf.constant([ |
| [1, 1, 2, 2], |
| [1, 1, 2, 2], |
| [0, 0, 2, 2], |
| [0, 0, 2, 2], |
| ], tf.int32) |
| pred_classes = tf.constant([ |
| [1, 1, 1, 1], |
| [1, 1, 1, 1], |
| [0, 0, 2, 2], |
| [0, 0, 2, 2], |
| ], tf.int32) |
| instances = tf.constant([ |
| [1, 1, 2, 2], |
| [1, 1, 2, 2], |
| [0, 0, 3, 3], |
| [0, 0, 3, 3], |
| ], tf.int32) |
| is_crowd_map = tf.math.equal(instances, 2) |
|
|
| gt_panoptic = combine_maps(gt_classes, instances, label_divisor) |
| pred_panoptic = combine_maps(pred_classes, instances, label_divisor) |
|
|
| semantic_probability = tf.ones( |
| tf.concat([tf.shape(pred_panoptic), [num_classes]], 0)) |
| instance_score_map = tf.ones(tf.shape(pred_panoptic)) |
|
|
| metric_obj = coco_instance_ap.PanopticInstanceAveragePrecision( |
| num_classes, things_list, label_divisor, ignore_label) |
| metric_obj.update_state(gt_panoptic, pred_panoptic, semantic_probability, |
| instance_score_map, is_crowd_map) |
|
|
| result = metric_obj.result().numpy() |
| logging.info('result = %s', result) |
| |
| |
| expected_result = [1., 1., 1., 1., -1., -1., 1., 1., 1., 1., -1., -1.] |
| np.testing.assert_almost_equal(result, expected_result, decimal=4) |
|
|
| def test_ignores_stuff(self): |
| num_classes = 4 |
| things_list = [3] |
| label_divisor = 256 |
| ignore_label = 0 |
| gt_classes = tf.constant([ |
| [3, 3, 2, 2], |
| [3, 3, 2, 2], |
| [0, 0, 2, 2], |
| [0, 0, 2, 2], |
| ], tf.int32) |
| pred_classes = tf.constant([ |
| [3, 3, 1, 1], |
| [3, 3, 1, 1], |
| [0, 0, 2, 2], |
| [0, 0, 2, 2], |
| ], tf.int32) |
| instances = tf.constant([ |
| [1, 1, 2, 2], |
| [1, 1, 2, 2], |
| [0, 0, 3, 3], |
| [0, 0, 3, 3], |
| ], tf.int32) |
|
|
| gt_panoptic = combine_maps(gt_classes, instances, label_divisor) |
| pred_panoptic = combine_maps(pred_classes, instances, label_divisor) |
|
|
| semantic_probability = tf.ones( |
| tf.concat([tf.shape(pred_panoptic), [num_classes]], 0)) |
| instance_score_map = tf.ones(tf.shape(pred_panoptic)) |
|
|
| metric_obj = coco_instance_ap.PanopticInstanceAveragePrecision( |
| num_classes, things_list, label_divisor, ignore_label) |
| metric_obj.update_state(gt_panoptic, pred_panoptic, semantic_probability, |
| instance_score_map) |
|
|
| result = metric_obj.result().numpy() |
| logging.info('result = %s', result) |
| |
| |
| expected_result = [1., 1., 1., 1., -1., -1., 1., 1., 1., 1., -1., -1.] |
| np.testing.assert_almost_equal(result, expected_result, decimal=4) |
|
|
|
|
| if __name__ == '__main__': |
| tf.test.main() |
|
|