code: def fancy_pca(img, alpha=0.1):
      """Perform 'Fancy PCA' augmentation from:
      http://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf
  
      Args:
          img (numpy.ndarray): numpy array with (h, w, rgb) shape, as ints between 0-255
          alpha (float): how much to perturb/scale the eigen vecs and vals
                  the paper used std=0.1
  
      Returns:
          numpy.ndarray: numpy image-like array as uint8 range(0, 255)
  
      """
      if not is_rgb_image(img) or img.dtype != np.uint8:
          raise TypeError("Image must be RGB image in uint8 format.")
  
      orig_img = img.astype(float).copy()
  
      img = img / 255.0  # rescale to 0 to 1 range
  
      # flatten image to columns of RGB
      img_rs = img.reshape(-1, 3)
      # img_rs shape (640000, 3)
  
      # center mean
      img_centered = img_rs - np.mean(img_rs, axis=0)
  
      # paper says 3x3 covariance matrix
      img_cov = np.cov(img_centered, rowvar=False)
  
      # eigen values and eigen vectors
      eig_vals, eig_vecs = np.linalg.eigh(img_cov)
  
      # sort values and vector
      sort_perm = eig_vals[::-1].argsort()
      eig_vals[::-1].sort()
      eig_vecs = eig_vecs[:, sort_perm]
  
      # get [p1, p2, p3]
      m1 = np.column_stack((eig_vecs))
  
      # get 3x1 matrix of eigen values multiplied by random variable draw from normal
      # distribution with mean of 0 and standard deviation of 0.1
      m2 = np.zeros((3, 1))
      # according to the paper alpha should only be draw once per augmentation (not once per channel)
      # alpha = np.random.normal(0, alpha_std)
  
      # broad cast to speed things up
      m2[:, 0] = alpha * eig_vals[:]
  
      # this is the vector that we're going to add to each pixel in a moment
      add_vect = np.matrix(m1) * np.matrix(m2)
  
      for idx in range(3):  # RGB
          orig_img[..., idx] += add_vect[idx] * 255
  
      # for image processing it was found that working with float 0.0 to 1.0
      # was easier than integers between 0-255
      # orig_img /= 255.0
      orig_img = np.clip(orig_img, 0.0, 255.0)
  
      # orig_img *= 255
      orig_img = orig_img.astype(np.uint8)
  
      return orig_img
  
imports: from __future__ import division
  from typing import Optional, Sequence, Union
  from warnings import warn
  import cv2
  import numpy
  import skimage
  from albumentations import random_utils
  from albumentations.augmentations.utils import MAX_VALUES_BY_DTYPE, _maybe_process_in_chunks, clip, clipped, ensure_contiguous, is_grayscale_image, is_rgb_image, non_rgb_warning, preserve_channel_dim, preserve_shape
label_desc: Use image node_id 48 for calling a global function with example usage: fancy_pca(img, alpha) and returns: orig_img