code: def dense_image_warp(image, flow):
      """Image warping using per-pixel flow vectors.
  
      Apply a non-linear warp to the image, where the warp is specified by a dense
      flow field of offset vectors that define the correspondences of pixel values
      in the output image back to locations in the  source image. Specifically, the
      pixel value at output[b, j, i, c] is
      images[b, j - flow[b, j, i, 0], i - flow[b, j, i, 1], c].
      The locations specified by this formula do not necessarily map to an int
      index. Therefore, the pixel value is obtained by bilinear
      interpolation of the 4 nearest pixels around
      (b, j - flow[b, j, i, 0], i - flow[b, j, i, 1]). For locations outside
      of the image, we use the nearest pixel values at the image boundary.
      Args:
      image: 4-D float `Tensor` with shape `[batch, height, width, channels]`.
      flow: A 4-D float `Tensor` with shape `[batch, height, width, 2]`.
      name: A name for the operation (optional).
      Note that image and flow can be of type tf.half, tf.float32, or tf.float64,
      and do not necessarily have to be the same type.
      Returns:
      A 4-D float `Tensor` with shape`[batch, height, width, channels]`
      and same type as input image.
      Raises:
      ValueError: if height < 2 or width < 2 or the inputs have the wrong number
      of dimensions.
      """
      image = image.unsqueeze(
          3
      )  # add a single channel dimension to image tensor
      batch_size, height, width, channels = image.shape
      device = image.device
  
      # The flow is defined on the image grid. Turn the flow into a list of query
      # points in the grid space.
      grid_x, grid_y = torch.meshgrid(
          torch.arange(width, device=device),
          torch.arange(height, device=device),
      )
  
      stacked_grid = torch.stack((grid_y, grid_x), dim=2).float()
  
      batched_grid = stacked_grid.unsqueeze(-1).permute(3, 1, 0, 2)
  
      query_points_on_grid = batched_grid - flow
      query_points_flattened = torch.reshape(
          query_points_on_grid, [batch_size, height * width, 2]
      )
      # Compute values at the query points, then reshape the result back to the
      # image grid.
      interpolated = interpolate_bilinear(image, query_points_flattened)
      interpolated = torch.reshape(
          interpolated, [batch_size, height, width, channels]
      )
      return interpolated
  
file_path: espnet/espnet/utils/spec_augment.py
imports: import random
  import torch
label_desc: Use image node_id 15 for calling a global function with example usage: dense_image_warp(image, flow) and returns: interpolated