class_docstr: Implementation of Jigsaw image augmentation, inspired from PyContrast library.
  
  Generates n_grid**2 random crops and returns a list.
  
  This augmentation is instrumental to PIRL.
  
  Attributes:
      n_grid:
          Side length of the meshgrid, sqrt of the number of crops.
      img_size:
          Size of image.
      crop_size:
          Size of crops.
      transform:
          Transformation to apply on each crop.
  
  Examples:
      >>> from lightly.transforms import Jigsaw
      >>>
      >>> jigsaw_crop = Jigsaw(n_grid=3, img_size=255, crop_size=64, transform=transforms.ToTensor())
      >>>
      >>> # img is a PIL image
      >>> crops = jigsaw_crops(img)
docstr: Performs the Jigsaw augmentation
  Args:
      img:
          PIL image to perform Jigsaw augmentation on.
  
  Returns:
      Torch tensor with stacked crops.
docstr_tok: ["Performs","the","Jigsaw","augmentation","Args",":","img",":","PIL","image","to","perform","Jigsaw","augmentation","on",".","Returns",":","Torch","tensor","with","stacked","crops","."]
code: def __call__(self, img: PILImage) -> Tensor:
      """Performs the Jigsaw augmentation
      Args:
          img:
              PIL image to perform Jigsaw augmentation on.
  
      Returns:
          Torch tensor with stacked crops.
      """
      r_x = np.random.randint(
          0, self.side + 1, self.n_grid * self.n_grid
      )
      r_y = np.random.randint(
          0, self.side + 1, self.n_grid * self.n_grid
      )
      img = np.asarray(img, np.uint8)
      crops: List[PILImage] = []
      for i in range(self.n_grid * self.n_grid):
          crops.append(
              img[
                  self.xx[i]
                  + r_x[i] : self.xx[i]
                  + r_x[i]
                  + self.crop_size,
                  self.yy[i]
                  + r_y[i] : self.yy[i]
                  + r_y[i]
                  + self.crop_size,
                  :,
              ]
          )
      crop_images = [Image.fromarray(crop) for crop in crops]
      crop_tensors: Tensor = torch.stack(
          [self.transform(crop) for crop in crop_images]
      )
      permutation: List[int] = np.random.permutation(
          self.n_grid**2
      ).tolist()
      return crop_tensors[permutation]
  
file_path: lightly/lightly/transforms/jigsaw.py
imports: from typing import List
  import numpy
  import torch
  from PIL import Image
  from PIL.Image import Image
  from torch import Tensor
  from torchvision import transforms
label_desc: Use image node_id 2 for calling the Jigsaw obj's underlying member method code with example usage: obj.__call__(img) and returns: crop_tensors