|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"""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() |
|
|