def _image_projective_transform_grad(op, grad): """Computes the gradient for ImageProjectiveTransform.""" images = op.inputs[0] transforms = op.inputs[1] interpolation = op.get_attr("interpolation") image_or_images = ops.convert_to_tensor(images, name="images") transform_or_transforms = ops.convert_to_tensor( transforms, name="transforms", dtype=dtypes.float32) if image_or_images.dtype.base_dtype not in _IMAGE_DTYPES: raise TypeError("Invalid dtype %s." % image_or_images.dtype) if len(transform_or_transforms.get_shape()) == 1: transforms = transform_or_transforms[None] elif len(transform_or_transforms.get_shape()) == 2: transforms = transform_or_transforms else: raise TypeError("Transforms should have rank 1 or 2.") # Invert transformations transforms = flat_transforms_to_matrices(transforms=transforms) inverse = linalg_ops.matrix_inverse(transforms) transforms = matrices_to_flat_transforms(inverse) output = gen_image_ops.image_projective_transform_v2( images=grad, transforms=transforms, output_shape=array_ops.shape(image_or_images)[1:3], interpolation=interpolation) return [output, None, None]
def _image_projective_transform_grad(op, grad): """Computes the gradient for ImageProjectiveTransform.""" images = op.inputs[0] transforms = op.inputs[1] interpolation = op.get_attr("interpolation") image_or_images = ops.convert_to_tensor(images, name="images") transform_or_transforms = ops.convert_to_tensor( transforms, name="transforms", dtype=dtypes.float32) if image_or_images.dtype.base_dtype not in _IMAGE_DTYPES: raise TypeError("Invalid dtype %s." % image_or_images.dtype) if len(transform_or_transforms.get_shape()) == 1: transforms = transform_or_transforms[None] elif len(transform_or_transforms.get_shape()) == 2: transforms = transform_or_transforms else: raise TypeError("Transforms should have rank 1 or 2.") # Invert transformations transforms = flat_transforms_to_matrices(transforms=transforms) inverse = linalg_ops.matrix_inverse(transforms) transforms = matrices_to_flat_transforms(inverse) output = gen_image_ops.image_projective_transform_v2( images=grad, transforms=transforms, output_shape=array_ops.shape(image_or_images)[1:3], interpolation=interpolation) return [output, None, None]
def transform(images, transforms, interpolation="NEAREST", output_shape=None, name=None): """Applies the given transform(s) to the image(s). Args: images: A tensor of shape (num_images, num_rows, num_columns, num_channels) (NHWC), (num_rows, num_columns, num_channels) (HWC), or (num_rows, num_columns) (HW). The rank must be statically known (the shape is not `TensorShape(None)`. transforms: Projective transform matrix/matrices. A vector of length 8 or tensor of size N x 8. If one row of transforms is [a0, a1, a2, b0, b1, b2, c0, c1], then it maps the *output* point `(x, y)` to a transformed *input* point `(x', y') = ((a0 x + a1 y + a2) / k, (b0 x + b1 y + b2) / k)`, where `k = c0 x + c1 y + 1`. The transforms are *inverted* compared to the transform mapping input points to output points. Note that gradients are not backpropagated into transformation parameters. interpolation: Interpolation mode. Supported values: "NEAREST", "BILINEAR". output_shape: Output dimesion after the transform, [height, width]. If None, output is the same size as input image. name: The name of the op. Returns: Image(s) with the same type and shape as `images`, with the given transform(s) applied. Transformed coordinates outside of the input image will be filled with zeros. Raises: TypeError: If `image` is an invalid type. ValueError: If output shape is not 1-D int32 Tensor. """ with ops.name_scope(name, "transform"): image_or_images = ops.convert_to_tensor(images, name="images") transform_or_transforms = ops.convert_to_tensor( transforms, name="transforms", dtype=dtypes.float32) if image_or_images.dtype.base_dtype not in _IMAGE_DTYPES: raise TypeError("Invalid dtype %s." % image_or_images.dtype) elif image_or_images.get_shape().ndims is None: raise TypeError("image_or_images rank must be statically known") elif len(image_or_images.get_shape()) == 2: images = image_or_images[None, :, :, None] elif len(image_or_images.get_shape()) == 3: images = image_or_images[None, :, :, :] elif len(image_or_images.get_shape()) == 4: images = image_or_images else: raise TypeError("Images should have rank between 2 and 4.") if output_shape is None: output_shape = tensor_util.constant_value( array_ops.shape(images)[1:3]) or array_ops.shape(images)[1:3] output_shape = ops.convert_to_tensor( output_shape, dtypes.int32, name="output_shape") if not output_shape.get_shape().is_compatible_with([2]): raise ValueError("output_shape must be a 1-D Tensor of 2 elements: " "new_height, new_width") if len(transform_or_transforms.get_shape()) == 1: transforms = transform_or_transforms[None] elif transform_or_transforms.get_shape().ndims is None: raise TypeError( "transform_or_transforms rank must be statically known") elif len(transform_or_transforms.get_shape()) == 2: transforms = transform_or_transforms else: raise TypeError("Transforms should have rank 1 or 2.") output = gen_image_ops.image_projective_transform_v2( images, output_shape=output_shape, transforms=transforms, interpolation=interpolation.upper()) if len(image_or_images.get_shape()) == 2: return output[0, :, :, 0] elif len(image_or_images.get_shape()) == 3: return output[0, :, :, :] else: return output
def transform(images, transforms, interpolation="NEAREST", output_shape=None, name=None): """Applies the given transform(s) to the image(s). Args: images: A tensor of shape (num_images, num_rows, num_columns, num_channels) (NHWC), (num_rows, num_columns, num_channels) (HWC), or (num_rows, num_columns) (HW). The rank must be statically known (the shape is not `TensorShape(None)`. transforms: Projective transform matrix/matrices. A vector of length 8 or tensor of size N x 8. If one row of transforms is [a0, a1, a2, b0, b1, b2, c0, c1], then it maps the *output* point `(x, y)` to a transformed *input* point `(x', y') = ((a0 x + a1 y + a2) / k, (b0 x + b1 y + b2) / k)`, where `k = c0 x + c1 y + 1`. The transforms are *inverted* compared to the transform mapping input points to output points. Note that gradients are not backpropagated into transformation parameters. interpolation: Interpolation mode. Supported values: "NEAREST", "BILINEAR". output_shape: Output dimesion after the transform, [height, width]. If None, output is the same size as input image. name: The name of the op. Returns: Image(s) with the same type and shape as `images`, with the given transform(s) applied. Transformed coordinates outside of the input image will be filled with zeros. Raises: TypeError: If `image` is an invalid type. ValueError: If output shape is not 1-D int32 Tensor. """ with ops.name_scope(name, "transform"): image_or_images = ops.convert_to_tensor(images, name="images") transform_or_transforms = ops.convert_to_tensor( transforms, name="transforms", dtype=dtypes.float32) if image_or_images.dtype.base_dtype not in _IMAGE_DTYPES: raise TypeError("Invalid dtype %s." % image_or_images.dtype) elif image_or_images.get_shape().ndims is None: raise TypeError("image_or_images rank must be statically known") elif len(image_or_images.get_shape()) == 2: images = image_or_images[None, :, :, None] elif len(image_or_images.get_shape()) == 3: images = image_or_images[None, :, :, :] elif len(image_or_images.get_shape()) == 4: images = image_or_images else: raise TypeError("Images should have rank between 2 and 4.") if output_shape is None: output_shape = tensor_util.constant_value( array_ops.shape(images)[1:3]) or array_ops.shape(images)[1:3] output_shape = ops.convert_to_tensor( output_shape, dtypes.int32, name="output_shape") if not output_shape.get_shape().is_compatible_with([2]): raise ValueError("output_shape must be a 1-D Tensor of 2 elements: " "new_height, new_width") if len(transform_or_transforms.get_shape()) == 1: transforms = transform_or_transforms[None] elif transform_or_transforms.get_shape().ndims is None: raise TypeError( "transform_or_transforms rank must be statically known") elif len(transform_or_transforms.get_shape()) == 2: transforms = transform_or_transforms else: raise TypeError("Transforms should have rank 1 or 2.") output = gen_image_ops.image_projective_transform_v2( images, output_shape=output_shape, transforms=transforms, interpolation=interpolation.upper()) if len(image_or_images.get_shape()) == 2: return output[0, :, :, 0] elif len(image_or_images.get_shape()) == 3: return output[0, :, :, :] else: return output