              requested
          area: ["mouth", "eyes"]
              The type of mask to obtain. `face` is a full face mask the others are masks for those
              specific areas
          aligned: bool, optional
              ``True`` if the returned mask should be for an aligned face. ``False`` if a full frame
              mask should be returned. Default ``True``
          centering: ["legacy", "face", "head"], optional
              Only used if `aligned`=``True``. The centering for the landmarks based mask. Should be
              the same as the centering used for the extracted face that this mask will be applied
              to. "legacy" places the nose in the center of the image (the original method for
              aligning). "face" aligns for the nose to be in the center of the face (top to bottom)
              but the center of the skull for left to right. "head" aligns for the center of the
              skull (in 3D space) being the center of the extracted image, with the crop holding the
              full head. Default: `"face"`
          dilation: int, optional
              The amount of dilation to apply to the mask. `0` for none. Default: `0`
          blur_kernel: int, optional
              The kernel size for applying gaussian blur to apply to the mask. `0` for none.
              Default: `0`
          as_zip: bool, optional
 
</s> remove         blur_kernel: int, optional
            The kernel size for applying gaussian blur to apply to the mask. `0` for none.
            Default: `0`
        as_zip: bool, optional
            ``True`` if the mask should be returned zipped otherwise ``False``
 </s> add  </s> remove         size: int or tuple
            The size of the aligned mask to retrieve. Should be an `int` if an aligned face is
            being requested, or a ('height', 'width') shape tuple if a full frame is being
            requested
        area: ["mouth", "eyes"]
 </s> add         area: ["face", "mouth", "eye"] </s> remove class _LandmarksMask():  # pylint:disable=too-few-public-methods
    """ Create a single channel mask from aligned landmark points.

    size: tuple
        The (height, width) shape tuple that the mask should be returned as
    points: list
        A list of landmark points that correspond to the given shape tuple to create
        the mask. Each item in the list should be a :class:`numpy.ndarray` that a filled
        convex polygon will be created from
    dilation: int, optional
        The amount of dilation to apply to the mask. `0` for none. Default: `0`
    blur_kernel: int, optional
        The kernel size for applying gaussian blur to apply to the mask. `0` for none. Default: `0`
    """
    def __init__(self, size, points, dilation=0, blur_kernel=0):
        logger.trace("Initializing: %s: (size: %s, points: %s, dilation: %s, blur_kernel: %s)",
                     self.__class__.__name__, size, points, dilation, blur_kernel)
        self._size = size
        self._points = points
        self._dilation = dilation
        self._blur_kernel = blur_kernel
        self._mask = None
        logger.trace("Initialized: %s", self.__class__.__name__)

    def get(self, as_zip=False):
        """ Obtain the mask.

        Parameters
        ----------
        as_zip: bool, optional
            ``True`` if the mask should be returned zipped otherwise ``False``

        Returns
        -------
        :class:`numpy.ndarray` or zipped array
            The mask as a single channel image of the given :attr:`size` dimension. If
            :attr:`as_zip` is ``True`` then the :class:`numpy.ndarray` will be contained within a
            zipped container
        """
        if not np.any(self._mask):
            self._generate_mask()
        retval = compress(self._mask) if as_zip else self._mask
        logger.trace("as_zip: %s, retval type: %s", as_zip, type(retval))
        return retval

    def _generate_mask(self):
        """ Generate the mask.

        Creates the mask applying any requested dilation and blurring and assigns to
        :attr:`_mask`

        Returns
        -------
        :class:`numpy.ndarray`
            The mask as a single channel image of the given :attr:`size` dimension.
        """
        mask = np.zeros((self._size) + (1, ), dtype="float32")
        for landmarks in self._points:
            lms = np.rint(landmarks).astype("int")
            cv2.fillConvexPoly(mask, cv2.convexHull(lms), 1.0, lineType=cv2.LINE_AA)
        if self._dilation != 0:
            mask = cv2.dilate(mask,
                              cv2.getStructuringElement(cv2.MORPH_ELLIPSE,
                                                        (self._dilation, self._dilation)),
                              iterations=1)
        if self._blur_kernel != 0:
            mask = BlurMask("gaussian", mask, self._blur_kernel).blurred
        logger.trace("mask: (shape: %s, dtype: %s)", mask.shape, mask.dtype)
        self._mask = (mask * 255.0).astype("uint8")


 </s> add  </s> remove         targets: list
            The targets for the model, with the mask as the final entry in the list
        masks: list
            The masks for the model
        additional_masks: list or ``None``
            Any additional masks for the model, or ``None`` if no additional masks are required
 </s> add         is_timelapse, bool, optional
            ``True`` if preview is to be generated for a Timelapse otherwise ``False``.
            Default: ``False`` </s> remove         images: list
            A list of image paths that will be used to compile the final augmented data from.
        batchsize: int
            The batchsize for this iterator. Images will be returned in :class:`numpy.ndarray`
            objects of this size from the iterator.
        side: {'a' or 'b'}
            The side of the model that this iterator is for.
        do_shuffle: bool, optional
            Whether data should be shuffled prior to loading from disk. If true, each time the full
            list of filenames are processed, the data will be reshuffled to make sure they are not
            returned in the same order. Default: ``True``
        is_preview: bool, optional
            Indicates whether this iterator is generating preview images. If ``True`` then certain
            augmentations will not be performed. Default: ``False``
        is_timelapse: bool optional
            Indicates whether this iterator is generating time-lapse images. If ``True``, then
            certain augmentations will not be performed. Default: ``False``
 </s> add         batch: :class:`numpy.ndarray`
            This should be a 4-dimensional array of training images in the format (`batch size`,
            `height`, `width`, `channels`). Targets should be requested after performing image
            transformations but prior to performing warps. The 4th channel should be the mask.
            Any channels above the 4th should be any additional area masks (e.g. eye/mouth) that
            are required.
        blur_kernel: int
            The size of the kernel for blurring the mask edges
        dilation: int
              requested
          area: ["mouth", "eyes"]
              The type of mask to obtain. `face` is a full face mask the others are masks for those
              specific areas
        blur_kernel: int
            The size of the kernel for blurring the mask edges
        dilation: int
        blur_kernel: int
            The size of the kernel for blurring the mask edges
        dilation: int
        blur_kernel: int
            The size of the kernel for blurring the mask edges
        dilation: int
        blur_kernel: int
            The size of the kernel for blurring the mask edges
        dilation: int
        blur_kernel: int
            The size of the kernel for blurring the mask edges
        dilation: int
        blur_kernel: int
            The size of the kernel for blurring the mask edges
        dilation: int
        blur_kernel: int
            The size of the kernel for blurring the mask edges
        dilation: int
        blur_kernel: int
            The size of the kernel for blurring the mask edges
        dilation: int
        blur_kernel: int
            The size of the kernel for blurring the mask edges
        dilation: int
        blur_kernel: int
            The size of the kernel for blurring the mask edges
        dilation: int
        blur_kernel: int
            The size of the kernel for blurring the mask edges
        dilation: int
        blur_kernel: int
            The size of the kernel for blurring the mask edges
        dilation: int
              The amount of dilation to apply to the mask. `0` for none. Default: `0`
          blur_kernel: int, optional
              The kernel size for applying gaussian blur to apply to the mask. `0` for none.
              Default: `0`
          as_zip: bool, optional
keep keep keep keep replace replace replace replace replace 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/align/detected_face.py