              A ``dict`` for each frame containing the ``image``, ``filename`` and list of
              :class:`lib.faces_detect.DetectedFace` objects.
  
          """
          if self.blur_kernel is not None:
              predicted = np.array([cv2.GaussianBlur(mask, (self.blur_kernel, self.blur_kernel), 0)
                                    for mask in batch["prediction"]])
          else:
              predicted = batch["prediction"]
          predicted[predicted < 0.04] = 0.0
          predicted[predicted > 0.96] = 1.0
          # TODO Convert this and landmarks_xy to numpy arrays once serialization
          # decision is made, Hacky temp fix as can't serialize numpy arrays in json
          # and tolist is hugely slow and gobbles ram
          for mask, face in zip(batch["prediction"], batch["detected_faces"]):
              placeholder = np.zeros(face.image.shape[:2] + (1, ), dtype="float32")
              placeholder = (cv2.warpAffine(
                  mask,
                  face.feed_matrix,
 
</s> remove             placeholder = np.zeros(face.image.shape[:2] + (1, ), dtype="float32")
            placeholder = (cv2.warpAffine(
                mask,
                face.feed_matrix,
                (face.image.shape[1], face.image.shape[0]),
                placeholder,
                flags=cv2.WARP_INVERSE_MAP | face.feed_interpolators[1],
                borderMode=cv2.BORDER_TRANSPARENT) * 255.0).astype("uint8")
            face.mask[self.name] = base64.b64encode(zlib.compress(placeholder)).decode()
 </s> add             face.add_mask(self.name,
                          mask,
                          face.feed_matrix,
                          (face.image.shape[1], face.image.shape[0]),
                          face.feed_interpolators[1])
            face.feed = None
 </s> remove         # Color Augmentation of the image only
 </s> add         # Color augmentation before mask is added </s> remove             batch[..., :3] = self._processing.color_adjust(batch[..., :3])
 </s> add             batch = self._processing.color_adjust(batch)

        # Add mask to batch prior to transforms and warps
        if self._mask_class:
            batch = np.array([self._mask_class(src_pts, image, channels=4).mask
                              for src_pts, image in zip(batch_src_pts, batch)]) </s> remove     if serializer.lower() == "json":
        return _JSONSerializer()
    if serializer.lower() == "pickle":
        return _PickleSerializer()
    if serializer.lower() == "yaml" and yaml is not None:
        return _YAMLSerializer()
    if serializer.lower() == "yaml" and yaml is None:
 </s> add     if serializer.lower() == "npy":
        retval = _NPYSerializer()
    elif serializer.lower() == "compressed":
        retval = _CompressedSerializer()
    elif serializer.lower() == "json":
        retval = _JSONSerializer()
    elif serializer.lower() == "pickle":
        retval = _PickleSerializer()
    elif serializer.lower() == "yaml" and yaml is not None:
        retval = _YAMLSerializer()
    elif serializer.lower() == "yaml" and yaml is None: </s> remove         return _JSONSerializer()
    if extension == ".p":
        return _PickleSerializer()
    if extension in (".yaml", ".yml") and yaml is not None:
        return _YAMLSerializer()
    if extension in (".yaml", ".yml") and yaml is None:
 </s> add         retval = _JSONSerializer()
    elif extension == ".p":
        retval = _PickleSerializer()
    elif extension == ".npy":
        retval = _NPYSerializer()
    elif extension == ".fsc":
        retval = _CompressedSerializer()
    elif extension in (".yaml", ".yml") and yaml is not None:
        retval = _YAMLSerializer()
    elif extension in (".yaml", ".yml") and yaml is None:
        # TODO Migrate these settings to retrieval rather than storage
        # if self.blur_kernel is not None:
        #    predicted = np.array([cv2.GaussianBlur(mask, (self.blur_kernel, self.blur_kernel), 0)
        #                          for mask in batch["prediction"]])
        # else:
        #    predicted = batch["prediction"]
        # predicted[predicted < 0.04] = 0.0
        # predicted[predicted > 0.96] = 1.0
        # TODO Convert landmarks_xy to numpy arrays
              A ``dict`` for each frame containing the ``image``, ``filename`` and list of
              :class:`lib.faces_detect.DetectedFace` objects.
  
          """
        # TODO Migrate these settings to retrieval rather than storage
        # if self.blur_kernel is not None:
        #    predicted = np.array([cv2.GaussianBlur(mask, (self.blur_kernel, self.blur_kernel), 0)
        #                          for mask in batch["prediction"]])
        # else:
        #    predicted = batch["prediction"]
        # predicted[predicted < 0.04] = 0.0
        # predicted[predicted > 0.96] = 1.0
        # TODO Convert landmarks_xy to numpy arrays
        # TODO Migrate these settings to retrieval rather than storage
        # if self.blur_kernel is not None:
        #    predicted = np.array([cv2.GaussianBlur(mask, (self.blur_kernel, self.blur_kernel), 0)
        #                          for mask in batch["prediction"]])
        # else:
        #    predicted = batch["prediction"]
        # predicted[predicted < 0.04] = 0.0
        # predicted[predicted > 0.96] = 1.0
        # TODO Convert landmarks_xy to numpy arrays
        # TODO Migrate these settings to retrieval rather than storage
        # if self.blur_kernel is not None:
        #    predicted = np.array([cv2.GaussianBlur(mask, (self.blur_kernel, self.blur_kernel), 0)
        #                          for mask in batch["prediction"]])
        # else:
        #    predicted = batch["prediction"]
        # predicted[predicted < 0.04] = 0.0
        # predicted[predicted > 0.96] = 1.0
        # TODO Convert landmarks_xy to numpy arrays
        # TODO Migrate these settings to retrieval rather than storage
        # if self.blur_kernel is not None:
        #    predicted = np.array([cv2.GaussianBlur(mask, (self.blur_kernel, self.blur_kernel), 0)
        #                          for mask in batch["prediction"]])
        # else:
        #    predicted = batch["prediction"]
        # predicted[predicted < 0.04] = 0.0
        # predicted[predicted > 0.96] = 1.0
        # TODO Convert landmarks_xy to numpy arrays
        # TODO Migrate these settings to retrieval rather than storage
        # if self.blur_kernel is not None:
        #    predicted = np.array([cv2.GaussianBlur(mask, (self.blur_kernel, self.blur_kernel), 0)
        #                          for mask in batch["prediction"]])
        # else:
        #    predicted = batch["prediction"]
        # predicted[predicted < 0.04] = 0.0
        # predicted[predicted > 0.96] = 1.0
        # TODO Convert landmarks_xy to numpy arrays
        # TODO Migrate these settings to retrieval rather than storage
        # if self.blur_kernel is not None:
        #    predicted = np.array([cv2.GaussianBlur(mask, (self.blur_kernel, self.blur_kernel), 0)
        #                          for mask in batch["prediction"]])
        # else:
        #    predicted = batch["prediction"]
        # predicted[predicted < 0.04] = 0.0
        # predicted[predicted > 0.96] = 1.0
        # TODO Convert landmarks_xy to numpy arrays
        # TODO Migrate these settings to retrieval rather than storage
        # if self.blur_kernel is not None:
        #    predicted = np.array([cv2.GaussianBlur(mask, (self.blur_kernel, self.blur_kernel), 0)
        #                          for mask in batch["prediction"]])
        # else:
        #    predicted = batch["prediction"]
        # predicted[predicted < 0.04] = 0.0
        # predicted[predicted > 0.96] = 1.0
        # TODO Convert landmarks_xy to numpy arrays
        # TODO Migrate these settings to retrieval rather than storage
        # if self.blur_kernel is not None:
        #    predicted = np.array([cv2.GaussianBlur(mask, (self.blur_kernel, self.blur_kernel), 0)
        #                          for mask in batch["prediction"]])
        # else:
        #    predicted = batch["prediction"]
        # predicted[predicted < 0.04] = 0.0
        # predicted[predicted > 0.96] = 1.0
        # TODO Convert landmarks_xy to numpy arrays
        # TODO Migrate these settings to retrieval rather than storage
        # if self.blur_kernel is not None:
        #    predicted = np.array([cv2.GaussianBlur(mask, (self.blur_kernel, self.blur_kernel), 0)
        #                          for mask in batch["prediction"]])
        # else:
        #    predicted = batch["prediction"]
        # predicted[predicted < 0.04] = 0.0
        # predicted[predicted > 0.96] = 1.0
        # TODO Convert landmarks_xy to numpy arrays
        # TODO Migrate these settings to retrieval rather than storage
        # if self.blur_kernel is not None:
        #    predicted = np.array([cv2.GaussianBlur(mask, (self.blur_kernel, self.blur_kernel), 0)
        #                          for mask in batch["prediction"]])
        # else:
        #    predicted = batch["prediction"]
        # predicted[predicted < 0.04] = 0.0
        # predicted[predicted > 0.96] = 1.0
        # TODO Convert landmarks_xy to numpy arrays
          for mask, face in zip(batch["prediction"], batch["detected_faces"]):
              placeholder = np.zeros(face.image.shape[:2] + (1, ), dtype="float32")
              placeholder = (cv2.warpAffine(
                  mask,
                  face.feed_matrix,
keep keep keep keep replace replace replace replace replace replace replace replace replace replace keep keep keep keep keep
 Serialize masks to alignments file

- Add new serializers (npy + compressed)
- Remove Serializer option from cli
- Revert get_aligned call in scripts/extract
- Default alignments to compressed
- Size masks to 128px and compress
- Remove mask thresholding/blur from generation code
- Add Mask class to lib/faces_detect
- Revert debug landmarks to aligned face
- Revert non-extraction code to staging version 
plugins/extract/mask/_base.py