class_docstr: This module implements Expectation over Transformation preprocessing for image center crop in PyTorch.
docstr: Center crop an input image and its labels by randomly sampled crop size.
  
  :param x: Input samples.
  :param y: Label of the samples `x`.
  :return: Transformed samples and labels.
code: def _transform(
      self,
      x: "torch.Tensor",
      y: Optional[
          Union["torch.Tensor", List[Dict[str, "torch.Tensor"]]]
      ],
      **kwargs,
  ) -> Tuple[
      "torch.Tensor",
      Optional[Union["torch.Tensor", List[Dict[str, "torch.Tensor"]]]],
  ]:
      """
      Center crop an input image and its labels by randomly sampled crop size.
  
      :param x: Input samples.
      :param y: Label of the samples `x`.
      :return: Transformed samples and labels.
      """
      import torch
      import torchvision
  
      size = np.random.randint(
          low=self.size_range[0], high=self.size_range[1]
      )
  
      # Ensure channels-first
      channels_first = True
      if x.shape[-1] in [1, 3]:
          x = torch.permute(x, (0, 3, 1, 2))
          channels_first = False
  
      x_preprocess = torchvision.transforms.functional.resized_crop(
          img=x,
          top=size,
          left=size,
          height=x.shape[-2] - 2 * size,
          width=x.shape[-1] - 2 * size,
          size=x.shape[-2:-1],
          interpolation=torchvision.transforms.functional.InterpolationMode.NEAREST,
      )
  
      x_preprocess = torch.clamp(
          input=x_preprocess,
          min=-self.clip_values[0],
          max=self.clip_values[1],
      )
  
      y_preprocess: Optional[
          Union["torch.Tensor", List[Dict[str, "torch.Tensor"]]]
      ]
  
      if self.label_type == "object_detection" and y is not None:
          y_od: List[Dict[str, "torch.Tensor"]] = [{}]
  
          if isinstance(y, list):
              if isinstance(y[0], dict):
                  y_od[0]["boxes"] = torch.clone(y[0]["boxes"])
                  y_od[0]["labels"] = torch.clone(y[0]["labels"])
              else:
                  raise TypeError(
                      "Wrong type for `y` and label_type=object_detection."
                  )
          else:
              raise TypeError(
                  "Wrong type for `y` and label_type=object_detection."
              )
  
          ratio_h = x.shape[-2] / (x.shape[-2] - 2 * size)
          ratio_w = x.shape[-1] / (x.shape[-1] - 2 * size)
  
          # top-left corner
  
          y_od[0]["boxes"][:, 0] -= size
          y_od[0]["boxes"][:, 1] -= size
  
          y_od[0]["boxes"][:, 0] = y_od[0]["boxes"][:, 0] * ratio_h
          y_od[0]["boxes"][:, 1] = y_od[0]["boxes"][:, 1] * ratio_w
  
          y_od[0]["boxes"][:, 0] = torch.maximum(
              torch.tensor(0), y_od[0]["boxes"][:, 0]
          ).int()
          y_od[0]["boxes"][:, 1] = torch.maximum(
              torch.tensor(0), y_od[0]["boxes"][:, 1]
          ).int()
  
          # bottom-right corner
  
          y_od[0]["boxes"][:, 2] -= size
          y_od[0]["boxes"][:, 3] -= size
  
          y_od[0]["boxes"][:, 2] = y_od[0]["boxes"][:, 2] * ratio_h
          y_od[0]["boxes"][:, 3] = y_od[0]["boxes"][:, 3] * ratio_w
  
          y_od[0]["boxes"][:, 2] = torch.minimum(
              y_od[0]["boxes"][:, 2], torch.tensor(x.shape[-2])
          ).int()
          y_od[0]["boxes"][:, 3] = torch.minimum(
              y_od[0]["boxes"][:, 3], torch.tensor(x.shape[-1])
          ).int()
  
          y_preprocess = y_od
  
      else:
          y_preprocess = y
  
      if not channels_first:
          x_preprocess = torch.permute(x_preprocess, (0, 2, 3, 1))
  
      return x_preprocess, y_preprocess
  
file_path: adversarial-robustness-toolbox/art/preprocessing/expectation_over_transformation/image_center_crop/pytorch.py
imports: import logging
  from typing import Dict, List, Optional, TYPE_CHECKING, Tuple, Union
  import numpy
  from art.preprocessing.expectation_over_transformation.pytorch import EoTPyTorch
label_desc: Use image node_id 2 for calling the EoTImageCenterCropPyTorch obj's underlying member method code with example usage: obj._transform(x, y) and returns: x_preprocess,  y_preprocess