code: def perspective_transform(
      image: type_alias.TensorLike,
      transform_matrix: type_alias.TensorLike,
      output_shape: Optional[type_alias.TensorLike] = None,
      resampling_type: ResamplingType = ResamplingType.BILINEAR,
      border_type: BorderType = BorderType.ZERO,
      pixel_type: PixelType = PixelType.HALF_INTEGER,
      name: Optional[str] = "perspective_transform",
  ) -> tf.Tensor:
      """Applies a projective transformation to an image.
  
      The projective transformation is represented by a 3 x 3 matrix
      [[a0, a1, a2], [b0, b1, b2], [c0, c1, c2]], mapping a point `[x, y]` to a
      transformed point
      `[x', y'] = [(a0 x + a1 y + a2) / k, (b0 x + b1 y + b2) / k]`, where
      `k = c0 x + c1 y + c2`.
  
      Note:
          The transformation matrix maps target to source by transforming output
          points to input points.
  
      Args:
        image: A tensor of shape `[B, H_i, W_i, C]`, where `B` is the batch size,
          `H_i` the height of the image, `W_i` the width of the image, and `C` the
          number of channels of the image.
        transform_matrix: A tensor of shape `[B, 3, 3]` containing projective
          transform matrices. The transformation maps target to source by
          transforming output points to input points.
        output_shape: The heigh `H_o` and width `W_o` output dimensions after the
          transform. If None, output is the same size as input image.
        resampling_type: Resampling mode. Supported values are
          `ResamplingType.NEAREST` and `ResamplingType.BILINEAR`.
        border_type: Border mode. Supported values are `BorderType.ZERO` and
          `BorderType.DUPLICATE`.
        pixel_type: Pixel mode. Supported values are `PixelType.INTEGER` and
          `PixelType.HALF_INTEGER`.
        name: A name for this op. Defaults to "perspective_transform".
  
      Returns:
        A tensor of shape `[B, H_o, W_o, C]` containing transformed images.
  
      Raises:
        ValueError: If `image` has rank != 4. If `transform_matrix` has rank < 3 or
        its last two dimensions are not 3. If `image` and `transform_matrix` batch
        dimension does not match.
      """
      with tf.name_scope(name):
          image = tf.convert_to_tensor(value=image, name="image")
          transform_matrix = tf.convert_to_tensor(
              value=transform_matrix, name="transform_matrix"
          )
          output_shape = (
              tf.shape(input=image)[-3:-1]
              if output_shape is None
              else tf.convert_to_tensor(
                  value=output_shape, name="output_shape"
              )
          )
  
          shape.check_static(image, tensor_name="image", has_rank=4)
          shape.check_static(
              transform_matrix,
              tensor_name="transform_matrix",
              has_rank=3,
              has_dim_equals=((-1, 3), (-2, 3)),
          )
          shape.compare_batch_dimensions(
              tensors=(image, transform_matrix),
              last_axes=0,
              broadcast_compatible=False,
          )
  
          dtype = image.dtype
          zero = tf.cast(0.0, dtype)
          height, width = tf.unstack(output_shape, axis=-1)
          warp = grid.generate(
              starts=(zero, zero),
              stops=(
                  tf.cast(width, dtype) - 1.0,
                  tf.cast(height, dtype) - 1.0,
              ),
              nums=(width, height),
          )
          warp = tf.transpose(a=warp, perm=[1, 0, 2])
  
          if pixel_type == PixelType.HALF_INTEGER:
              warp += 0.5
  
          padding = [[0, 0] for _ in range(warp.shape.ndims)]
          padding[-1][-1] = 1
          warp = tf.pad(
              tensor=warp,
              paddings=padding,
              mode="CONSTANT",
              constant_values=1.0,
          )
  
          warp = warp[..., tf.newaxis]
          transform_matrix = transform_matrix[
              :, tf.newaxis, tf.newaxis, ...
          ]
          warp = tf.linalg.matmul(transform_matrix, warp)
          warp = warp[..., 0:2, 0] / warp[..., 2, :]
  
          return sample(
              image, warp, resampling_type, border_type, pixel_type
          )
  
file_path: graphics/tensorflow_graphics/image/transformer.py
imports: import enum
  from typing import Optional
  from six.moves import range
  import tensorflow
  from tensorflow_addons import image
  from tensorflow_graphics.geometry.representation import grid
  from tensorflow_graphics.util import export_api
  from tensorflow_graphics.util import shape
  from tensorflow_graphics.util import type_alias
label_desc: Use image node_id 2 for calling a global function with example usage: perspective_transform(image, transform_matrix, output_shape, resampling_type, border_type, pixel_type, name) and returns: sample