//  [python]
def apply(self, tensor, seed, key,
            video_shape):
    """Applies the crop operation on tensor."""
    param = self.sample_augmentation_params(video_shape, seed)
    si, sj = param[0], param[1]
    crop_h, crop_w = param[2], param[3]

    to_float32 = lambda x: tf.cast(x, tf.float32)

    if key == self.boxes_key:
      # First crop the boxes.
      cropped_boxes = crop_or_pad_boxes(
          tensor, si, sj,
          crop_h, crop_w,
          video_shape[1], video_shape[2])
      # We do not need to scale the boxes because they are in normalized coords.
      resized_boxes = cropped_boxes
      # Lastly detects NOTRACK_BOX boxes and avoid manipulating those.
      no_track_boxes = tf.convert_to_tensor(NOTRACK_BOX)
      no_track_boxes = tf.reshape(no_track_boxes, [1, 4])
      resized_boxes = tf.where(
          tf.reduce_all(tensor == no_track_boxes, axis=-1, keepdims=True),
          tensor, resized_boxes)

      if self.relative_box_area_threshold > 0:
        # Thresholds boxes that have been cropped too much, as in their area is
        # lower, in relative terms, than `relative_box_area_threshold`.
        area_before_crop = tf.reduce_prod(tensor[Ellipsis, 2:] - tensor[Ellipsis, :2],
                                          axis=-1)
        # Sets minimum area_before_crop to 1e-8 we avoid divisions by 0.
        area_before_crop = tf.maximum(area_before_crop,
                                      tf.zeros_like(area_before_crop) + 1e-8)
        area_after_crop = tf.reduce_prod(
            resized_boxes[Ellipsis, 2:] - resized_boxes[Ellipsis, :2], axis=-1)
        # As the boxes have normalized coordinates, they need to be rescaled to
        # be compared against the original uncropped boxes.
        scale_x = to_float32(crop_w) / to_float32(self.width)
        scale_y = to_float32(crop_h) / to_float32(self.height)
        area_after_crop *= scale_x * scale_y

        ratio = area_after_crop / area_before_crop
        return tf.where(
            tf.expand_dims(ratio > self.relative_box_area_threshold, -1),
            resized_boxes, no_track_boxes)

      else:
        return resized_boxes

    else:
      if key in (self.padding_mask_key, self.segmentations_key):
        tensor = tensor[Ellipsis, tf.newaxis]

      # Crop.
      seq_len, n_channels = tensor.get_shape()[0], tensor.get_shape()[3]
      crop_size = (seq_len, crop_h, crop_w, n_channels)
      tensor = tf.slice(tensor, tf.stack([0, si, sj, 0]), crop_size)

      # Resize.
      resize_method = tf.image.ResizeMethod.BILINEAR
      if (tensor.dtype == tf.int32 or tensor.dtype == tf.int64 or
          tensor.dtype == tf.uint8):
        resize_method = tf.image.ResizeMethod.NEAREST_NEIGHBOR
      tensor = tf.image.resize(tensor, [self.height, self.width],
                               method=resize_method)
      out_size = (seq_len, self.height, self.width, n_channels)
      tensor = tf.ensure_shape(tensor, out_size)

      if key == self.flow_key:
        # Rescales optical flow.
        scale_x = to_float32(self.width) / to_float32(crop_w)
        scale_y = to_float32(self.height) / to_float32(crop_h)
        tensor = tf.stack(
            [tensor[Ellipsis, 0] * scale_y, tensor[Ellipsis, 1] * scale_x], axis=-1)

      if key in (self.padding_mask_key, self.segmentations_key):
        tensor = tensor[Ellipsis, 0]
      return tensor