Example #1
0
def pad_to_bounding_box(image, offset_height, offset_width, target_height,
                        target_width):
    """Pad `image` with zeros to the specified `height` and `width`.

  Adds `offset_height` rows of zeros on top, `offset_width` columns of
  zeros on the left, and then pads the image on the bottom and right
  with zeros until it has dimensions `target_height`, `target_width`.

  This op does nothing if `offset_*` is zero and the image already has size
  `target_height` by `target_width`.

  Args:
    image: 3-D tensor with shape `[height, width, channels]`
    offset_height: Number of rows of zeros to add on top.
    offset_width: Number of columns of zeros to add on the left.
    target_height: Height of output image.
    target_width: Width of output image.

  Returns:
    3-D tensor of shape `[target_height, target_width, channels]`

  Raises:
    ValueError: If the shape of `image` is incompatible with the `offset_*` or
      `target_*` arguments, or either `offset_height` or `offset_width` is
      negative.
  """
    image = ops.convert_to_tensor(image, name='image')

    assert_ops = []
    assert_ops += _Check3DImage(image, require_static=False)

    height, width, depth = _ImageDimensions(image, static_only=False)
    after_padding_width = target_width - offset_width - width
    after_padding_height = target_height - offset_height - height

    assert_ops += _assert(offset_height >= 0, ValueError,
                          'offset_height must be >= 0')
    assert_ops += _assert(offset_width >= 0, ValueError,
                          'offset_width must be >= 0')
    assert_ops += _assert(after_padding_width >= 0, ValueError,
                          'width must be <= target - offset')
    assert_ops += _assert(after_padding_height >= 0, ValueError,
                          'height must be <= target - offset')
    image = control_flow_ops.with_dependencies(assert_ops, image)

    # Do not pad on the depth dimensions.
    paddings = array_ops.reshape(
        array_ops.pack([
            offset_height, after_padding_height, offset_width,
            after_padding_width, 0, 0
        ]), [3, 2])
    padded = array_ops.pad(image, paddings)

    padded_shape = [
        None if is_tensor(i) else i
        for i in [target_height, target_width, depth]
    ]
    padded.set_shape(padded_shape)

    return padded
Example #2
0
def pad_to_bounding_box(image, offset_height, offset_width, target_height,
                        target_width):
  """Pad `image` with zeros to the specified `height` and `width`.

  Adds `offset_height` rows of zeros on top, `offset_width` columns of
  zeros on the left, and then pads the image on the bottom and right
  with zeros until it has dimensions `target_height`, `target_width`.

  This op does nothing if `offset_*` is zero and the image already has size
  `target_height` by `target_width`.

  Args:
    image: 3-D tensor with shape `[height, width, channels]`
    offset_height: Number of rows of zeros to add on top.
    offset_width: Number of columns of zeros to add on the left.
    target_height: Height of output image.
    target_width: Width of output image.

  Returns:
    3-D tensor of shape `[target_height, target_width, channels]`

  Raises:
    ValueError: If the shape of `image` is incompatible with the `offset_*` or
      `target_*` arguments, or either `offset_height` or `offset_width` is
      negative.
  """
  image = ops.convert_to_tensor(image, name='image')

  assert_ops = []
  assert_ops += _Check3DImage(image, require_static=False)

  height, width, depth = _ImageDimensions(image, static_only=False)
  after_padding_width = target_width - offset_width - width
  after_padding_height = target_height - offset_height - height

  assert_ops += _assert(offset_height >= 0, ValueError,
                        'offset_height must be >= 0')
  assert_ops += _assert(offset_width >= 0, ValueError,
                        'offset_width must be >= 0')
  assert_ops += _assert(after_padding_width >= 0, ValueError,
                        'width must be <= target - offset')
  assert_ops += _assert(after_padding_height >= 0, ValueError,
                        'height must be <= target - offset')
  image = control_flow_ops.with_dependencies(assert_ops, image)

  # Do not pad on the depth dimensions.
  paddings = array_ops.reshape(
    array_ops.pack([offset_height, after_padding_height,
                    offset_width, after_padding_width,
                    0, 0]),
    [3, 2])
  padded = array_ops.pad(image, paddings)

  padded_shape = [None if is_tensor(i) else i
                  for i in [target_height, target_width, depth]]
  padded.set_shape(padded_shape)

  return padded
Example #3
0
def crop_to_bounding_box(image, offset_height, offset_width, target_height,
                         target_width):
    """Crops an image to a specified bounding box.

  This op cuts a rectangular part out of `image`. The top-left corner of the
  returned image is at `offset_height, offset_width` in `image`, and its
  lower-right corner is at
  `offset_height + target_height, offset_width + target_width`.

  Args:
    image: 3-D tensor with shape `[height, width, channels]`
    offset_height: Vertical coordinate of the top-left corner of the result in
                   the input.
    offset_width: Horizontal coordinate of the top-left corner of the result in
                  the input.
    target_height: Height of the result.
    target_width: Width of the result.

  Returns:
    3-D tensor of image with shape `[target_height, target_width, channels]`

  Raises:
    ValueError: If the shape of `image` is incompatible with the `offset_*` or
      `target_*` arguments, or either `offset_height` or `offset_width` is
      negative, or either `target_height` or `target_width` is not positive.
  """
    image = ops.convert_to_tensor(image, name='image')

    assert_ops = []
    assert_ops += _Check3DImage(image, require_static=False)

    height, width, depth = _ImageDimensions(image, static_only=False)

    assert_ops += _assert(offset_width >= 0, ValueError,
                          'offset_width must be >= 0.')
    assert_ops += _assert(offset_height >= 0, ValueError,
                          'offset_height must be >= 0.')
    assert_ops += _assert(target_width > 0, ValueError,
                          'target_width must be > 0.')
    assert_ops += _assert(target_height > 0, ValueError,
                          'target_height must be > 0.')
    assert_ops += _assert(width >= (target_width + offset_width), ValueError,
                          'width must be >= target + offset.')
    assert_ops += _assert(height >= (target_height + offset_height),
                          ValueError, 'height must be >= target + offset.')
    image = control_flow_ops.with_dependencies(assert_ops, image)

    cropped = array_ops.slice(
        image, array_ops.pack([offset_height, offset_width, 0]),
        array_ops.pack([target_height, target_width, -1]))

    cropped_shape = [
        None if is_tensor(i) else i
        for i in [target_height, target_width, depth]
    ]
    cropped.set_shape(cropped_shape)

    return cropped
Example #4
0
def crop_to_bounding_box(image, offset_height, offset_width, target_height,
                         target_width):
  """Crops an image to a specified bounding box.

  This op cuts a rectangular part out of `image`. The top-left corner of the
  returned image is at `offset_height, offset_width` in `image`, and its
  lower-right corner is at
  `offset_height + target_height, offset_width + target_width`.

  Args:
    image: 3-D tensor with shape `[height, width, channels]`
    offset_height: Vertical coordinate of the top-left corner of the result in
                   the input.
    offset_width: Horizontal coordinate of the top-left corner of the result in
                  the input.
    target_height: Height of the result.
    target_width: Width of the result.

  Returns:
    3-D tensor of image with shape `[target_height, target_width, channels]`

  Raises:
    ValueError: If the shape of `image` is incompatible with the `offset_*` or
      `target_*` arguments, or either `offset_height` or `offset_width` is
      negative, or either `target_height` or `target_width` is not positive.
  """
  image = ops.convert_to_tensor(image, name='image')

  assert_ops = []
  assert_ops += _Check3DImage(image, require_static=False)

  height, width, depth = _ImageDimensions(image, static_only=False)

  assert_ops += _assert(offset_width >= 0, ValueError,
                        'offset_width must be >= 0.')
  assert_ops += _assert(offset_height >= 0, ValueError,
                        'offset_height must be >= 0.')
  assert_ops += _assert(target_width > 0, ValueError,
                        'target_width must be > 0.')
  assert_ops += _assert(target_height > 0, ValueError,
                        'target_height must be > 0.')
  assert_ops += _assert(width >= (target_width + offset_width), ValueError,
                        'width must be >= target + offset.')
  assert_ops += _assert(height >= (target_height + offset_height), ValueError,
                        'height must be >= target + offset.')
  image = control_flow_ops.with_dependencies(assert_ops, image)

  cropped = array_ops.slice(
    image,
    array_ops.pack([offset_height, offset_width, 0]),
    array_ops.pack([target_height, target_width, -1]))

  cropped_shape = [None if is_tensor(i) else i
                   for i in [target_height, target_width, depth]]
  cropped.set_shape(cropped_shape)

  return cropped
Example #5
0
def _assert(cond, ex_type, msg):
  """A polymorphic assert, works with tensors and boolean expressions.

  If `cond` is not a tensor, behave like an ordinary assert statement, except
  that a empty list is returned. If `cond` is a tensor, return a list
  containing a single TensorFlow assert op.

  Args:
    cond: Something evaluates to a boolean value. May be a tensor.
    ex_type: The exception class to use.
    msg: The error message.

  Returns:
    A list, containing at most one assert op.
  """
  if is_tensor(cond):
    return [logging_ops.Assert(cond, [msg])]
  else:
    if not cond:
      raise ex_type(msg)
    else:
      return []
Example #6
0
def _assert(cond, ex_type, msg):
    """A polymorphic assert, works with tensors and boolean expressions.

  If `cond` is not a tensor, behave like an ordinary assert statement, except
  that a empty list is returned. If `cond` is a tensor, return a list
  containing a single TensorFlow assert op.

  Args:
    cond: Something evaluates to a boolean value. May be a tensor.
    ex_type: The exception class to use.
    msg: The error message.

  Returns:
    A list, containing at most one assert op.
  """
    if is_tensor(cond):
        return [logging_ops.Assert(cond, [msg])]
    else:
        if not cond:
            raise ex_type(msg)
        else:
            return []
Example #7
0
 def equal_(x, y):
   if is_tensor(x) or is_tensor(y):
     return math_ops.equal(x, y)
   else:
     return x == y
Example #8
0
 def min_(x, y):
   if is_tensor(x) or is_tensor(y):
     return math_ops.minimum(x, y)
   else:
     return min(x, y)
Example #9
0
 def max_(x, y):
   if is_tensor(x) or is_tensor(y):
     return math_ops.maximum(x, y)
   else:
     return max(x, y)
Example #10
0
def resize_image_with_crop_or_pad(image, target_height, target_width):
  """Crops and/or pads an image to a target width and height.

  Resizes an image to a target width and height by either centrally
  cropping the image or padding it evenly with zeros.

  If `width` or `height` is greater than the specified `target_width` or
  `target_height` respectively, this op centrally crops along that dimension.
  If `width` or `height` is smaller than the specified `target_width` or
  `target_height` respectively, this op centrally pads with 0 along that
  dimension.

  Args:
    image: 3-D tensor of shape `[height, width, channels]`
    target_height: Target height.
    target_width: Target width.

  Raises:
    ValueError: if `target_height` or `target_width` are zero or negative.

  Returns:
    Cropped and/or padded image of shape
    `[target_height, target_width, channels]`
  """
  image = ops.convert_to_tensor(image, name='image')

  assert_ops = []
  assert_ops += _Check3DImage(image, require_static=False)
  assert_ops += _assert(target_width > 0, ValueError,
                        'target_width must be > 0.')
  assert_ops += _assert(target_height > 0, ValueError,
                        'target_height must be > 0.')

  image = control_flow_ops.with_dependencies(assert_ops, image)
  # `crop_to_bounding_box` and `pad_to_bounding_box` have their own checks.
  # Make sure our checks come first, so that error messages are clearer.
  if is_tensor(target_height):
    target_height = control_flow_ops.with_dependencies(
      assert_ops, target_height)
  if is_tensor(target_width):
    target_width = control_flow_ops.with_dependencies(assert_ops, target_width)

  def max_(x, y):
    if is_tensor(x) or is_tensor(y):
      return math_ops.maximum(x, y)
    else:
      return max(x, y)

  def min_(x, y):
    if is_tensor(x) or is_tensor(y):
      return math_ops.minimum(x, y)
    else:
      return min(x, y)

  def equal_(x, y):
    if is_tensor(x) or is_tensor(y):
      return math_ops.equal(x, y)
    else:
      return x == y

  height, width, _ = _ImageDimensions(image, static_only=False)
  width_diff = target_width - width
  offset_crop_width = max_(-width_diff // 2, 0)
  offset_pad_width = max_(width_diff // 2, 0)

  height_diff = target_height - height
  offset_crop_height = max_(-height_diff // 2, 0)
  offset_pad_height = max_(height_diff // 2, 0)

  # Maybe crop if needed.
  cropped = crop_to_bounding_box(image, offset_crop_height, offset_crop_width,
                                 min_(target_height, height),
                                 min_(target_width, width))

  # Maybe pad if needed.
  resized = pad_to_bounding_box(cropped, offset_pad_height, offset_pad_width,
                                target_height, target_width)

  # In theory all the checks below are redundant.
  if resized.get_shape().ndims is None:
    raise ValueError('resized contains no shape.')

  resized_height, resized_width, _ = \
    _ImageDimensions(resized, static_only=False)

  assert_ops = []
  assert_ops += _assert(equal_(resized_height, target_height), ValueError,
                        'resized height is not correct.')
  assert_ops += _assert(equal_(resized_width, target_width), ValueError,
                        'resized width is not correct.')

  resized = control_flow_ops.with_dependencies(assert_ops, resized)
  return resized
Example #11
0
 def equal_(x, y):
     if is_tensor(x) or is_tensor(y):
         return math_ops.equal(x, y)
     else:
         return x == y
Example #12
0
 def min_(x, y):
     if is_tensor(x) or is_tensor(y):
         return math_ops.minimum(x, y)
     else:
         return min(x, y)
Example #13
0
 def max_(x, y):
     if is_tensor(x) or is_tensor(y):
         return math_ops.maximum(x, y)
     else:
         return max(x, y)
Example #14
0
def resize_image_with_crop_or_pad(image, target_height, target_width):
    """Crops and/or pads an image to a target width and height.

  Resizes an image to a target width and height by either centrally
  cropping the image or padding it evenly with zeros.

  If `width` or `height` is greater than the specified `target_width` or
  `target_height` respectively, this op centrally crops along that dimension.
  If `width` or `height` is smaller than the specified `target_width` or
  `target_height` respectively, this op centrally pads with 0 along that
  dimension.

  Args:
    image: 3-D tensor of shape `[height, width, channels]`
    target_height: Target height.
    target_width: Target width.

  Raises:
    ValueError: if `target_height` or `target_width` are zero or negative.

  Returns:
    Cropped and/or padded image of shape
    `[target_height, target_width, channels]`
  """
    image = ops.convert_to_tensor(image, name='image')

    assert_ops = []
    assert_ops += _Check3DImage(image, require_static=False)
    assert_ops += _assert(target_width > 0, ValueError,
                          'target_width must be > 0.')
    assert_ops += _assert(target_height > 0, ValueError,
                          'target_height must be > 0.')

    image = control_flow_ops.with_dependencies(assert_ops, image)
    # `crop_to_bounding_box` and `pad_to_bounding_box` have their own checks.
    # Make sure our checks come first, so that error messages are clearer.
    if is_tensor(target_height):
        target_height = control_flow_ops.with_dependencies(
            assert_ops, target_height)
    if is_tensor(target_width):
        target_width = control_flow_ops.with_dependencies(
            assert_ops, target_width)

    def max_(x, y):
        if is_tensor(x) or is_tensor(y):
            return math_ops.maximum(x, y)
        else:
            return max(x, y)

    def min_(x, y):
        if is_tensor(x) or is_tensor(y):
            return math_ops.minimum(x, y)
        else:
            return min(x, y)

    def equal_(x, y):
        if is_tensor(x) or is_tensor(y):
            return math_ops.equal(x, y)
        else:
            return x == y

    height, width, _ = _ImageDimensions(image, static_only=False)
    width_diff = target_width - width
    offset_crop_width = max_(-width_diff // 2, 0)
    offset_pad_width = max_(width_diff // 2, 0)

    height_diff = target_height - height
    offset_crop_height = max_(-height_diff // 2, 0)
    offset_pad_height = max_(height_diff // 2, 0)

    # Maybe crop if needed.
    cropped = crop_to_bounding_box(image, offset_crop_height,
                                   offset_crop_width,
                                   min_(target_height, height),
                                   min_(target_width, width))

    # Maybe pad if needed.
    resized = pad_to_bounding_box(cropped, offset_pad_height, offset_pad_width,
                                  target_height, target_width)

    # In theory all the checks below are redundant.
    if resized.get_shape().ndims is None:
        raise ValueError('resized contains no shape.')

    resized_height, resized_width, _ = \
      _ImageDimensions(resized, static_only=False)

    assert_ops = []
    assert_ops += _assert(equal_(resized_height, target_height), ValueError,
                          'resized height is not correct.')
    assert_ops += _assert(equal_(resized_width, target_width), ValueError,
                          'resized width is not correct.')

    resized = control_flow_ops.with_dependencies(assert_ops, resized)
    return resized