                           colorspace="RGB",
                           input_size=256,
                           **kwargs)
          self.vram = 2240
          self.model = None
          self.reference_scale = 195
  
      def initialize(self, *args, **kwargs):
          """ Initialization tasks to run prior to alignments """
          try:
 
</s> remove         super().__init__(git_model_id=git_model_id,
                         model_filename=model_filename,
                         colorspace="RGB",
                         input_size=128,
                         **kwargs)
 </s> add         super().__init__(git_model_id=git_model_id, model_filename=model_filename, **kwargs)

        self.name = "cv2-DNN Aligner"
        self.input_size = 128
        self.colorformat = "RGB" </s> remove         git_model_id = 0
        model_filename = "face-alignment-network_2d4_v1.pb"
        super().__init__(git_model_id=git_model_id,
                         model_filename=model_filename,
                         colorspace="RGB",
                         input_size=256,
                         **kwargs)
 </s> add         git_model_id = 9
        model_filename = "face-alignment-network_2d4_keras_v1.h5"
        super().__init__(git_model_id=git_model_id, model_filename=model_filename, **kwargs)
        self.name = "FAN"
        self.input_size = 256
        self.colorformat = "RGB" </s> remove         self.model = None

    def initialize(self, *args, **kwargs):
        """ Initialization tasks to run prior to alignments """
        try:
            super().initialize(*args, **kwargs)
            logger.info("Initializing cv2 DNN Aligner...")
            logger.debug("cv2 DNN initialize: (args: %s kwargs: %s)", args, kwargs)
            logger.verbose("Using CPU for alignment")

            self.model = cv2.dnn.readNetFromTensorflow(  # pylint: disable=no-member
                self.model_path)
            self.model.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)  # pylint: disable=no-member
            self.init.set()
            logger.info("Initialized cv2 DNN Aligner.")
        except Exception as err:
            self.error.set()
            raise err

    def align_image(self, detected_face, image):
 </s> add         self.batchsize = 1

    def init_model(self):
        """ Initialize CV2 DNN Detector Model"""
        self.model = cv2.dnn.readNetFromTensorflow(self.model_path)  # pylint: disable=no-member
        self.model.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)  # pylint: disable=no-member

    def process_input(self, batch):
        """ Compile the detected faces for prediction """
        faces, batch["roi"] = self.align_image(batch["detected_faces"])
        faces = self._normalize_faces(faces)
        batch["feed"] = np.array(faces, dtype="float32").transpose((0, 3, 1, 2))
        return batch

    def align_image(self, detected_faces): </s> remove     def initialize(self, *args, **kwargs):
        """ Initialization tasks to run prior to alignments """
        try:
            super().initialize(*args, **kwargs)
            logger.info("Initializing Face Alignment Network...")
            logger.debug("fan initialize: (args: %s kwargs: %s)", args, kwargs)

            _, _, vram_total = self.get_vram_free()

            if vram_total <= self.vram:
                tf_ratio = 1.0
            else:
                tf_ratio = self.vram / vram_total
            logger.verbose("Reserving %sMB for face alignments", self.vram)

            self.model = FAN(self.model_path, ratio=tf_ratio)

            self.init.set()
            logger.info("Initialized Face Alignment Network.")
        except Exception as err:
            self.error.set()
            raise err

    # DETECTED FACE BOUNDING BOX PROCESSING
    def align_image(self, detected_face, image):
        """ Get center and scale, crop and align image around center """
        logger.trace("Aligning image around center")
        center, scale = self.get_center_scale(detected_face)
        image = self.crop(image, center, scale)
 </s> add     def init_model(self):
        """ Initialize FAN model """
        model_kwargs = dict(custom_objects={'TorchBatchNorm2D': TorchBatchNorm2D})
        self.model = KSession(self.name, self.model_path, model_kwargs=model_kwargs)
        self.model.load_model()
        # Feed a placeholder so Aligner is primed for Manual tool
        placeholder = np.zeros((self.batchsize, 3, self.input_size, self.input_size),
                               dtype="float32")
        self.model.predict(placeholder)

    def process_input(self, batch):
        """ Compile the detected faces for prediction """
        # TODO Batching
        logger.trace("Aligning faces around center")
        batch["center_scale"] = self.get_center_scale(batch["detected_faces"])
        faces = self.crop(batch) </s> remove         self.target = (300, 300)  # Doesn't use VRAM
        self.vram = 0
        self.detector = None
 </s> add         self.name = "cv2-DNN Detector"
        self.input_size = 300
        self.vram = 0  # CPU Only. Doesn't use VRAM
        self.batchsize = 1
        self.vram_warnings = 512  # Will run at this with warnings
        self.vram_per_batch = 64
        self.batchsize = self.config["batch-size"]
                           colorspace="RGB",
                           input_size=256,
                           **kwargs)
          self.vram = 2240
        self.vram_warnings = 512  # Will run at this with warnings
        self.vram_per_batch = 64
        self.batchsize = self.config["batch-size"]
          self.reference_scale = 195
  
      def initialize(self, *args, **kwargs):
          """ Initialization tasks to run prior to alignments """
          try:
keep keep keep keep replace keep keep keep keep keep
 De-Multiprocess Extract (#871)

* requirements.txt: - Pin opencv to 4.1.1 (fixes cv2-dnn error)

* lib.face_detect.DetectedFace: change LandmarksXY to landmarks_xy. Add left, right, top, bottom attributes

* lib.model.session: Session manager for loading models into different graphs (for Nvidia + CPU)

* plugins.extract._base: New parent class for all extract plugins

* plugins.extract.pipeline. Remove MultiProcessing. Dynamically limit batchsize for Nvidia cards. Remove loglevel input

* S3FD + FAN plugins. Standardise to Keras version for all backends

* Standardize all extract plugins to new threaded codebase

* Documentation. Start implementing Numpy style docstrings for Sphinx Documentation

* Remove s3fd_amd. Change convert OTF to expect DetectedFace object

* faces_detect - clean up and documentation

* Remove PoolProcess

* Migrate manual tool to new extract workflow

* Remove AMD specific extractor code from cli and plugins

* Sort tool to new extract workflow

* Remove multiprocessing from project

* Remove multiprocessing queues from QueueManager

* Remove multiprocessing support from logger

* Move face_filter to new extraction pipeline

* Alignments landmarksXY > landmarks_xy and legacy handling

* Intercept get_backend for sphinx doc build

# Add Sphinx documentation 
plugins/extract/align/fan.py