def _assertForwardOpMatchesExpected(self, image_np, target_shape, expected=None, large_tolerance=False, align_corners=True): if expected is None: self.fail("expected must be specified") with self.session() as sess, self.test_scope(): image = array_ops.placeholder(image_np.dtype) resized = gen_image_ops.resize_nearest_neighbor( image, target_shape, align_corners=align_corners) out = sess.run(resized, {image: image_np[np.newaxis, :, :, np.newaxis]}) if large_tolerance: self.assertAllClose( expected[np.newaxis, :, :, np.newaxis], out, rtol=2e-4, atol=2e-4) else: self.assertAllClose(expected[np.newaxis, :, :, np.newaxis], out)
def _assertForwardOpMatchesExpected(self, image_np, target_shape, expected=None, large_tolerance=False, align_corners=True): if expected is None: self.fail("expected must be specified") with self.cached_session() as sess, self.test_scope(): image = array_ops.placeholder(image_np.dtype) resized = gen_image_ops.resize_nearest_neighbor( image, target_shape, align_corners=align_corners) out = sess.run(resized, {image: image_np[np.newaxis, :, :, np.newaxis]}) if large_tolerance: self.assertAllClose( expected[np.newaxis, :, :, np.newaxis], out, rtol=2e-4, atol=2e-4) else: self.assertAllClose(expected[np.newaxis, :, :, np.newaxis], out)
def call(self, input, **kwargs): if self.scale == 1.0: return input padded = tf.keras.backend.spatial_2d_padding(input, ((self.ka, self.kb), (self.ka, self.kb))) # split & concat - to work on CPU splitted = tf.split(padded, 3, axis=3) parts = [] for i in range(3): parts.append(tf.nn.conv2d(splitted[i], self.kernels[i], strides=1, padding='VALID')) out = tf.concat([*parts], axis=3) # out = tf.nn.conv2d(padded, self.kernel, strides=1, padding='VALID') size = (tf.cast(out.shape[1] * self.scale, tf.int32), tf.cast(out.shape[2] * self.scale, tf.int32)) # out = tf.image.resize(out, size, method=tf.image.ResizeMethod.BILINEAR) out = resize_nearest_neighbor(out, size) return out
def resize_images(images, new_height, new_width, method=ResizeMethod.BILINEAR, align_corners=False): """Resize `images` to `new_width`, `new_height` using the specified `method`. Resized images will be distorted if their original aspect ratio is not the same as `new_width`, `new_height`. To avoid distortions see [`resize_image_with_crop_or_pad`](#resize_image_with_crop_or_pad). `method` can be one of: * <b>`ResizeMethod.BILINEAR`</b>: [Bilinear interpolation.] (https://en.wikipedia.org/wiki/Bilinear_interpolation) * <b>`ResizeMethod.NEAREST_NEIGHBOR`</b>: [Nearest neighbor interpolation.] (https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation) * <b>`ResizeMethod.BICUBIC`</b>: [Bicubic interpolation.] (https://en.wikipedia.org/wiki/Bicubic_interpolation) * <b>`ResizeMethod.AREA`</b>: Area interpolation. Args: images: 4-D Tensor of shape `[batch, height, width, channels]` or 3-D Tensor of shape `[height, width, channels]`. new_height: integer. new_width: integer. method: ResizeMethod. Defaults to `ResizeMethod.BILINEAR`. align_corners: bool. If true, exactly align all 4 cornets of the input and output. Defaults to `false`. Only implemented for bilinear interpolation method so far. Raises: ValueError: if the shape of `images` is incompatible with the shape arguments to this function ValueError: if an unsupported resize method is specified. Returns: If `images` was 4-D, a 4-D float Tensor of shape `[batch, new_height, new_width, channels]`. If `images` was 3-D, a 3-D float Tensor of shape `[new_height, new_width, channels]`. """ if images.get_shape().ndims is None: raise ValueError('\'images\' contains no shape.') # TODO(shlens): Migrate this functionality to the underlying Op's. is_batch = True if len(images.get_shape()) == 3: is_batch = False images = array_ops.expand_dims(images, 0) _, height, width, depth = _ImageDimensions(images) if width == new_width and height == new_height: if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images if method == ResizeMethod.BILINEAR: images = gen_image_ops.resize_bilinear(images, [new_height, new_width], align_corners=align_corners) elif method == ResizeMethod.NEAREST_NEIGHBOR: images = gen_image_ops.resize_nearest_neighbor(images, [new_height, new_width]) elif method == ResizeMethod.BICUBIC: images = gen_image_ops.resize_bicubic(images, [new_height, new_width]) elif method == ResizeMethod.AREA: images = gen_image_ops.resize_area(images, [new_height, new_width]) else: raise ValueError('Resize method is not implemented.') if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images
def resize_images(images, new_height, new_width, method=ResizeMethod.BILINEAR, align_corners=False): """Resize `images` to `new_width`, `new_height` using the specified `method`. Resized images will be distorted if their original aspect ratio is not the same as `new_width`, `new_height`. To avoid distortions see [`resize_image_with_crop_or_pad`](#resize_image_with_crop_or_pad). `method` can be one of: * <b>`ResizeMethod.BILINEAR`</b>: [Bilinear interpolation.] (https://en.wikipedia.org/wiki/Bilinear_interpolation) * <b>`ResizeMethod.NEAREST_NEIGHBOR`</b>: [Nearest neighbor interpolation.] (https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation) * <b>`ResizeMethod.BICUBIC`</b>: [Bicubic interpolation.] (https://en.wikipedia.org/wiki/Bicubic_interpolation) * <b>`ResizeMethod.AREA`</b>: Area interpolation. Args: images: 4-D Tensor of shape `[batch, height, width, channels]` or 3-D Tensor of shape `[height, width, channels]`. new_height: integer. new_width: integer. method: ResizeMethod. Defaults to `ResizeMethod.BILINEAR`. align_corners: bool. If true, exactly align all 4 corners of the input and output. Defaults to `false`. Raises: ValueError: if the shape of `images` is incompatible with the shape arguments to this function ValueError: if an unsupported resize method is specified. Returns: If `images` was 4-D, a 4-D float Tensor of shape `[batch, new_height, new_width, channels]`. If `images` was 3-D, a 3-D float Tensor of shape `[new_height, new_width, channels]`. """ images = ops.convert_to_tensor(images, name='images') if images.get_shape().ndims is None: raise ValueError('\'images\' contains no shape.') # TODO(shlens): Migrate this functionality to the underlying Op's. is_batch = True if len(images.get_shape()) == 3: is_batch = False images = array_ops.expand_dims(images, 0) _, height, width, depth = _ImageDimensions(images) # Handle tensor-valued sizes as well as Python integers. try: new_width = ops.convert_to_tensor(new_width, dtypes.int32, name='new_width') new_width.get_shape().assert_has_rank(0) except (TypeError, ValueError): raise ValueError('new_width must be a scalar integer') try: new_height = ops.convert_to_tensor(new_height, dtypes.int32, name='new_height') new_height.get_shape().assert_has_rank(0) except (TypeError, ValueError): raise ValueError('new_height must be a scalar integer') new_width_const = tensor_util.constant_value(new_width) new_height_const = tensor_util.constant_value(new_height) # If we can determine that the height and width will be unmodified by this # transformation, we avoid performing the resize. if all(x is not None for x in [new_width_const, width, new_height_const, height]) and ( width == new_width_const and height == new_height_const): if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images new_size = array_ops.pack([new_height, new_width]) if method == ResizeMethod.BILINEAR: images = gen_image_ops.resize_bilinear(images, new_size, align_corners=align_corners) elif method == ResizeMethod.NEAREST_NEIGHBOR: images = gen_image_ops.resize_nearest_neighbor(images, new_size, align_corners=align_corners) elif method == ResizeMethod.BICUBIC: images = gen_image_ops.resize_bicubic(images, new_size, align_corners=align_corners) elif method == ResizeMethod.AREA: images = gen_image_ops.resize_area(images, new_size, align_corners=align_corners) else: raise ValueError('Resize method is not implemented.') # NOTE(mrry): The shape functions for the resize ops cannot unpack # the packed values in `new_size`, so set the shape here. images.set_shape([None, new_height_const, new_width_const, None]) if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images
def resize_images(images, new_height, new_width, method=ResizeMethod.BILINEAR, align_corners=False): """Resize `images` to `new_width`, `new_height` using the specified `method`. Resized images will be distorted if their original aspect ratio is not the same as `new_width`, `new_height`. To avoid distortions see [`resize_image_with_crop_or_pad`](#resize_image_with_crop_or_pad). `method` can be one of: * <b>`ResizeMethod.BILINEAR`</b>: [Bilinear interpolation.] (https://en.wikipedia.org/wiki/Bilinear_interpolation) * <b>`ResizeMethod.NEAREST_NEIGHBOR`</b>: [Nearest neighbor interpolation.] (https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation) * <b>`ResizeMethod.BICUBIC`</b>: [Bicubic interpolation.] (https://en.wikipedia.org/wiki/Bicubic_interpolation) * <b>`ResizeMethod.AREA`</b>: Area interpolation. Args: images: 4-D Tensor of shape `[batch, height, width, channels]` or 3-D Tensor of shape `[height, width, channels]`. new_height: integer. new_width: integer. method: ResizeMethod. Defaults to `ResizeMethod.BILINEAR`. align_corners: bool. If true, exactly align all 4 corners of the input and output. Defaults to `false`. Raises: ValueError: if the shape of `images` is incompatible with the shape arguments to this function ValueError: if an unsupported resize method is specified. Returns: If `images` was 4-D, a 4-D float Tensor of shape `[batch, new_height, new_width, channels]`. If `images` was 3-D, a 3-D float Tensor of shape `[new_height, new_width, channels]`. """ images = ops.convert_to_tensor(images, name='images') if images.get_shape().ndims is None: raise ValueError('\'images\' contains no shape.') # TODO(shlens): Migrate this functionality to the underlying Op's. is_batch = True if len(images.get_shape()) == 3: is_batch = False images = array_ops.expand_dims(images, 0) _, height, width, depth = _ImageDimensions(images) # Handle tensor-valued sizes as well as Python integers. try: new_width = ops.convert_to_tensor(new_width, dtypes.int32, name='new_width') new_width.get_shape().assert_has_rank(0) except (TypeError, ValueError): raise ValueError('new_width must be a scalar integer') try: new_height = ops.convert_to_tensor(new_height, dtypes.int32, name='new_height') new_height.get_shape().assert_has_rank(0) except (TypeError, ValueError): raise ValueError('new_height must be a scalar integer') new_width_const = tensor_util.constant_value(new_width) new_height_const = tensor_util.constant_value(new_height) # If we can determine that the height and width will be unmodified by this # transformation, we avoid performing the resize. if all(x is not None for x in [new_width_const, width, new_height_const, height]) and ( width == new_width_const and height == new_height_const): if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images new_size = array_ops.pack([new_height, new_width]) if method == ResizeMethod.BILINEAR: images = gen_image_ops.resize_bilinear(images, new_size, align_corners=align_corners) elif method == ResizeMethod.NEAREST_NEIGHBOR: images = gen_image_ops.resize_nearest_neighbor( images, new_size, align_corners=align_corners) elif method == ResizeMethod.BICUBIC: images = gen_image_ops.resize_bicubic(images, new_size, align_corners=align_corners) elif method == ResizeMethod.AREA: images = gen_image_ops.resize_area(images, new_size, align_corners=align_corners) else: raise ValueError('Resize method is not implemented.') # NOTE(mrry): The shape functions for the resize ops cannot unpack # the packed values in `new_size`, so set the shape here. images.set_shape([None, new_height_const, new_width_const, None]) if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images
def resize_images(images, size, method=ResizeMethod.BILINEAR, align_corners=False): """Resize `images` to `size` using the specified `method`. Resized images will be distorted if their original aspect ratio is not the same as `size`. To avoid distortions see [`resize_image_with_crop_or_pad`](#resize_image_with_crop_or_pad). `method` can be one of: * <b>`ResizeMethod.BILINEAR`</b>: [Bilinear interpolation.](https://en.wikipedia.org/wiki/Bilinear_interpolation) * <b>`ResizeMethod.NEAREST_NEIGHBOR`</b>: [Nearest neighbor interpolation.](https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation) * <b>`ResizeMethod.BICUBIC`</b>: [Bicubic interpolation.](https://en.wikipedia.org/wiki/Bicubic_interpolation) * <b>`ResizeMethod.AREA`</b>: Area interpolation. Args: images: 4-D Tensor of shape `[batch, height, width, channels]` or 3-D Tensor of shape `[height, width, channels]`. size: A 1-D int32 Tensor of 2 elements: `new_height, new_width`. The new size for the images. method: ResizeMethod. Defaults to `ResizeMethod.BILINEAR`. align_corners: bool. If true, exactly align all 4 corners of the input and output. Defaults to `false`. Raises: ValueError: if the shape of `images` is incompatible with the shape arguments to this function ValueError: if `size` has invalid shape or type. ValueError: if an unsupported resize method is specified. Returns: If `images` was 4-D, a 4-D float Tensor of shape `[batch, new_height, new_width, channels]`. If `images` was 3-D, a 3-D float Tensor of shape `[new_height, new_width, channels]`. """ images = ops.convert_to_tensor(images, name='images') if images.get_shape().ndims is None: raise ValueError('\'images\' contains no shape.') # TODO(shlens): Migrate this functionality to the underlying Op's. is_batch = True if images.get_shape().ndims == 3: is_batch = False images = array_ops.expand_dims(images, 0) elif images.get_shape().ndims != 4: raise ValueError('\'images\' must have either 3 or 4 dimensions.') _, height, width, _ = images.get_shape().as_list() try: size = ops.convert_to_tensor(size, dtypes.int32, name='size') except (TypeError, ValueError): raise ValueError('\'size\' must be a 1-D int32 Tensor') if not size.get_shape().is_compatible_with([2]): raise ValueError('\'size\' must be a 1-D Tensor of 2 elements: ' 'new_height, new_width') size_const_as_shape = tensor_util.constant_value_as_shape(size) new_height_const = size_const_as_shape[0].value new_width_const = size_const_as_shape[1].value # If we can determine that the height and width will be unmodified by this # transformation, we avoid performing the resize. if all(x is not None for x in [new_width_const, width, new_height_const, height]) and ( width == new_width_const and height == new_height_const): if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images if method == ResizeMethod.BILINEAR: images = gen_image_ops.resize_bilinear(images, size, align_corners=align_corners) elif method == ResizeMethod.NEAREST_NEIGHBOR: images = gen_image_ops.resize_nearest_neighbor(images, size, align_corners=align_corners) elif method == ResizeMethod.BICUBIC: images = gen_image_ops.resize_bicubic(images, size, align_corners=align_corners) elif method == ResizeMethod.AREA: images = gen_image_ops.resize_area(images, size, align_corners=align_corners) else: raise ValueError('Resize method is not implemented.') # NOTE(mrry): The shape functions for the resize ops cannot unpack # the packed values in `new_size`, so set the shape here. images.set_shape([None, new_height_const, new_width_const, None]) if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images
def resize_images(images, new_height, new_width, method=ResizeMethod.BILINEAR): """Resize `images` to `new_width`, `new_height` using the specified `method`. Resized images will be distorted if their original aspect ratio is not the same as `new_width`, `new_height`. To avoid distortions see [`resize_image_with_crop_or_pad`](#resize_image_with_crop_or_pad). `method` can be one of: * <b>`ResizeMethod.BILINEAR`</b>: [Bilinear interpolation.] (https://en.wikipedia.org/wiki/Bilinear_interpolation) * <b>`ResizeMethod.NEAREST_NEIGHBOR`</b>: [Nearest neighbor interpolation.] (https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation) * <b>`ResizeMethod.BICUBIC`</b>: [Bicubic interpolation.] (https://en.wikipedia.org/wiki/Bicubic_interpolation) * <b>`ResizeMethod.AREA`</b>: Area interpolation. Args: images: 4-D Tensor of shape `[batch, height, width, channels]` or 3-D Tensor of shape `[height, width, channels]`. new_height: integer. new_width: integer. method: ResizeMethod. Defaults to `ResizeMethod.BILINEAR`. Raises: ValueError: if the shape of `images` is incompatible with the shape arguments to this function ValueError: if an unsupported resize method is specified. Returns: If `images` was 4-D, a 4-D float Tensor of shape `[batch, new_height, new_width, channels]`. If `images` was 3-D, a 3-D float Tensor of shape `[new_height, new_width, channels]`. """ if images.get_shape().ndims is None: raise ValueError('\'images\' contains no shape.') # TODO(shlens): Migrate this functionality to the underlying Op's. is_batch = True if len(images.get_shape()) == 3: is_batch = False images = array_ops.expand_dims(images, 0) _, height, width, depth = _ImageDimensions(images) if width == new_width and height == new_height: if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images if method == ResizeMethod.BILINEAR: images = gen_image_ops.resize_bilinear(images, [new_height, new_width]) elif method == ResizeMethod.NEAREST_NEIGHBOR: images = gen_image_ops.resize_nearest_neighbor(images, [new_height, new_width]) elif method == ResizeMethod.BICUBIC: images = gen_image_ops.resize_bicubic(images, [new_height, new_width]) elif method == ResizeMethod.AREA: images = gen_image_ops.resize_area(images, [new_height, new_width]) else: raise ValueError('Resize method is not implemented.') if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images