docstr: Perturbs an image by altering the values of selected superpixels. If a dataset of image
  backgrounds is provided to the explainer, then the superpixels are replaced with the
  equivalent superpixels from the background image. Otherwise, the superpixels are replaced
  by their average value.
  
  Parameters
  ----------
  anchor:
      Contains the superpixels whose values are not going to be perturbed.
  num_samples:
      Number of perturbed samples to be returned.
  
  Returns
  -------
  imgs
      A `[num_samples, H, W, C]` array of perturbed images.
  segments_mask
      A `[num_samples, M]` binary mask, where `M` is the number of image superpixels
      segments. 1 indicates the values in that particular superpixels are not
      perturbed.
docstr_tok: ["Perturbs","an","image","by","altering","the","values","of","selected","superpixels",".","If","a","dataset","of","image","backgrounds","is","provided","to","the","explainer",",","then","the","superpixels","are","replaced","with","the","equivalent","superpixels","from","the","background","image",".","Otherwise",",","the","superpixels","are","replaced","by","their","average","value",".","Parameters","--","--","--","--","--","anchor",":","Contains","the","superpixels","whose","values","are","not","going","to","be","perturbed",".","num_samples",":","Number","of","perturbed","samples","to","be","returned",".","Returns","--","--","--","-","imgs","A","`","[","num_samples",",","H",",","W",",","C","]","`","array","of","perturbed","images",".","segments_mask","A","`","[","num_samples",",","M","]","`","binary","mask",",","where","`","M","`","is","the","number","of","image","superpixels","segments",".","1","indicates","the","values","in","that","particular","superpixels","are","not","perturbed","."]
code: def perturbation(
      self, anchor: tuple, num_samples: int
  ) -> Tuple[np.ndarray, np.ndarray]:
      """
      Perturbs an image by altering the values of selected superpixels. If a dataset of image
      backgrounds is provided to the explainer, then the superpixels are replaced with the
      equivalent superpixels from the background image. Otherwise, the superpixels are replaced
      by their average value.
  
      Parameters
      ----------
      anchor:
          Contains the superpixels whose values are not going to be perturbed.
      num_samples:
          Number of perturbed samples to be returned.
  
      Returns
      -------
      imgs
          A `[num_samples, H, W, C]` array of perturbed images.
      segments_mask
          A `[num_samples, M]` binary mask, where `M` is the number of image superpixels
          segments. 1 indicates the values in that particular superpixels are not
          perturbed.
      """
  
      image = self.image
      segments = self.segments
      backgrounds: Union[np.ndarray, List[None]]
  
      # choose superpixels to be perturbed
      segments_mask = self._choose_superpixels(
          num_samples, p_sample=self.p_sample
      )
      segments_mask[:, anchor] = 1
  
      # for each sample, need to sample one of the background images if provided
      if self.images_background is not None:
          backgrounds = np.random.choice(
              range(len(self.images_background)),
              segments_mask.shape[0],
              replace=True,
          )
      else:
          backgrounds = [None] * segments_mask.shape[0]
          # create fudged image where the pixel value in each superpixel is set to the
          # average over the superpixel for each channel
          fudged_image = image.copy()
          n_channels = image.shape[-1]
          for x in np.unique(segments):
              fudged_image[segments == x] = [
                  np.mean(image[segments == x][:, i])
                  for i in range(n_channels)
              ]
  
      pert_imgs = []
      for mask, background_idx in zip(segments_mask, backgrounds):
          temp = copy.deepcopy(image)
          to_perturb = np.where(mask == 0)[0]
          # create mask for each superpixel not present in the sample
          mask = np.zeros(segments.shape).astype(bool)
          for superpixel in to_perturb:
              mask[segments == superpixel] = True
          if background_idx is not None:
              # replace values with those of background image
              temp[mask] = self.images_background[background_idx][mask]  # type: ignore[index]
          else:
              # ... or with the averaged superpixel value
              temp[mask] = fudged_image[mask]
          pert_imgs.append(temp)
  
      return np.array(pert_imgs), segments_mask
  
imports: import copy
  import logging
  from functools import partial
  from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union
  import numpy
  from skimage.segmentation import felzenszwalb, quickshift, slic
  from alibi.api.defaults import DEFAULT_DATA_ANCHOR_IMG, DEFAULT_META_ANCHOR
  from alibi.api.interfaces import Explainer, Explanation
  from alibi.exceptions import PredictorCallError, PredictorReturnTypeError
  from alibi.utils.wrappers import ArgmaxTransformer
  from .anchor_base import AnchorBaseBeam
  from .anchor_explanation import AnchorExplanation
label_desc: Use image node_id 5 for calling the AnchorImageSampler obj's underlying member method code with example usage: obj.perturbation(anchor, num_samples) and returns: np,  segments_mask