          preds = self.get_predictions(feeds["a"], feeds["b"])
  
          for side, samples in self.images.items():
              other_side = "a" if side == "b" else "b"
              predictions = [preds["{}_{}".format(side, side)],
                             preds["{}_{}".format(other_side, side)]]
              display = self.to_full_frame(side, samples, predictions)
              headers[side] = self.get_headers(side, other_side, display[0].shape[1])
              figures[side] = np.stack([display[0], display[1], display[2], ], axis=1)
              if self.images[side][0].shape[0] % 2 == 1:
 
</s> remove             headers[side] = self.get_headers(side, other_side, display[0].shape[1])
 </s> add             headers[side] = self.get_headers(side, display[0].shape[1]) </s> remove         logger.debug("side: '%s', other_side: '%s', width: %s",
                     side, other_side, width)
 </s> add         logger.debug("side: '%s', width: %s",
                     side, width)
        titles = ("Original", "Swap") if side == "a" else ("Swap", "Original") </s> remove         return src_points

    def get_closest_match(self, filename, side, src_points):
        """ Return closest matched landmarks from opposite set """
        logger.trace("Retrieving closest matched landmarks: (filename: '%s', src_points: '%s'",
                     filename, src_points)
        landmarks = self.landmarks["a"] if side == "b" else self.landmarks["b"]
        closest_hashes = self._nearest_landmarks.get(filename)
        if not closest_hashes:
            dst_points_items = list(landmarks.items())
            dst_points = list(x[1] for x in dst_points_items)
 </s> add         return np.array(src_points)

    def _get_closest_match(self, filenames, side, batch_src_points):
        """ Only called if the config item ``warp_to_landmarks`` is ``True``. Gets the closest
        matched 68 point landmarks from the opposite training set. """
        logger.trace("Retrieving closest matched landmarks: (filenames: '%s', src_points: '%s'",
                     filenames, batch_src_points)
        landmarks = self._landmarks["a"] if side == "b" else self._landmarks["b"]
        closest_hashes = [self._nearest_landmarks.get(filename) for filename in filenames]
        if None in closest_hashes:
            closest_hashes = self._cache_closest_hashes(filenames, batch_src_points, landmarks)

        batch_dst_points = np.array([landmarks[choice(hsh)] for hsh in closest_hashes])
        logger.trace("Returning: (batch_dst_points: %s)", batch_dst_points.shape)
        return batch_dst_points

    def _cache_closest_hashes(self, filenames, batch_src_points, landmarks):
        """ Cache the nearest landmarks for this batch """
        logger.trace("Caching closest hashes")
        dst_landmarks = list(landmarks.items())
        dst_points = np.array([lm[1] for lm in dst_landmarks])
        batch_closest_hashes = list()

        for filename, src_points in zip(filenames, batch_src_points): </s> remove     def get_headers(self, side, other_side, width):
 </s> add     def get_headers(self, side, width): </s> remove         other_side = other_side.upper()
 </s> add 
            predictions = [preds["{0}_{0}".format(side)],
          preds = self.get_predictions(feeds["a"], feeds["b"])
  
          for side, samples in self.images.items():
              other_side = "a" if side == "b" else "b"
            predictions = [preds["{0}_{0}".format(side)],
                             preds["{}_{}".format(other_side, side)]]
              display = self.to_full_frame(side, samples, predictions)
              headers[side] = self.get_headers(side, other_side, display[0].shape[1])
              figures[side] = np.stack([display[0], display[1], display[2], ], axis=1)
              if self.images[side][0].shape[0] % 2 == 1:
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 
plugins/train/trainer/_base.py