      """ Extended mask
          Based on components mask. Attempts to extend the eyebrow points up the forehead
      """
      def build_mask(self):
          mask = np.zeros(self.face.shape[0:2] + (1, ), dtype=np.float32)
  
          landmarks = self.landmarks.copy()
          # mid points between the side of face and eye point
          ml_pnt = (landmarks[36] + landmarks[0]) // 2
          mr_pnt = (landmarks[16] + landmarks[45]) // 2
 
</s> remove         mask = np.zeros(self.face.shape[0:2] + (1, ), dtype=np.float32)
        hull = cv2.convexHull(  # pylint: disable=no-member
 </s> add         mask = np.zeros(self.face.shape[0:2] + (1, ), dtype=self.dtype)
        hull = cv2.convexHull( </s> remove         mask = np.zeros(self.face.shape[0:2] + (1, ), dtype=np.float32)
 </s> add         mask = np.zeros(self.face.shape[0:2] + (1, ), dtype=self.dtype) </s> remove         mask = np.zeros(self.face.shape[0:2] + (1, ), dtype=np.float32)
 </s> add         mask = np.zeros(self.face.shape[0:2] + (1, ), dtype=self.dtype) </s> remove         cv2.fillConvexPoly(mask, hull, 255.0, lineType=cv2.LINE_AA)  # pylint: disable=no-member
 </s> add         cv2.fillConvexPoly(mask, hull, self.threshold, lineType=cv2.LINE_AA) </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.
        mask = np.zeros(self.face.shape[0:2] + (1, ), dtype=self.dtype)
      """ Extended mask
          Based on components mask. Attempts to extend the eyebrow points up the forehead
      """
      def build_mask(self):
        mask = np.zeros(self.face.shape[0:2] + (1, ), dtype=self.dtype)
  
          landmarks = self.landmarks.copy()
          # mid points between the side of face and eye point
          ml_pnt = (landmarks[36] + landmarks[0]) // 2
          mr_pnt = (landmarks[16] + landmarks[45]) // 2
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 
lib/model/masks.py