  
          logger.info("Sorting by face similarity...")
  
          images = np.array(self.find_images(input_dir))
          preds = np.array([self.vgg_face.predict(cv2_read_img(img, raise_error=True))
                            for img in tqdm(images, desc="loading", file=sys.stdout)])
          logger.info("Sorting. Depending on ths size of your dataset, this may take a few "
                      "minutes...")
          indices = self.vgg_face.sorted_similarity(preds, method="ward")
          img_list = images[indices]
 
</s> remove             [img, cv2.calcHist([cv2_read_img(img, raise_error=True)], [0], None, [256], [0, 256])]
 </s> add             [img, cv2.calcHist([read_image(img, raise_error=True)], [0], None, [256], [0, 256])] </s> remove     def get_landmarks(self, filename, image, side):
        """ Return the landmarks for this face """
        logger.trace("Retrieving landmarks: (filename: '%s', side: '%s'", filename, side)
        lm_key = sha1(image).hexdigest()
        try:
            src_points = self.landmarks[side][lm_key]
        except KeyError as err:
            msg = ("At least one of your images does not have a matching entry in your alignments "
                   "file."
 </s> add     def _get_landmarks(self, filenames, batch, side):
        """ Obtains the 68 Point Landmarks for the images in this batch. This is only called if
        config item ``warp_to_landmarks`` is ``True`` or if :attr:`mask_type` is not ``None``. If
        the landmarks for an image cannot be found, then an error is raised. """
        logger.trace("Retrieving landmarks: (filenames: '%s', side: '%s'", filenames, side)
        src_points = [self._landmarks[side].get(sha1(face).hexdigest(), None) for face in batch]

        # Raise error on missing alignments
        if not all(isinstance(pts, np.ndarray) for pts in src_points):
            indices = [idx for idx, hsh in enumerate(src_points) if hsh is None]
            missing = [filenames[idx] for idx in indices]
            msg = ("Files missing alignments for this batch: {}"
                   "\nAt least one of your images does not have a matching entry in your "
                   "alignments file." </s> remove              cv2.calcHist([cv2_read_img(img, raise_error=True)], [0], None, [256], [0, 256]), 0]
 </s> add              cv2.calcHist([read_image(img, raise_error=True)], [0], None, [256], [0, 256]), 0] </s> remove                "batch-size: {}".format(length, self.batchsize))
 </s> add                "batch-size: {}".format(length, self._batchsize)) </s> remove     def random_warp(self, image):
        """ get pair of random warped images from aligned face image """
        logger.trace("Randomly warping image")
        height, width = image.shape[0:2]
        coverage = self.get_coverage(image) // 2
        try:
            assert height == width and height % 2 == 0
        except AssertionError as err:
            msg = ("Training images should be square with an even number of pixels across each "
                   "side. An image was found with width: {}, height: {}."
                   "\nMost likely this is a frame rather than a face within your training set. "
                   "\nMake sure that the only images within your training set are faces generated "
                   "from the Extract process.".format(width, height))
            raise FaceswapError(msg) from err

        range_ = np.linspace(height // 2 - coverage, height // 2 + coverage, 5, dtype='float32')
        mapx = np.broadcast_to(range_, (5, 5)).copy()
        mapy = mapx.T
        # mapx, mapy = np.float32(np.meshgrid(range_,range_)) # instead of broadcast

        pad = int(1.25 * self.input_size)
        slices = slice(pad // 10, -pad // 10)
        dst_slices = [slice(0, (size + 1), (size // 4)) for size in self.output_sizes]
        interp = np.empty((2, self.input_size, self.input_size), dtype='float32')
 </s> add     # <<< COLOR AUGMENTATION >>> #
    def color_adjust(self, batch):
        """ Perform color augmentation on the passed in batch.
        preds = np.array([self.vgg_face.predict(read_image(img, raise_error=True))
  
          logger.info("Sorting by face similarity...")
  
          images = np.array(self.find_images(input_dir))
        preds = np.array([self.vgg_face.predict(read_image(img, raise_error=True))
                            for img in tqdm(images, desc="loading", file=sys.stdout)])
          logger.info("Sorting. Depending on ths size of your dataset, this may take a few "
                      "minutes...")
          indices = self.vgg_face.sorted_similarity(preds, method="ward")
          img_list = images[indices]
keep keep keep keep replace keep keep keep keep keep
 Optimize Data Augmentation (#881)

* Move image utils to lib.image
* Add .pylintrc file
* Remove some cv2 pylint ignores
* TrainingData: Load images from disk in batches
* TrainingData: get_landmarks to batch
* TrainingData: transform and flip to batches
* TrainingData: Optimize color augmentation
* TrainingData: Optimize target and random_warp
* TrainingData - Convert _get_closest_match for batching
* TrainingData: Warp To Landmarks optimized
* Save models to threadpoolexecutor
* Move stack_images, Rename ImageManipulation. ImageAugmentation Docstrings
* Masks: Set dtype and threshold for lib.masks based on input face
* Docstrings and Documentation 
tools/sort.py