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( 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", 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". 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. """ 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 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( images, 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 _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( images=grad, transforms=transforms, output_shape=array_ops.shape(image_or_images)[1:3], interpolation=interpolation) return [output, None, None]
def test_projective_transform_v1(self): """The original ImageProjectiveTransform op should take 2 arguments.""" image = constant_op.constant([[[[1], [0]], [[0], [1]]]]) transform = constant_op.constant([[1., 0., 0., 0., 1., 0., 0., 0.]]) result = gen_image_ops.image_projective_transform( image, transform, interpolation="NEAREST") with self.cached_session(): self.assertAllEqual([[[[1], [0]], [[0], [1]]]], result.eval())
def transform(images, transforms): """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). 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. 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. """ 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(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 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.") # pylint: disable=protected-access output = gen_image_ops.image_projective_transform(images, transforms) 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): """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). 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. 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. """ 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(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 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.") # pylint: disable=protected-access output = gen_image_ops.image_projective_transform(images, transforms) 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_4d(images, transforms, interpolation="NEAREST"): """ A variant of tensorflow.contrib.image.python.ops.image_ops.rotate.transform that only works on 4D tensors, without checking image rank. when the shape of images is unknown, len(image_or_images.get_shape()) will raise error. 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). 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. interpolation: Interpolation mode. Supported values: "NEAREST", "BILINEAR". 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. """ images = ops.convert_to_tensor(images, name="images") transform_or_transforms = ops.convert_to_tensor(transforms, name="transforms", dtype=dtypes.float32) if images.dtype.base_dtype not in _IMAGE_DTYPES: raise TypeError("Invalid dtype %s." % 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.") output = gen_image_ops.image_projective_transform( images, transforms, interpolation=interpolation.upper()) return output
def _image_projective_transform_grad(op, grad): images = op.inputs[0] transforms = op.inputs[1] 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(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 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 = _transform_matrices_to_flat(inverse) output = gen_image_ops.image_projective_transform(grad, transforms) if len(image_or_images.get_shape()) == 2: return [output[0, :, :, 0], None] elif len(image_or_images.get_shape()) == 3: return [output[0, :, :, :], None] else: return [output, None]
def _image_projective_transform_grad(op, grad): images = op.inputs[0] transforms = op.inputs[1] 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(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 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 = _transform_matrices_to_flat(inverse) output = gen_image_ops.image_projective_transform(grad, transforms) if len(image_or_images.get_shape()) == 2: return [output[0, :, :, 0], None] elif len(image_or_images.get_shape()) == 3: return [output[0, :, :, :], None] else: return [output, None]