# Lint as: python2, python3 # Copyright 2019 The TensorFlow Authors All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== """Utility functions to set up unit tests on Panoptic Segmentation code.""" from __future__ import absolute_import from __future__ import division from __future__ import print_function import os from absl import flags import numpy as np import scipy.misc import six from six.moves import map FLAGS = flags.FLAGS _TEST_DIR = 'deeplab/evaluation/testdata' def read_test_image(testdata_path, *args, **kwargs): """Loads a test image. Args: testdata_path: Image path relative to panoptic_segmentation/testdata as a string. *args: Additional positional arguments passed to `imread`. **kwargs: Additional keyword arguments passed to `imread`. Returns: The image, as a numpy array. """ image_path = os.path.join(_TEST_DIR, testdata_path) return scipy.misc.imread(image_path, *args, **kwargs) def read_segmentation_with_rgb_color_map(image_testdata_path, rgb_to_semantic_label, output_dtype=None): """Reads a test segmentation as an image and a map from colors to labels. Args: image_testdata_path: Image path relative to panoptic_segmentation/testdata as a string. rgb_to_semantic_label: Mapping from RGB colors to integer labels as a dictionary. output_dtype: Type of the output labels. If None, defaults to the type of the provided color map. Returns: A 2D numpy array of labels. Raises: ValueError: On an incomplete `rgb_to_semantic_label`. """ rgb_image = read_test_image(image_testdata_path, mode='RGB') if len(rgb_image.shape) != 3 or rgb_image.shape[2] != 3: raise AssertionError( 'Expected RGB image, actual shape is %s' % rgb_image.sape) num_pixels = rgb_image.shape[0] * rgb_image.shape[1] unique_colors = np.unique(np.reshape(rgb_image, [num_pixels, 3]), axis=0) if not set(map(tuple, unique_colors)).issubset( six.viewkeys(rgb_to_semantic_label)): raise ValueError('RGB image has colors not in color map.') output_dtype = output_dtype or type( next(six.itervalues(rgb_to_semantic_label))) output_labels = np.empty(rgb_image.shape[:2], dtype=output_dtype) for rgb_color, int_label in six.iteritems(rgb_to_semantic_label): color_array = np.array(rgb_color, ndmin=3) output_labels[np.all(rgb_image == color_array, axis=2)] = int_label return output_labels def panoptic_segmentation_with_class_map(instance_testdata_path, instance_label_to_semantic_label): """Reads in a panoptic segmentation with an instance map and a map to classes. Args: instance_testdata_path: Path to a grayscale instance map, given as a string and relative to panoptic_segmentation/testdata. instance_label_to_semantic_label: A map from instance labels to class labels. Returns: A tuple `(instance_labels, class_labels)` of numpy arrays. Raises: ValueError: On a mismatched set of instances in the `instance_label_to_semantic_label`. """ instance_labels = read_test_image(instance_testdata_path, mode='L') if set(np.unique(instance_labels)) != set( six.iterkeys(instance_label_to_semantic_label)): raise ValueError('Provided class map does not match present instance ids.') class_labels = np.empty_like(instance_labels) for instance_id, class_id in six.iteritems(instance_label_to_semantic_label): class_labels[instance_labels == instance_id] = class_id return instance_labels, class_labels