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_arr = np.asarray(img, np.uint8)
        crops: List[NDArray[np.uint8]] = []
        for i in range(self.n_grid * self.n_grid):
            crops.append(
                img_arr[
                    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]
Performs the Jigsaw augmentation
        Args:
            img:
                PIL image to perform Jigsaw augmentation on.

        Returns:
            Torch tensor with stacked crops.
        
lightly/transforms/jigsaw.py