karolmajek/maxdeeplab
0
1# coding=utf-82# Copyright 2021 The Deeplab2 Authors.3#4# Licensed under the Apache License, Version 2.0 (the "License");5# you may not use this file except in compliance with the License.6# You may obtain a copy of the License at7#8# http://www.apache.org/licenses/LICENSE-2.09#10# Unless required by applicable law or agreed to in writing, software11# distributed under the License is distributed on an "AS IS" BASIS,12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13# See the License for the specific language governing permissions and14# limitations under the License.15 16"""Tests for sample_generator."""17 18import os19 20from absl import flags21import numpy as np22from PIL import Image23import tensorflow as tf24 25from deeplab2 import common26from deeplab2.data import data_utils27from deeplab2.data import dataset28from deeplab2.data import sample_generator29 30image_utils = tf.keras.preprocessing.image31 32flags.DEFINE_string(33 'panoptic_annotation_data',34 'deeplab2/data/testdata/',35 'Path to annotated test image.')36flags.DEFINE_bool('update_golden_data', False,37 'Whether or not to update the golden data for testing.')38 39FLAGS = flags.FLAGS40 41_FILENAME_PREFIX = 'dummy_000000_000000'42_IMAGE_FOLDER = 'leftImg8bit/'43_TARGET_FOLDER = 'targets/'44 45 46def _get_groundtruth_image(computed_image_array, groundtruth_image_filename):47 if FLAGS.update_golden_data:48 image = Image.fromarray(tf.squeeze(computed_image_array).numpy())49 with tf.io.gfile.GFile(groundtruth_image_filename, mode='wb') as fp:50 image.save(fp)51 return computed_image_array52 53 with tf.io.gfile.GFile(groundtruth_image_filename, mode='rb') as fp:54 image = data_utils.read_image(fp.read())55 # If loaded image has 3 channels, the returned shape is [height, width, 3].56 # If loaded image has 1 channel, the returned shape is [height, width].57 image = np.squeeze(image_utils.img_to_array(image))58 return image59 60 61def _get_groundtruth_array(computed_image_array, groundtruth_image_filename):62 if FLAGS.update_golden_data:63 with tf.io.gfile.GFile(groundtruth_image_filename, mode='wb') as fp:64 np.save(fp, computed_image_array)65 return computed_image_array66 with tf.io.gfile.GFile(groundtruth_image_filename, mode='rb') as fp:67 # If loaded data has C>1 channels, the returned shape is [height, width, C].68 # If loaded data has 1 channel, the returned shape is [height, width].69 array = np.squeeze(np.load(fp))70 return array71 72 73class PanopticSampleGeneratorTest(tf.test.TestCase):74 75 def setUp(self):76 super().setUp()77 self._test_img_data_dir = os.path.join(78 FLAGS.test_srcdir,79 FLAGS.panoptic_annotation_data,80 _IMAGE_FOLDER)81 self._test_gt_data_dir = os.path.join(82 FLAGS.test_srcdir,83 FLAGS.panoptic_annotation_data)84 self._test_target_data_dir = os.path.join(85 FLAGS.test_srcdir,86 FLAGS.panoptic_annotation_data,87 _TARGET_FOLDER)88 image_path = self._test_img_data_dir + _FILENAME_PREFIX + '_leftImg8bit.png'89 with tf.io.gfile.GFile(image_path, 'rb') as image_file:90 rgb_image = data_utils.read_image(image_file.read())91 self._rgb_image = tf.convert_to_tensor(np.array(rgb_image))92 label_path = self._test_gt_data_dir + 'dummy_gt_for_vps.png'93 with tf.io.gfile.GFile(label_path, 'rb') as label_file:94 label = data_utils.read_image(label_file.read())95 self._label = tf.expand_dims(tf.convert_to_tensor(96 np.dot(np.array(label), [1, 256, 256 * 256])), -1)97 98 def test_input_generator(self):99 tf.random.set_seed(0)100 np.random.seed(0)101 small_instances = {'threshold': 4096, 'weight': 3.0}102 generator = sample_generator.PanopticSampleGenerator(103 dataset.CITYSCAPES_PANOPTIC_INFORMATION._asdict(),104 focus_small_instances=small_instances,105 is_training=True,106 crop_size=[769, 769],107 thing_id_mask_annotations=True)108 input_sample = {109 'image': self._rgb_image,110 'image_name': 'test_image',111 'label': self._label,112 'height': 800,113 'width': 800114 }115 sample = generator(input_sample)116 117 self.assertIn(common.IMAGE, sample)118 self.assertIn(common.GT_SEMANTIC_KEY, sample)119 self.assertIn(common.GT_PANOPTIC_KEY, sample)120 self.assertIn(common.GT_INSTANCE_CENTER_KEY, sample)121 self.assertIn(common.GT_INSTANCE_REGRESSION_KEY, sample)122 self.assertIn(common.GT_IS_CROWD, sample)123 self.assertIn(common.GT_THING_ID_MASK_KEY, sample)124 self.assertIn(common.GT_THING_ID_CLASS_KEY, sample)125 self.assertIn(common.SEMANTIC_LOSS_WEIGHT_KEY, sample)126 self.assertIn(common.CENTER_LOSS_WEIGHT_KEY, sample)127 self.assertIn(common.REGRESSION_LOSS_WEIGHT_KEY, sample)128 129 self.assertListEqual(sample[common.IMAGE].shape.as_list(), [769, 769, 3])130 self.assertListEqual(sample[common.GT_SEMANTIC_KEY].shape.as_list(),131 [769, 769])132 self.assertListEqual(sample[common.GT_PANOPTIC_KEY].shape.as_list(),133 [769, 769])134 self.assertListEqual(sample[common.GT_INSTANCE_CENTER_KEY].shape.as_list(),135 [769, 769])136 self.assertListEqual(137 sample[common.GT_INSTANCE_REGRESSION_KEY].shape.as_list(),138 [769, 769, 2])139 self.assertListEqual(sample[common.GT_IS_CROWD].shape.as_list(), [769, 769])140 self.assertListEqual(sample[common.GT_THING_ID_MASK_KEY].shape.as_list(),141 [769, 769])142 self.assertListEqual(sample[common.GT_THING_ID_CLASS_KEY].shape.as_list(),143 [128])144 self.assertListEqual(145 sample[common.SEMANTIC_LOSS_WEIGHT_KEY].shape.as_list(), [769, 769])146 self.assertListEqual(sample[common.CENTER_LOSS_WEIGHT_KEY].shape.as_list(),147 [769, 769])148 self.assertListEqual(149 sample[common.REGRESSION_LOSS_WEIGHT_KEY].shape.as_list(),150 [769, 769])151 152 gt_sem = sample[common.GT_SEMANTIC_KEY]153 gt_pan = sample[common.GT_PANOPTIC_KEY]154 gt_center = tf.cast(sample[common.GT_INSTANCE_CENTER_KEY] * 255, tf.uint8)155 gt_is_crowd = sample[common.GT_IS_CROWD]156 gt_thing_id_mask = sample[common.GT_THING_ID_MASK_KEY]157 gt_thing_id_class = sample[common.GT_THING_ID_CLASS_KEY]158 image = tf.cast(sample[common.IMAGE], tf.uint8)159 160 # semantic weights can be in range of [0, 3] in this example.161 semantic_weights = tf.cast(sample[common.SEMANTIC_LOSS_WEIGHT_KEY] * 85,162 tf.uint8)163 center_weights = tf.cast(sample[common.CENTER_LOSS_WEIGHT_KEY] * 255,164 tf.uint8)165 offset_weights = tf.cast(sample[common.REGRESSION_LOSS_WEIGHT_KEY] * 255,166 tf.uint8)167 168 np.testing.assert_almost_equal(169 image.numpy(),170 _get_groundtruth_image(171 image,172 self._test_target_data_dir + 'rgb_target.png'))173 np.testing.assert_almost_equal(174 gt_sem.numpy(),175 _get_groundtruth_image(176 gt_sem,177 self._test_target_data_dir + 'semantic_target.png'))178 # Save gt as png. Pillow is currently unable to correctly save the image as179 # 32bit, but uses 16bit which overflows.180 _ = _get_groundtruth_image(181 gt_pan, self._test_target_data_dir + 'panoptic_target.png')182 np.testing.assert_almost_equal(183 gt_pan.numpy(),184 _get_groundtruth_array(185 gt_pan,186 self._test_target_data_dir + 'panoptic_target.npy'))187 np.testing.assert_almost_equal(188 gt_thing_id_mask.numpy(),189 _get_groundtruth_array(190 gt_thing_id_mask,191 self._test_target_data_dir + 'thing_id_mask_target.npy'))192 np.testing.assert_almost_equal(193 gt_thing_id_class.numpy(),194 _get_groundtruth_array(195 gt_thing_id_class,196 self._test_target_data_dir + 'thing_id_class_target.npy'))197 np.testing.assert_almost_equal(198 gt_center.numpy(),199 _get_groundtruth_image(200 gt_center,201 self._test_target_data_dir + 'center_target.png'))202 np.testing.assert_almost_equal(203 sample[common.GT_INSTANCE_REGRESSION_KEY].numpy(),204 _get_groundtruth_array(205 sample[common.GT_INSTANCE_REGRESSION_KEY].numpy(),206 self._test_target_data_dir + 'offset_target.npy'))207 np.testing.assert_array_equal(208 gt_is_crowd.numpy(),209 _get_groundtruth_array(gt_is_crowd.numpy(),210 self._test_target_data_dir + 'is_crowd.npy'))211 np.testing.assert_almost_equal(212 semantic_weights.numpy(),213 _get_groundtruth_image(214 semantic_weights,215 self._test_target_data_dir + 'semantic_weights.png'))216 np.testing.assert_almost_equal(217 center_weights.numpy(),218 _get_groundtruth_image(219 center_weights,220 self._test_target_data_dir + 'center_weights.png'))221 np.testing.assert_almost_equal(222 offset_weights.numpy(),223 _get_groundtruth_image(224 offset_weights,225 self._test_target_data_dir + 'offset_weights.png'))226 227 def test_input_generator_eval(self):228 tf.random.set_seed(0)229 np.random.seed(0)230 small_instances = {'threshold': 4096, 'weight': 3.0}231 generator = sample_generator.PanopticSampleGenerator(232 dataset.CITYSCAPES_PANOPTIC_INFORMATION._asdict(),233 focus_small_instances=small_instances,234 is_training=False,235 crop_size=[800, 800])236 input_sample = {237 'image': self._rgb_image,238 'image_name': 'test_image',239 'label': self._label,240 'height': 800,241 'width': 800242 }243 sample = generator(input_sample)244 245 self.assertIn(common.GT_SEMANTIC_RAW, sample)246 self.assertIn(common.GT_PANOPTIC_RAW, sample)247 self.assertIn(common.GT_IS_CROWD_RAW, sample)248 249 gt_sem_raw = sample[common.GT_SEMANTIC_RAW]250 gt_pan_raw = sample[common.GT_PANOPTIC_RAW]251 gt_is_crowd_raw = sample[common.GT_IS_CROWD_RAW]252 253 self.assertListEqual(gt_sem_raw.shape.as_list(), [800, 800])254 self.assertListEqual(gt_pan_raw.shape.as_list(), [800, 800])255 self.assertListEqual(gt_is_crowd_raw.shape.as_list(), [800, 800])256 257 np.testing.assert_almost_equal(258 gt_sem_raw.numpy(),259 _get_groundtruth_image(260 gt_sem_raw,261 self._test_target_data_dir + 'eval_semantic_target.png'))262 np.testing.assert_almost_equal(263 gt_pan_raw.numpy(),264 _get_groundtruth_array(265 gt_pan_raw,266 self._test_target_data_dir + 'eval_panoptic_target.npy'))267 np.testing.assert_almost_equal(268 gt_is_crowd_raw.numpy(),269 _get_groundtruth_array(gt_is_crowd_raw, self._test_target_data_dir +270 'eval_is_crowd.npy'))271 272 273if __name__ == '__main__':274 tf.test.main()275 