  
      def output_faces(self, filename, faces):
          """ Output faces to save thread """
          final_faces = list()
          for idx, detected_face in enumerate(faces["detected_faces"]):
              output_file = detected_face["file_location"]
              extension = Path(filename).suffix
              out_filename = "{}_{}{}".format(str(output_file), str(idx), extension)
  
              face = detected_face["face"]
              resized_face = face.aligned_face
              face.hash, img = encode_image_with_hash(resized_face, extension)
              self.save_queue.put((out_filename, img))
              final_faces.append(face.to_alignment())
          self.alignments.data[os.path.basename(filename)] = final_faces
 
</s> remove         self.alignments.data[os.path.basename(filename)] = final_faces
 </s> add         self._alignments.data[os.path.basename(faces["filename"])] = final_faces </s> remove     def align_face(self, faces, size, filename):
        """ Align the detected face and add the destination file path """
        final_faces = list()
        image = faces["image"]
        detected_faces = faces["detected_faces"]
        for face in detected_faces:
            face.load_aligned(image, size=size)
            final_faces.append({"file_location": self.output_dir / Path(filename).stem,
                                "face": face})
        faces["detected_faces"] = final_faces

    def output_faces(self, filename, faces):
        """ Output faces to save thread """
 </s> add     def _output_faces(self, saver, faces):
        """ Output faces to save thread

        Set the face filename based on the frame name and put the face to the
        :class:`lib.image.ImagesSaver` save queue and add the face information to the alignments
        data.

        Parameters
        ----------
        saver: lib.images.ImagesSaver
            The background saver for saving the image
        faces: dict
            The output dictionary from :class:`plugins.extract.Pipeline.Extractor`
        """
        logger.debug("Save Faces: Start") </s> remove         if not self.verify_output and faces_count > 1:
            self.verify_output = True
 </s> add         if not self._verify_output and faces_count > 1:
            self._verify_output = True </s> remove         load_queue = self.extractor.input_queue
        idx = 0
        for filename, image in self.images.load():
            idx += 1
 </s> add         load_queue = self._extractor.input_queue
        for filename, image in self._images.load(): </s> remove     def save_faces(self):
        """ Save the generated faces """
        logger.debug("Save Faces: Start")
        while True:
            if self.save_queue.shutdown.is_set():
                logger.debug("Save Queue: Stop signal received. Terminating")
                break
            item = self.save_queue.get()
            logger.trace(item)
            if item == "EOF":
                break
            filename, face = item

            logger.trace("Saving face: '%s'", filename)
            try:
                with open(filename, "wb") as out_file:
                    out_file.write(face)
            except Exception as err:  # pylint: disable=broad-except
                logger.error("Failed to save image '%s'. Original Error: %s", filename, err)
                continue
        logger.debug("Save Faces: Complete")

    def process_item_count(self):
        """ Return the number of items to be processedd """
        processed = sum(os.path.basename(frame) in self.alignments.data.keys()
                        for frame in self.images.input_images)
        logger.debug("Items already processed: %s", processed)

        if processed != 0 and self.args.skip_existing:
            logger.info("Skipping previously extracted frames: %s", processed)
        if processed != 0 and self.args.skip_faces:
            logger.info("Skipping frames with detected faces: %s", processed)

        to_process = (self.images.images_found - processed) // self.skip_num
        logger.debug("Items to be Processed: %s", to_process)
        if to_process == 0:
            logger.error("No frames to process. Exiting")
            queue_manager.terminate_queues()
            exit(0)
        return to_process

    def run_extraction(self):
        """ Run Face Detection """
        to_process = self.process_item_count()
        size = self.args.size if hasattr(self.args, "size") else 256
 </s> add     def _run_extraction(self):
        """ The main Faceswap Extraction process

        Receives items from :class:`plugins.extract.Pipeline.Extractor` and either saves out the
        faces and data (if on the final pass) or reprocesses data through the pipeline for serial
        processing.
        """
        size = self._args.size if hasattr(self._args, "size") else 256
        saver = ImagesSaver(self._output_dir, as_bytes=True)
        filename, extension = os.path.splitext(os.path.basename(faces["filename"]))
        for idx, face in enumerate(faces["detected_faces"]):
            output_filename = "{}_{}{}".format(filename, str(idx), extension)
            face.hash, image = encode_image_with_hash(face.aligned_face, extension)

            saver.save(output_filename, image)
  
      def output_faces(self, filename, faces):
          """ Output faces to save thread """
          final_faces = list()
        filename, extension = os.path.splitext(os.path.basename(faces["filename"]))
        for idx, face in enumerate(faces["detected_faces"]):
            output_filename = "{}_{}{}".format(filename, str(idx), extension)
            face.hash, image = encode_image_with_hash(face.aligned_face, extension)

            saver.save(output_filename, image)
        filename, extension = os.path.splitext(os.path.basename(faces["filename"]))
        for idx, face in enumerate(faces["detected_faces"]):
            output_filename = "{}_{}{}".format(filename, str(idx), extension)
            face.hash, image = encode_image_with_hash(face.aligned_face, extension)

            saver.save(output_filename, image)
        filename, extension = os.path.splitext(os.path.basename(faces["filename"]))
        for idx, face in enumerate(faces["detected_faces"]):
            output_filename = "{}_{}{}".format(filename, str(idx), extension)
            face.hash, image = encode_image_with_hash(face.aligned_face, extension)

            saver.save(output_filename, image)
        filename, extension = os.path.splitext(os.path.basename(faces["filename"]))
        for idx, face in enumerate(faces["detected_faces"]):
            output_filename = "{}_{}{}".format(filename, str(idx), extension)
            face.hash, image = encode_image_with_hash(face.aligned_face, extension)

            saver.save(output_filename, image)
        filename, extension = os.path.splitext(os.path.basename(faces["filename"]))
        for idx, face in enumerate(faces["detected_faces"]):
            output_filename = "{}_{}{}".format(filename, str(idx), extension)
            face.hash, image = encode_image_with_hash(face.aligned_face, extension)

            saver.save(output_filename, image)
        filename, extension = os.path.splitext(os.path.basename(faces["filename"]))
        for idx, face in enumerate(faces["detected_faces"]):
            output_filename = "{}_{}{}".format(filename, str(idx), extension)
            face.hash, image = encode_image_with_hash(face.aligned_face, extension)

            saver.save(output_filename, image)
        filename, extension = os.path.splitext(os.path.basename(faces["filename"]))
        for idx, face in enumerate(faces["detected_faces"]):
            output_filename = "{}_{}{}".format(filename, str(idx), extension)
            face.hash, image = encode_image_with_hash(face.aligned_face, extension)

            saver.save(output_filename, image)
        filename, extension = os.path.splitext(os.path.basename(faces["filename"]))
        for idx, face in enumerate(faces["detected_faces"]):
            output_filename = "{}_{}{}".format(filename, str(idx), extension)
            face.hash, image = encode_image_with_hash(face.aligned_face, extension)

            saver.save(output_filename, image)
        filename, extension = os.path.splitext(os.path.basename(faces["filename"]))
        for idx, face in enumerate(faces["detected_faces"]):
            output_filename = "{}_{}{}".format(filename, str(idx), extension)
            face.hash, image = encode_image_with_hash(face.aligned_face, extension)

            saver.save(output_filename, image)
              final_faces.append(face.to_alignment())
          self.alignments.data[os.path.basename(filename)] = final_faces
keep keep keep keep replace replace replace replace replace replace replace replace replace keep keep
 scripts.extract - code optimizations

Limit queue sizes to reduce RAM usage
Rename lib.image.BackgroundIO to ImageIO
Create separate ImagesLoader and ImagesSaver classes
Load/Save images from centralized lib.image.ImageIO
scripts.extract documentation 
scripts/extract.py