code: def compute_mean(
      data, channels, per_channel_subtraction=True
  ) -> Union[Tuple, None]:
      """
      Computes mean per channel over the train set and returns a tuple of dimensions=channels
      Train should not be normalized
      """
      if len(data) == 0:
          raise ValueError("Dataset is empty")
  
      if not isinstance(data, (list, Tensor)):
          raise ValueError(
              "Dataset must be a list of size=number of images and shape=image shape"
          )
  
      if channels == 3:
          rMean, gMean, bMean = 0.0, 0.0, 0.0
      if channels == 1:
          bgrMean: float = 0.0
  
      count: int = 0
  
      for tens in data:
          count += 1
          if channels == 3:
              b, g, r = cv.mean(tens.astype("float32"))[:3]
              rMean += r
              gMean += g
              bMean += b
          if channels == 1:
              bgrMean += np.mean(tens.astype("float32"))
  
      # Computing average mean
      if channels == 3:
          rMean /= count
          bMean /= count
          gMean /= count
          if per_channel_subtraction:
              return rMean, bMean, gMean
          else:
              mean_of_means = (rMean + bMean + gMean) / 3
              return mean_of_means, mean_of_means, mean_of_means
  
      if channels == 1:
          bgrMean /= count
          return tuple([bgrMean])
  
      return None
  
file_path: caer/caer/preprocessing/mean_subtraction.py
imports: from .._internal import _check_mean_sub_values
  from ..path import exists, list_images
  from ..io import imread
  from ..coreten import Tensor
  from ..annotations import Tuple, List, Union
  import numpy
  import cv2
label_desc: Use image node_id 2 for calling a global function with example usage: compute_mean(data, channels, per_channel_subtraction) and returns: None, tuple, rMean,  bMean,  gMean, mean_of_means,  mean_of_means,  mean_of_means