class_docstr: Class that generates noisy augmentations of input images.
  
  Args:
      anomaly_source_path (str | None): Path to a folder of images that will be used as source of the anomalous
      noise. If not specified, random noise will be used instead.
      p_anomalous (float): Probability that the anomalous perturbation will be applied to a given image.
      beta (float): Parameter that determines the opacity of the noise mask.
class_docstr_tok: ["Class","that","generates","noisy","augmentations","of","input","images",".","Args",":","anomaly_source_path","(","str","|","None",")",":","Path","to","a","folder","of","images","that","will","be","used","as","source","of","the","anomalous","noise",".","If","not","specified",",","random","noise","will","be","used","instead",".","p_anomalous","(","float",")",":","Probability","that","the","anomalous","perturbation","will","be","applied","to","a","given","image",".","beta","(","float",")",":","Parameter","that","determines","the","opacity","of","the","noise","mask","."]
docstr: Generate anomalous augmentations for a batch of input images.
  
  Args:
      batch (Tensor): Batch of input images
  
  Returns:
      - Augmented image to which anomalous perturbations have been added.
      - Ground truth masks corresponding to the anomalous perturbations.
docstr_tok: ["Generate","anomalous","augmentations","for","a","batch","of","input","images",".","Args",":","batch","(","Tensor",")",":","Batch","of","input","images","Returns",":","-","Augmented","image","to","which","anomalous","perturbations","have","been","added",".","-","Ground","truth","masks","corresponding","to","the","anomalous","perturbations","."]
code: def augment_batch(self, batch: Tensor) -> tuple[Tensor, Tensor]:
      """Generate anomalous augmentations for a batch of input images.
  
      Args:
          batch (Tensor): Batch of input images
  
      Returns:
          - Augmented image to which anomalous perturbations have been added.
          - Ground truth masks corresponding to the anomalous perturbations.
      """
      batch_size, channels, height, width = batch.shape
  
      # Collect perturbations
      perturbations_list = []
      masks_list = []
      for _ in range(batch_size):
          if torch.rand(1) > self.p_anomalous:  # include normal samples
              perturbations_list.append(
                  torch.zeros((channels, height, width))
              )
              masks_list.append(torch.zeros((1, height, width)))
          else:
              anomaly_source_path = (
                  random.sample(self.anomaly_source_paths, 1)[0]
                  if len(self.anomaly_source_paths) > 0
                  else None
              )
              perturbation, mask = self.generate_perturbation(
                  height, width, anomaly_source_path
              )
              perturbations_list.append(
                  Tensor(perturbation).permute((2, 0, 1))
              )
              masks_list.append(Tensor(mask).permute((2, 0, 1)))
  
      perturbations = torch.stack(perturbations_list).to(batch.device)
      masks = torch.stack(masks_list).to(batch.device)
  
      # Apply perturbations batch wise
      if isinstance(self.beta, float):
          beta = self.beta
      elif isinstance(self.beta, tuple):
          beta = (
              torch.rand(batch_size) * (self.beta[1] - self.beta[0])
              + self.beta[0]
          )
          beta = beta.view(batch_size, 1, 1, 1).expand_as(batch).to(batch.device)  # type: ignore
      else:
          raise ValueError(
              "Beta must be either float or tuple of floats"
          )
  
      augmented_batch = (
          batch * (1 - masks)
          + (beta) * perturbations
          + (1 - beta) * batch * (masks)
      )
  
      return augmented_batch, masks
  
file_path: anomalib/src/anomalib/data/utils/augmenter.py
imports: from __future__ import annotations
  import glob
  import math
  import random
  import cv2
  import imgaug.augmenters
  import numpy
  import torch
  from torch import Tensor
  from torchvision.datasets.folder import IMG_EXTENSIONS
  from anomalib.data.utils.generators.perlin import random_2d_perlin
label_desc: Use image node_id 4 for calling the Augmenter obj's underlying member method code with example usage: obj.augment_batch(batch) and returns: augmented_batch,  masks