class_docstr: Class that handles the logic of composing the visualizations.
  
  Args:
      mode (VisualizationMode): visualization mode, either "full" or "simple"
      task (TaskType): task type "segmentation", "detection" or "classification"
docstr: Generator that yields a visualization result for each item in the batch.
  
  Args:
      batch (dict): Dictionary containing the ground truth and predictions of a batch of images.
  
  Returns:
      Generator that yields a display-ready visualization for each image.
docstr_tok: ["Generator","that","yields","a","visualization","result","for","each","item","in","the","batch",".","Args",":","batch","(","dict",")",":","Dictionary","containing","the","ground","truth","and","predictions","of","a","batch","of","images",".","Returns",":","Generator","that","yields","a","display-ready","visualization","for","each","image","."]
code: def visualize_batch(self, batch: dict) -> Iterator[np.ndarray]:
      """Generator that yields a visualization result for each item in the batch.
  
      Args:
          batch (dict): Dictionary containing the ground truth and predictions of a batch of images.
  
      Returns:
          Generator that yields a display-ready visualization for each image.
      """
      batch_size = batch["image"].shape[0]
      for i in range(batch_size):
          if "image_path" in batch:
              height, width = batch["image"].shape[-2:]
              image = read_image(
                  path=batch["image_path"][i],
                  image_size=(height, width),
              )
          elif "video_path" in batch:
              height, width = batch["original_image"].shape[1:3]
              image = batch["original_image"][i].squeeze().numpy()
              image = cv2.resize(
                  image,
                  dsize=(width, height),
                  interpolation=cv2.INTER_AREA,
              )
          else:
              raise KeyError(
                  "Batch must have either 'image_path' or 'video_path' defined."
              )
  
          image_result = ImageResult(
              image=image,
              pred_score=batch["pred_scores"][i].cpu().numpy().item(),
              pred_label=batch["pred_labels"][i].cpu().numpy().item(),
              anomaly_map=batch["anomaly_maps"][i].cpu().numpy()
              if "anomaly_maps" in batch
              else None,
              pred_mask=batch["pred_masks"][i]
              .squeeze()
              .int()
              .cpu()
              .numpy()
              if "pred_masks" in batch
              else None,
              gt_mask=batch["mask"][i].squeeze().int().cpu().numpy()
              if "mask" in batch
              else None,
              gt_boxes=batch["boxes"][i].cpu().numpy()
              if "boxes" in batch
              else None,
              pred_boxes=batch["pred_boxes"][i].cpu().numpy()
              if "pred_boxes" in batch
              else None,
              box_labels=batch["box_labels"][i].cpu().numpy()
              if "box_labels" in batch
              else None,
          )
          yield self.visualize_image(image_result)
  
imports: from __future__ import annotations
  from dataclasses import dataclass, field
  from enum import Enum
  from pathlib import Path
  from typing import Iterator
  import cv2
  import matplotlib.figure
  import matplotlib.pyplot
  import numpy
  from skimage.segmentation import mark_boundaries
  from anomalib.data import TaskType
  from anomalib.data.utils import read_image
  from anomalib.post_processing.post_process import add_anomalous_label, add_normal_label, draw_boxes, superimpose_anomaly_map
label_desc: Use image node_id 2 for calling the Visualizer obj's underlying member method code with example usage: obj.visualize_batch(batch) without return types