          """ Detect and move blurry face """
          if not hasattr(self.args, 'blur_thresh') or not self.args.blur_thresh:
              return None
  
          blurry_file = None
          aligned_landmarks = self.extractor.transform_points(
              face.landmarks_as_xy(),
              t_mat,
              256,
              48)
          feature_mask = self.extractor.get_feature_mask(aligned_landmarks / 256,
                                                         256,
                                                         48)
          feature_mask = cv2.blur(feature_mask, (10, 10))
          isolated_face = cv2.multiply(
              feature_mask,
              resized_image.astype(float)).astype(np.uint8)
          blurry, focus_measure = is_blurry(isolated_face, self.args.blur_thresh)
  
          if blurry:
              print("{}'s focus measure of {} was below the blur threshold, "
                    "moving to \"blurry\"".format(Path(filename).stem,
                                                  focus_measure))
              blurry_file = get_folder(Path(self.output_dir) /
                                       Path("blurry")) / Path(filename).stem
          return blurry_file
  
  
  class Alignments():
      """ Holds processes pertaining to the alignments file """
      def __init__(self, arguments):
 
</s> remove class Alignments():
    """ Holds processes pertaining to the alignments file """
 </s> add class PostProcess():
    """ Optional post processing tasks """ </s> remove     def detect_blurry_faces(self, face, t_mat, resized_image, filename):
        """ Detect and move blurry face """
        if not hasattr(self.args, 'blur_thresh') or not self.args.blur_thresh:
            return None
 </s> add         return input_images </s> remove         self.serializer = self.get_serializer()
        self.alignments_path = self.get_alignments_path()
        self.have_alignments_file = os.path.exists(self.alignments_path)
 </s> add         self.verbose = self.args.verbose
        self.actions = self.set_actions()

    def get_items(self):
        """ Set the post processing actions """
        postprocess_items = dict()
        # Debug Landmarks
        if (hasattr(self.args, 'debug_landmarks')
                and self.args.debug_landmarks):
            postprocess_items["DebugLandmarks"] = None

        # Blurry Face
        if hasattr(self.args, 'blur_thresh') and self.args.blur_thresh:
            kwargs = {"blur_thresh": self.args.blur_thresh}
            postprocess_items["BlurryFaceFilter"] = {"kwargs": kwargs}

        # Face Filter post processing
        if ((hasattr(self.args, "filter") and self.args.filter is not None) or
                (hasattr(self.args, "nfilter") and
                 self.args.nfilter is not None)):
            face_filter = dict()
            filter_lists = dict()
            if hasattr(self.args, "ref_threshold"):
                face_filter["ref_threshold"] = self.args.ref_threshold
            for filter_type in ('filter', 'nfilter'):
                filter_args = getattr(self.args, filter_type, None)
                filter_args = None if not filter_args else filter_args
                filter_lists[filter_type] = filter_args
            face_filter["filter_lists"] = filter_lists
            postprocess_items["FaceFilter"] = {"kwargs": face_filter}

        return postprocess_items

    def set_actions(self):
        """ Compile the actions to be performed into a list """
        postprocess_items = self.get_items()
        actions = list()
        for action, options in postprocess_items.items():
            options = dict() if options is None else options
            args = options.get("args", tuple())
            kwargs = options.get("kwargs", dict())
            args = args if isinstance(args, tuple) else tuple()
            kwargs = kwargs if isinstance(kwargs, dict) else dict()
            kwargs["verbose"] = self.verbose
            task = globals()[action](*args, **kwargs)
            actions.append(task)

        for action in actions:
            action_name = camel_case_split(action.__class__.__name__)
            print("Adding post processing item: "
                  "{}".format(" ".join(action_name)))

        return actions

    def do_actions(self, output_item):
        """ Perform the requested post-processing actions """
        for action in self.actions:
            action.process(output_item)


class PostProcessAction():
    """ Parent class for Post Processing Actions
        Usuable in Extract or Convert or both
        depending on context """
    def __init__(self, *args, **kwargs):
        self.verbose = kwargs["verbose"]

    def process(self, output_item):
        """ Override for specific post processing action """
        raise NotImplementedError


class BlurryFaceFilter(PostProcessAction):
    """ Move blurry faces to a different folder
        Extract Only """
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.blur_thresh = kwargs["blur_thresh"]

    def process(self, output_item):
        """ Detect and move blurry face """
        extractor = AlignerExtract()

        for idx, face in enumerate(output_item["detected_faces"]):
            resized_face = output_item["resized_faces"][idx]
            dims = resized_face.shape[:2]
            size = dims[0]
            t_mat = output_item["t_mats"][idx]

            aligned_landmarks = extractor.transform_points(
                face.landmarksXY,
                t_mat, size, 48)
            feature_mask = extractor.get_feature_mask(
                aligned_landmarks / size,
                size, 48)
            feature_mask = cv2.blur(feature_mask, (10, 10))
            isolated_face = cv2.multiply(
                feature_mask,
                resized_face.astype(float)).astype(np.uint8)
            blurry, focus_measure = is_blurry(isolated_face, self.blur_thresh)

            if blurry:
                blur_folder = output_item["output_file"].parts[:-1]
                blur_folder = get_folder(Path(*blur_folder) / Path("blurry"))
                frame_name = output_item["output_file"].parts[-1]
                output_item["output_file"] = blur_folder / Path(frame_name)
                if self.verbose:
                    print("{}'s focus measure of {} was below the blur "
                          "threshold, moving to \"blurry\"".format(
                              frame_name, focus_measure))


class DebugLandmarks(PostProcessAction):
    """ Draw debug landmarks on face
        Extract Only """

    def process(self, output_item):
        """ Draw landmarks on image """
        transform_points = AlignerExtract().transform_points
        for idx, face in enumerate(output_item["detected_faces"]):
            dims = output_item["resized_faces"][idx].shape[:2]
            size = dims[0]
            landmarks = transform_points(face.landmarksXY,
                                         output_item["t_mats"][idx],
                                         size,
                                         48)
            for (pos_x, pos_y) in landmarks:
                cv2.circle(output_item["resized_faces"][idx],
                           (pos_x, pos_y), 2, (0, 0, 255), -1)


class FaceFilter(PostProcessAction):
    """ Filter in or out faces based on input image(s)
        Extract or Convert """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        filter_lists = kwargs["filter_lists"]
        ref_threshold = kwargs.get("ref_threshold", 0.6)
        self.filter = self.load_face_filter(filter_lists, ref_threshold)

    def load_face_filter(self, filter_lists, ref_threshold):
        """ Load faces to filter out of images """
        if not any(val for val in filter_lists.values()):
            return None </s> remove         for (pos_x, pos_y) in face.landmarks_as_xy():
            cv2.circle(image, (pos_x, pos_y), 2, (0, 0, 255), -1)
 </s> add         print("Input Directory: {}".format(self.args.input_dir))
        input_images = get_image_paths(self.args.input_dir) </s> remove class Images():
    """ Holds the full frames/images """
    def __init__(self, arguments):
 </s> add class Alignments():
    """ Holds processes pertaining to the alignments file """
    def __init__(self, arguments, is_extract):
        self.is_extract = is_extract
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
          """ Detect and move blurry face """
          if not hasattr(self.args, 'blur_thresh') or not self.args.blur_thresh:
              return None
  
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
    def load(self):
        """ Load an image and yield it with it's filename """
        for filename in self.input_images:
            yield filename, cv2.imread(filename)
  
  
  class Alignments():
      """ Holds processes pertaining to the alignments file """
      def __init__(self, arguments):
keep keep keep keep replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace keep keep keep keep keep
 Extraction - Speed improvements (#522) (#523)

* Extraction - Speed improvements (#522)

* Initial Plugin restructure

* Detectors to plugins. Detector speed improvements

* Re-implement dlib aligner, remove models, FAN to TF. Parallel processing

* Update manual, update convert, implement parallel/serial switching

* linting + fix cuda check (setup.py). requirements update keras 2.2.4

* Add extract size option. Fix dlib hog init

* GUI: Increase tooltip width

* Update alignment tool to support new DetectedFace

* Add skip existing faces option

* Fix sort tool to new plugin structure

* remove old align plugin

* fix convert -skip faces bug

* Fix convert skipping no faces frames

* Convert - draw onto transparent layer

* Fix blur threshold bug

* fix skip_faces convert bug

* Fix training 
scripts/fsmedia.py