CoolFace
Apppublic

karolmajek/Axial-DeepLab-SWideRNet

sourceHugging Faceupdated 5y agoView on Hugging Face
0likes
data_utils.py392 linesDownload Raw Back to data
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"""Contains common utility functions and classes for building dataset."""17 18import collections19import io20 21import numpy as np22from PIL import Image23from PIL import ImageOps24import tensorflow as tf25 26from deeplab2 import common27 28_PANOPTIC_LABEL_FORMAT = 'raw'29 30 31def read_image(image_data):32  """Decodes image from in-memory data.33 34  Args:35    image_data: Bytes data representing encoded image.36 37  Returns:38    Decoded PIL.Image object.39  """40  image = Image.open(io.BytesIO(image_data))41 42  try:43    image = ImageOps.exif_transpose(image)44  except TypeError:45    # capture and ignore this bug:46    # https://github.com/python-pillow/Pillow/issues/397347    pass48 49  return image50 51 52def get_image_dims(image_data, check_is_rgb=False):53  """Decodes image and return its height and width.54 55  Args:56    image_data: Bytes data representing encoded image.57    check_is_rgb: Whether to check encoded image is RGB.58 59  Returns:60    Decoded image size as a tuple of (height, width)61 62  Raises:63    ValueError: If check_is_rgb is set and input image has other format.64  """65  image = read_image(image_data)66 67  if check_is_rgb and image.mode != 'RGB':68    raise ValueError('Expects RGB image data, gets mode: %s' % image.mode)69 70  width, height = image.size71  return height, width72 73 74def _int64_list_feature(values):75  """Returns a TF-Feature of int64_list.76 77  Args:78    values: A scalar or an iterable of integer values.79 80  Returns:81    A TF-Feature.82  """83  if not isinstance(values, collections.Iterable):84    values = [values]85 86  return tf.train.Feature(int64_list=tf.train.Int64List(value=values))87 88 89def _bytes_list_feature(values):90  """Returns a TF-Feature of bytes.91 92  Args:93    values: A string.94 95  Returns:96    A TF-Feature.97  """98  if isinstance(values, str):99    values = values.encode()100 101  return tf.train.Feature(bytes_list=tf.train.BytesList(value=[values]))102 103 104def create_features(image_data,105                    image_format,106                    filename,107                    label_data=None,108                    label_format=None):109  """Creates image/segmentation features.110 111  Args:112    image_data: String or byte stream of encoded image data.113    image_format: String, image data format, should be either 'jpeg' or 'png'.114    filename: String, image filename.115    label_data: String or byte stream of (potentially) encoded label data. If116      None, we skip to write it to tf.train.Example.117    label_format: String, label data format, should be either 'png' or 'raw'. If118      None, we skip to write it to tf.train.Example.119 120  Returns:121    A dictionary of feature name to tf.train.Feature maaping.122  """123  if image_format not in ('jpeg', 'png'):124    raise ValueError('Unsupported image format: %s' % image_format)125 126  # Check color mode, and convert grey image to rgb image.127  image = read_image(image_data)128  if image.mode != 'RGB':129    image = image.convert('RGB')130    image_data = io.BytesIO()131    image.save(image_data, format=image_format)132    image_data = image_data.getvalue()133 134  height, width = get_image_dims(image_data, check_is_rgb=True)135 136  feature_dict = {137      common.KEY_ENCODED_IMAGE: _bytes_list_feature(image_data),138      common.KEY_IMAGE_FILENAME: _bytes_list_feature(filename),139      common.KEY_IMAGE_FORMAT: _bytes_list_feature(image_format),140      common.KEY_IMAGE_HEIGHT: _int64_list_feature(height),141      common.KEY_IMAGE_WIDTH: _int64_list_feature(width),142      common.KEY_IMAGE_CHANNELS: _int64_list_feature(3),143  }144 145  if label_data is None:146    return feature_dict147 148  if label_format == 'png':149    label_height, label_width = get_image_dims(label_data)150    if (label_height, label_width) != (height, width):151      raise ValueError('Image (%s) and label (%s) shape mismatch' %152                       ((height, width), (label_height, label_width)))153  elif label_format == 'raw':154    # Raw label encodes int32 array.155    expected_label_size = height * width * np.dtype(np.int32).itemsize156    if len(label_data) != expected_label_size:157      raise ValueError('Expects raw label data length %d, gets %d' %158                       (expected_label_size, len(label_data)))159  else:160    raise ValueError('Unsupported label format: %s' % label_format)161 162  feature_dict.update({163      common.KEY_ENCODED_LABEL: _bytes_list_feature(label_data),164      common.KEY_LABEL_FORMAT: _bytes_list_feature(label_format)165  })166 167  return feature_dict168 169 170def create_tfexample(image_data,171                     image_format,172                     filename,173                     label_data=None,174                     label_format=None):175  """Converts one image/segmentation pair to TF example.176 177  Args:178    image_data: String or byte stream of encoded image data.179    image_format: String, image data format, should be either 'jpeg' or 'png'.180    filename: String, image filename.181    label_data: String or byte stream of (potentially) encoded label data. If182      None, we skip to write it to tf.train.Example.183    label_format: String, label data format, should be either 'png' or 'raw'. If184      None, we skip to write it to tf.train.Example.185 186  Returns:187    TF example proto.188  """189  feature_dict = create_features(image_data, image_format, filename, label_data,190                                 label_format)191  return tf.train.Example(features=tf.train.Features(feature=feature_dict))192 193 194def create_video_tfexample(image_data,195                           image_format,196                           filename,197                           sequence_id,198                           image_id,199                           label_data=None,200                           label_format=None,201                           prev_image_data=None,202                           prev_label_data=None):203  """Converts one video frame/panoptic segmentation pair to TF example.204 205  Args:206    image_data: String or byte stream of encoded image data.207    image_format: String, image data format, should be either 'jpeg' or 'png'.208    filename: String, image filename.209    sequence_id: ID of the video sequence as a string.210    image_id: ID of the image as a string.211    label_data: String or byte stream of (potentially) encoded label data. If212      None, we skip to write it to tf.train.Example.213    label_format: String, label data format, should be either 'png' or 'raw'. If214      None, we skip to write it to tf.train.Example.215    prev_image_data: An optional string or byte stream of encoded previous image216      data.217    prev_label_data: An optional string or byte stream of (potentially) encoded218      previous label data.219 220  Returns:221    TF example proto.222  """223  feature_dict = create_features(image_data, image_format, filename, label_data,224                                 label_format)225  feature_dict.update({226      common.KEY_SEQUENCE_ID: _bytes_list_feature(sequence_id),227      common.KEY_FRAME_ID: _bytes_list_feature(image_id)228  })229  if prev_image_data is not None:230    feature_dict[common.KEY_ENCODED_PREV_IMAGE] = _bytes_list_feature(231        prev_image_data)232  if prev_label_data is not None:233    feature_dict[common.KEY_ENCODED_PREV_LABEL] = _bytes_list_feature(234        prev_label_data)235  return tf.train.Example(features=tf.train.Features(feature=feature_dict))236 237 238def create_video_and_depth_tfexample(image_data,239                                     image_format,240                                     filename,241                                     sequence_id,242                                     image_id,243                                     label_data=None,244                                     label_format=None,245                                     next_image_data=None,246                                     next_label_data=None,247                                     depth_data=None,248                                     depth_format=None):249  """Converts an image/segmentation pair and depth of first frame to TF example.250 251    The image pair contains the current frame and the next frame with the252    current frame including depth label.253 254  Args:255    image_data: String or byte stream of encoded image data.256    image_format: String, image data format, should be either 'jpeg' or 'png'.257    filename: String, image filename.258    sequence_id: ID of the video sequence as a string.259    image_id: ID of the image as a string.260    label_data: String or byte stream of (potentially) encoded label data. If261      None, we skip to write it to tf.train.Example.262    label_format: String, label data format, should be either 'png' or 'raw'. If263      None, we skip to write it to tf.train.Example.264    next_image_data: An optional string or byte stream of encoded next image265      data.266    next_label_data: An optional string or byte stream of (potentially) encoded267      next label data.268    depth_data: An optional string or byte sream of encoded depth data.269    depth_format: String, depth data format, should be either 'png' or 'raw'.270 271  Returns:272    TF example proto.273  """274  feature_dict = create_features(image_data, image_format, filename, label_data,275                                 label_format)276  feature_dict.update({277      common.KEY_SEQUENCE_ID: _bytes_list_feature(sequence_id),278      common.KEY_FRAME_ID: _bytes_list_feature(image_id)279  })280  if next_image_data is not None:281    feature_dict[common.KEY_ENCODED_NEXT_IMAGE] = _bytes_list_feature(282        next_image_data)283  if next_label_data is not None:284    feature_dict[common.KEY_ENCODED_NEXT_LABEL] = _bytes_list_feature(285        next_label_data)286  if depth_data is not None:287    feature_dict[common.KEY_ENCODED_DEPTH] = _bytes_list_feature(288        depth_data)289    feature_dict[common.KEY_DEPTH_FORMAT] = _bytes_list_feature(290        depth_format)291  return tf.train.Example(features=tf.train.Features(feature=feature_dict))292 293 294class SegmentationDecoder(object):295  """Basic parser to decode serialized tf.Example."""296 297  def __init__(self,298               is_panoptic_dataset=True,299               is_video_dataset=False,300               use_two_frames=False,301               use_next_frame=False,302               decode_groundtruth_label=True):303    self._is_panoptic_dataset = is_panoptic_dataset304    self._is_video_dataset = is_video_dataset305    self._use_two_frames = use_two_frames306    self._use_next_frame = use_next_frame307    self._decode_groundtruth_label = decode_groundtruth_label308    string_feature = tf.io.FixedLenFeature((), tf.string)309    int_feature = tf.io.FixedLenFeature((), tf.int64)310    self._keys_to_features = {311        common.KEY_ENCODED_IMAGE: string_feature,312        common.KEY_IMAGE_FILENAME: string_feature,313        common.KEY_IMAGE_FORMAT: string_feature,314        common.KEY_IMAGE_HEIGHT: int_feature,315        common.KEY_IMAGE_WIDTH: int_feature,316        common.KEY_IMAGE_CHANNELS: int_feature,317    }318    if decode_groundtruth_label:319      self._keys_to_features[common.KEY_ENCODED_LABEL] = string_feature320    if self._is_video_dataset:321      self._keys_to_features[common.KEY_SEQUENCE_ID] = string_feature322      self._keys_to_features[common.KEY_FRAME_ID] = string_feature323    # Two-frame specific processing.324    if self._use_two_frames:325      self._keys_to_features[common.KEY_ENCODED_PREV_IMAGE] = string_feature326      if decode_groundtruth_label:327        self._keys_to_features[common.KEY_ENCODED_PREV_LABEL] = string_feature328    # Next-frame specific processing.329    if self._use_next_frame:330      self._keys_to_features[common.KEY_ENCODED_NEXT_IMAGE] = string_feature331      if decode_groundtruth_label:332        self._keys_to_features[common.KEY_ENCODED_NEXT_LABEL] = string_feature333 334  def _decode_image(self, parsed_tensors, key):335    """Decodes image udner key from parsed tensors."""336    image = tf.io.decode_image(337        parsed_tensors[key],338        channels=3,339        dtype=tf.dtypes.uint8,340        expand_animations=False)341    image.set_shape([None, None, 3])342    return image343 344  def _decode_label(self, parsed_tensors, label_key):345    """Decodes segmentation label under label_key from parsed tensors."""346    if self._is_panoptic_dataset:347      flattened_label = tf.io.decode_raw(348          parsed_tensors[label_key], out_type=tf.int32)349      label_shape = tf.stack([350          parsed_tensors[common.KEY_IMAGE_HEIGHT],351          parsed_tensors[common.KEY_IMAGE_WIDTH], 1352      ])353      label = tf.reshape(flattened_label, label_shape)354      return label355 356    label = tf.io.decode_image(parsed_tensors[label_key], channels=1)357    label.set_shape([None, None, 1])358    return label359 360  def __call__(self, serialized_example):361    parsed_tensors = tf.io.parse_single_example(362        serialized_example, features=self._keys_to_features)363    return_dict = {364        'image':365            self._decode_image(parsed_tensors, common.KEY_ENCODED_IMAGE),366        'image_name':367            parsed_tensors[common.KEY_IMAGE_FILENAME],368        'height':369            tf.cast(parsed_tensors[common.KEY_IMAGE_HEIGHT], dtype=tf.int32),370        'width':371            tf.cast(parsed_tensors[common.KEY_IMAGE_WIDTH], dtype=tf.int32),372    }373    return_dict['label'] = None374    if self._decode_groundtruth_label:375      return_dict['label'] = self._decode_label(parsed_tensors,376                                                common.KEY_ENCODED_LABEL)377    if self._is_video_dataset:378      return_dict['sequence'] = parsed_tensors[common.KEY_SEQUENCE_ID]379    if self._use_two_frames:380      return_dict['prev_image'] = self._decode_image(381          parsed_tensors, common.KEY_ENCODED_PREV_IMAGE)382      if self._decode_groundtruth_label:383        return_dict['prev_label'] = self._decode_label(384            parsed_tensors, common.KEY_ENCODED_PREV_LABEL)385    if self._use_next_frame:386      return_dict['next_image'] = self._decode_image(387          parsed_tensors, common.KEY_ENCODED_NEXT_IMAGE)388      if self._decode_groundtruth_label:389        return_dict['next_label'] = self._decode_label(390            parsed_tensors, common.KEY_ENCODED_NEXT_LABEL)391    return return_dict392