  
      def _random_lab(self, batch):
          """ Perform random color/lightness adjustment in L*a*b* color space on a batch of
          images """
          amount_l = self._config.get("color_lightness", 30) / 100
          amount_ab = self._config.get("color_ab", 8) / 100
          adjust = np.array([amount_l, amount_ab, amount_ab], dtype="float32")
          randoms = (
              (np.random.rand(self._batchsize, 1, 1, 3).astype("float32") * (adjust * 2)) - adjust)
          logger.trace("Random LAB adjustments: %s", randoms)
  
          for image, rand in zip(batch, randoms):
              for idx in range(rand.shape[-1]):
                  adjustment = rand[:, :, idx]
                  if adjustment >= 0:
                      image[:, :, idx] = ((255 - image[:, :, idx]) * adjustment) + image[:, :, idx]
 
</s> remove     def _random_lab(self, batch):
 </s> add     def _random_lab(self, batch: np.ndarray) -> None: </s> remove         return batch
 </s> add  </s> remove             batch[idx, :, :, 0] = clahe.apply(batch[idx, :, :, 0])
        return batch
 </s> add             batch[idx, :, :, 0] = clahe.apply(batch[idx, :, :, 0], ) </s> remove     def transform(self, batch):
 </s> add     def transform(self, batch: np.ndarray): </s> remove         clahe_base_contrast = training_size // 128
        # Target Images
        tgt_slices = slice(self._training_size // 2 - coverage // 2,
                           self._training_size // 2 + coverage // 2)
 </s> add         amount_l = int(self._config.get("color_lightness", 30)) / 100
        amount_ab = int(self._config.get("color_ab", 8)) / 100
        lab_adjust = np.array([amount_l, amount_ab, amount_ab], dtype="float32")
        randoms = np.random.uniform(-self._constants.lab_adjust,
                                    self._constants.lab_adjust,
                                    size=(self._batchsize, 1, 1, 3)).astype("float32")
        logger.trace("Random LAB adjustments: %s", randoms)  # type: ignore
        # Iterating through the images and channels is much faster than numpy.where and slightly
        # faster than numexpr.where.
  
      def _random_lab(self, batch):
          """ Perform random color/lightness adjustment in L*a*b* color space on a batch of
          images """
        randoms = np.random.uniform(-self._constants.lab_adjust,
                                    self._constants.lab_adjust,
                                    size=(self._batchsize, 1, 1, 3)).astype("float32")
        logger.trace("Random LAB adjustments: %s", randoms)  # type: ignore
        # Iterating through the images and channels is much faster than numpy.where and slightly
        # faster than numexpr.where.
        randoms = np.random.uniform(-self._constants.lab_adjust,
                                    self._constants.lab_adjust,
                                    size=(self._batchsize, 1, 1, 3)).astype("float32")
        logger.trace("Random LAB adjustments: %s", randoms)  # type: ignore
        # Iterating through the images and channels is much faster than numpy.where and slightly
        # faster than numexpr.where.
        randoms = np.random.uniform(-self._constants.lab_adjust,
                                    self._constants.lab_adjust,
                                    size=(self._batchsize, 1, 1, 3)).astype("float32")
        logger.trace("Random LAB adjustments: %s", randoms)  # type: ignore
        # Iterating through the images and channels is much faster than numpy.where and slightly
        # faster than numexpr.where.
        randoms = np.random.uniform(-self._constants.lab_adjust,
                                    self._constants.lab_adjust,
                                    size=(self._batchsize, 1, 1, 3)).astype("float32")
        logger.trace("Random LAB adjustments: %s", randoms)  # type: ignore
        # Iterating through the images and channels is much faster than numpy.where and slightly
        # faster than numexpr.where.
        randoms = np.random.uniform(-self._constants.lab_adjust,
                                    self._constants.lab_adjust,
                                    size=(self._batchsize, 1, 1, 3)).astype("float32")
        logger.trace("Random LAB adjustments: %s", randoms)  # type: ignore
        # Iterating through the images and channels is much faster than numpy.where and slightly
        # faster than numexpr.where.
        randoms = np.random.uniform(-self._constants.lab_adjust,
                                    self._constants.lab_adjust,
                                    size=(self._batchsize, 1, 1, 3)).astype("float32")
        logger.trace("Random LAB adjustments: %s", randoms)  # type: ignore
        # Iterating through the images and channels is much faster than numpy.where and slightly
        # faster than numexpr.where.
        randoms = np.random.uniform(-self._constants.lab_adjust,
                                    self._constants.lab_adjust,
                                    size=(self._batchsize, 1, 1, 3)).astype("float32")
        logger.trace("Random LAB adjustments: %s", randoms)  # type: ignore
        # Iterating through the images and channels is much faster than numpy.where and slightly
        # faster than numexpr.where.
          for image, rand in zip(batch, randoms):
              for idx in range(rand.shape[-1]):
                  adjustment = rand[:, :, idx]
                  if adjustment >= 0:
                      image[:, :, idx] = ((255 - image[:, :, idx]) * adjustment) + image[:, :, idx]
keep keep keep keep replace replace replace replace replace replace replace keep keep keep keep keep
 Data Augmentation update (#1263)

- lib.detected_face
    - Subclass Masks for Landmark based masks
    - Add training mask propery + methods to DetectedFace
  - lib.training_training
    - subclass TrainingDataGenerator for training and preview data
    - Split cache into own module
    - Reduce thread count to 1 to prevent image corruption + data re-use
    - Process on largest model input/output size rather than stored image size
    - Size and crop masks during caching stage
    - Implement ring buffer for data flow
    - Fix preview reload bug
  - augmentation
    - typing
    - switch color aug order
    - better initialization
    - Fix warp + landmark warp to correctly apply at different image scales
    - Slightly improved warp caching
    - Don't store whether image is_preview. Handle all data as training images implicitly
  - plugins.trainer: Typing and fixes to work with trainingdata refactor 
lib/training/augmentation.py