          self._verify_output = False
          logger.debug("Initialized %s", self.__class__.__name__)
  
      @property
      def _save_interval(self) -> Optional[int]:
          """ int: The number of frames to be processed between each saving of the alignments file if
          it has been provided, otherwise ``None`` """
          if hasattr(self._args, "save_interval"):
              return self._args.save_interval
          return None
  
      @property
      def _skip_num(self) -> int:
          """ int: Number of frames to skip if extract_every_n has been provided """
          return self._args.extract_every_n if hasattr(self._args, "extract_every_n") else 1
 
</s> remove     def _skip_num(self) -> int:
        """ int: Number of frames to skip if extract_every_n has been provided """
        return self._args.extract_every_n if hasattr(self._args, "extract_every_n") else 1
 </s> add     def embeddings(self) -> np.ndarray:
        """ :class:`numpy.ndarray`: The filter embeddings"""
        if self._embeddings and all(np.any(e) for e in self._embeddings):
            retval = np.concatenate(self._embeddings, axis=0)
        else:
            retval = np.array([])
        return retval </s> remove     def _set_skip_list(self) -> None:
        """ Add the skip list to the image loader
 </s> add     @property
    def n_embeddings(self) -> np.ndarray:
        """ :class:`numpy.ndarray`: The n-filter embeddings"""
        if self._nembeddings and all(np.any(e) for e in self._nembeddings):
            retval = np.concatenate(self._nembeddings, axis=0)
        else:
            retval = np.array([])
        return retval </s> remove         self._existing_count = 0
        self._set_skip_list()

        self._post_process = PostProcess(arguments)
        self._threads: List[MultiThread] = []
        self._verify_output = False
 </s> add         self._get_embeddings()
        self._extractor.recognition.add_identity_filters(self.embeddings,
                                                         self.n_embeddings,
                                                         self._threshold) </s> remove     def frame_metadata(self) -> dict:
 </s> add     def is_aligned(self) -> bool:
        """ bool. ``True`` if :attr:`image` is an aligned faceswap image otherwise ``False`` """
        return self._is_aligned

    @property
    def frame_metadata(self) -> "PNGHeaderSourceDict": </s> remove         # from lib.queue_manager import queue_manager ; queue_manager.debug_monitor(3)
 </s> add         logger.info("Extracting faces to obtain identity from images")
        logger.debug("Files requiring full extraction: %s",
                     [fname for fname in file_list if fname not in aligned])
        logger.debug("Aligned files requiring identity info: %s", aligned)

        loader = PipelineLoader(file_list, self._extractor, aligned_filenames=aligned)
        loader.launch()

        for phase in range(self._extractor.passes):
            is_final = self._extractor.final_pass
            detected_faces: Dict[str, ExtractMedia] = {}
            self._extractor.launch()
            desc = "Obtaining reference face Identity"
            if self._extractor.passes > 1:
                desc = (f"{desc } pass {phase + 1} of {self._extractor.passes}: "
                        f"{self._extractor.phase_text}")
            for extract_media in tqdm(self._extractor.detected_faces(),
                                      total=len(file_list),
                                      file=sys.stdout,
                                      desc=desc):
                if is_final:
                    self._process_extracted(extract_media)
                else:
                    extract_media.remove_image()
                    # cache extract_media for next run
                    detected_faces[extract_media.filename] = extract_media

            if not is_final:
                logger.debug("Reloading images")
                loader.reload(detected_faces)

        self._extractor.reset_phase_index()

    def _get_embeddings(self) -> None:
        """ Obtain the embeddings for the given filter lists """
        needs_extraction: List[str] = []
        aligned: List[str] = []

        for files, embed in zip((self._filter_files, self._nfilter_files),
                                (self._embeddings, self._nembeddings)):
            for idx, file in enumerate(files):
                identity, is_aligned = self._identity_from_extracted(file)
                if np.any(identity):
                    logger.debug("Obtained identity from png header: '%s'", file)
                    embed[idx] = identity[None, ...]
                    continue

                needs_extraction.append(file)
                if is_aligned:
                    aligned.append(file)

        if needs_extraction:
            self._identity_from_extractor(needs_extraction, aligned)

        if not self._nfilter_files and not self._filter_files:
            logger.error("No faces were detected from your selected identity filter files")
            sys.exit(1)

        logger.debug("Filter: (filenames: %s, shape: %s), nFilter: (filenames: %s, shape: %s)",
                     [os.path.basename(f) for f in self._filter_files],
                     self.embeddings.shape,
                     [os.path.basename(f) for f in self._nfilter_files],
                     self.n_embeddings.shape)


class PipelineLoader():
    """ Handles loading and reloading images into the extraction pipeline.

    Parameters
    ----------
    path: str or list of str
        Full path to a folder of images or a video file or a list of image files
    extractor: :class:`~plugins.extract.pipeline.Extractor`
        The extractor pipeline for obtaining face identity from images
    aligned_filenames: list, optional
        Used for when the loader is used for getting face filter embeddings. List of full path to
        image files that exist in :attr:`path` that are aligned faceswap images
    """
    def __init__(self,
                 path: Union[str, List[str]],
                 extractor: Extractor,
                 aligned_filenames: Optional[List[str]] = None) -> None:
        logger.debug("Initializing %s: (path: %s, extractor: %s, aligned_filenames: %s)",
                     self.__class__.__name__, path, extractor, aligned_filenames)
        self._images = ImagesLoader(path, fast_count=True)
        self._extractor = extractor
        self._threads: List[MultiThread] = []
        self._aligned_filenames = [] if aligned_filenames is None else aligned_filenames
        logger.debug("Initialized %s", self.__class__.__name__)

    @property
    def is_video(self) -> bool:
        """ bool: ``True`` if the input location is a video file, ``False`` if it is a folder of
        images """
        return self._images.is_video

    @property
    def file_list(self) -> List[str]:
        """ list: A full list of files in the source location. If the input is a video
        then this is a list of dummy filenames as corresponding to an alignments file """
        return self._images.file_list

    @property
    def process_count(self) -> int:
        """ int: The number of images or video frames to be processed (IE the total count less
        items that are to be skipped from the :attr:`skip_list`)"""
        return self._images.process_count

    def add_skip_list(self, skip_list: List[int]) -> None:
        """ Add a skip list to the :class:`ImagesLoader`

        Parameters
        ----------
        skip_list: list
            A list of indices corresponding to the frame indices that should be skipped by the
            :func:`load` function.
        """
        self._images.add_skip_list(skip_list)

    def launch(self) -> None:
        """ Launch the image loading pipeline """
    def active(self):
        """ bool: ``True`` if filter files have been passed in command line arguments. ``False`` if
        no filter files have been provided """
        return bool(self._filter_files) or bool(self._nfilter_files)
          self._verify_output = False
          logger.debug("Initialized %s", self.__class__.__name__)
  
      @property
    def active(self):
        """ bool: ``True`` if filter files have been passed in command line arguments. ``False`` if
        no filter files have been provided """
        return bool(self._filter_files) or bool(self._nfilter_files)
    def active(self):
        """ bool: ``True`` if filter files have been passed in command line arguments. ``False`` if
        no filter files have been provided """
        return bool(self._filter_files) or bool(self._nfilter_files)
    def active(self):
        """ bool: ``True`` if filter files have been passed in command line arguments. ``False`` if
        no filter files have been provided """
        return bool(self._filter_files) or bool(self._nfilter_files)
    def active(self):
        """ bool: ``True`` if filter files have been passed in command line arguments. ``False`` if
        no filter files have been provided """
        return bool(self._filter_files) or bool(self._nfilter_files)
    def active(self):
        """ bool: ``True`` if filter files have been passed in command line arguments. ``False`` if
        no filter files have been provided """
        return bool(self._filter_files) or bool(self._nfilter_files)
    def active(self):
        """ bool: ``True`` if filter files have been passed in command line arguments. ``False`` if
        no filter files have been provided """
        return bool(self._filter_files) or bool(self._nfilter_files)
  
      @property
      def _skip_num(self) -> int:
          """ int: Number of frames to skip if extract_every_n has been provided """
          return self._args.extract_every_n if hasattr(self._args, "extract_every_n") else 1
keep keep keep keep replace replace replace replace replace replace keep keep keep keep keep
 Update Face Filter
  - Remove old face filter
  - plugins.extract.pipeline: Expose plugins directly
  - Change `is_aligned` from plugin level to ExtractMedia level
  - Allow extract pipeline to take faceswap aligned images
  - Add ability for recognition plugins to accept aligned faces as input
  - Add face filter to recognition plugin
  - Move extractor pipeline IO ops to own class 
scripts/extract.py