                      for face in faces]
          logger.trace("Processed Output: %s", detected)
          return detected
  
      @staticmethod
      def recalculate_bounding_box(faces, landmarks):
          """ Recalculate the bounding box for Face Alignment.
  
              Resize the bounding box around features to present
              a better box to Face Alignment. Helps its chances
              on edge cases and helps remove 'jitter' """
          logger.trace("Recalculating Bounding Boxes: (faces: %s, landmarks: %s)",
                       faces, landmarks)
          retval = list()
          no_faces = len(faces)
          if no_faces == 0:
              return retval
          face_landmarks = np.hsplit(landmarks, no_faces)
          for idx in range(no_faces):
              pts = np.reshape(face_landmarks[idx], (5, 2), order="F")
              nose = pts[2]
  
              minmax = (np.amin(pts, axis=0), np.amax(pts, axis=0))
              padding = [(minmax[1][0] - minmax[0][0]) / 2,
                         (minmax[1][1] - minmax[0][1]) / 2]
  
              center = (minmax[1][0] - padding[0], minmax[1][1] - padding[1])
              offset = (center[0] - nose[0], nose[1] - center[1])
              center = (center[0] + offset[0], center[1] + offset[1])
  
              padding[0] += padding[0]
              padding[1] += padding[1]
  
              bounding = [center[0] - padding[0], center[1] - padding[1],
                          center[0] + padding[0], center[1] + padding[1]]
              retval.append(bounding)
          logger.trace("Recalculated Bounding Boxes: %s", retval)
          return retval
  
  
  # MTCNN Detector for face alignment
  # Code adapted from: https://github.com/davidsandberg/facenet
  
  # Tensorflow implementation of the face detection / alignment algorithm
  # found at
  # https://github.com/kpzhang93/MTCNN_face_detection_alignment
  
  # MIT License
  #
 
</s> remove         center = np.array([(detected_face["left"] + detected_face["right"]) / 2.0,
                           (detected_face["top"] + detected_face["bottom"]) / 2.0])

        height = detected_face["bottom"] - detected_face["top"]
        width = detected_face["right"] - detected_face["left"]

        center[1] -= height * 0.12

        scale = (width + height) / self.reference_scale
 </s> add         l_center = []
        l_scale = []
        for face in detected_faces:
            center = np.array([(face.left + face.right) / 2.0, (face.top + face.bottom) / 2.0])
            center[1] -= face.h * 0.12
            l_center.append(center)
            l_scale.append((face.w + face.h) / self.reference_scale)
        logger.trace("Calculated center and scale: %s, %s", l_center, l_scale)
        return l_center, l_scale

    def crop(self, batch):  # pylint:disable=too-many-locals
        """ Crop image around the center point """
        logger.trace("Cropping images")
        new_images = []
        for face, center, scale in zip(batch["detected_faces"], *batch["center_scale"]):
            is_color = face.image.ndim > 2
            v_ul = self.transform([1, 1], center, scale, self.input_size).astype(np.int)
            v_br = self.transform([self.input_size, self.input_size],
                                  center,
                                  scale,
                                  self.input_size).astype(np.int)
            if is_color:
                new_dim = np.array([v_br[1] - v_ul[1],
                                    v_br[0] - v_ul[0],
                                    face.image.shape[2]],
                                   dtype=np.int32)
                new_img = np.zeros(new_dim, dtype=np.uint8)
            else:
                new_dim = np.array([v_br[1] - v_ul[1],
                                    v_br[0] - v_ul[0]],
                                   dtype=np.int)
                new_img = np.zeros(new_dim, dtype=np.uint8)
            height = face.image.shape[0]
            width = face.image.shape[1]
            new_x = np.array([max(1, -v_ul[0] + 1), min(v_br[0], width) - v_ul[0]],
                             dtype=np.int32)
            new_y = np.array([max(1, -v_ul[1] + 1),
                              min(v_br[1], height) - v_ul[1]],
                             dtype=np.int32)
            old_x = np.array([max(1, v_ul[0] + 1), min(v_br[0], width)],
                             dtype=np.int32)
            old_y = np.array([max(1, v_ul[1] + 1), min(v_br[1], height)],
                             dtype=np.int32)
            if is_color:
                new_img[new_y[0] - 1:new_y[1],
                        new_x[0] - 1:new_x[1]] = face.image[old_y[0] - 1:old_y[1],
                                                            old_x[0] - 1:old_x[1], :]
            else:
                new_img[new_y[0] - 1:new_y[1],
                        new_x[0] - 1:new_x[1]] = face.image[old_y[0] - 1:old_y[1],
                                                            old_x[0] - 1:old_x[1]] </s> remove     def landmarks_as_xy(self):
        """ Landmarks as XY """
        return self.landmarksXY

    def to_bounding_box_dict(self):
        """ Return Bounding Box as a bounding box dixt """
        retval = dict(left=self.x, top=self.y, right=self.x + self.w, bottom=self.y + self.h)
        logger.trace("Returning: %s", retval)
        return retval

    def from_bounding_box_dict(self, bounding_box_dict, image=None):
        """ Set Bounding Box from a bounding box dict """
        logger.trace("Creating from bounding box dict: %s", bounding_box_dict)
        if not isinstance(bounding_box_dict, dict):
            raise ValueError("Supplied Bounding Box is not a dictionary.")
        self.x = bounding_box_dict["left"]
        self.w = bounding_box_dict["right"] - bounding_box_dict["left"]
        self.y = bounding_box_dict["top"]
        self.h = bounding_box_dict["bottom"] - bounding_box_dict["top"]
        if image is not None and image.any():
            self.image_to_face(image)
        logger.trace("Created from bounding box dict: (x: %s, w: %s, y: %s. h: %s)",
                     self.x, self.w, self.y, self.h)
 </s> add     def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y </s> remove     def filter_small_faces(self, detected_faces):
        """ Filter out any faces smaller than the min size threshold """
        retval = list()
        for face in detected_faces:
            width = face["right"] - face["left"]
            height = face["bottom"] - face["top"]
            face_size = (width ** 2 + height ** 2) ** 0.5
            if face_size < self.min_size:
                logger.debug("Removing detected face: (face_size: %s, min_size: %s",
                             face_size, self.min_size)
                continue
            retval.append(face)
        return retval
 </s> add     @staticmethod
    def to_detected_face(left, top, right, bottom):
        """ Return a :class:`~lib.faces_detect.DetectedFace` object for the bounding box """
        return DetectedFace(x=int(round(left)),
                            w=int(round(right - left)),
                            y=int(round(top)),
                            h=int(round(bottom - top)))

    # <<< PROTECTED ACCESS METHODS >>> #
    # <<< PREDICT WRAPPER >>> #
    def _predict(self, batch):
        """ Wrap models predict function in rotations """
        batch["rotmat"] = [np.array([]) for _ in range(len(batch["feed"]))]
        found_faces = [np.array([]) for _ in range(len(batch["feed"]))]
        for angle in self.rotation:
            # Rotate the batch and insert placeholders for already found faces
            self._rotate_batch(batch, angle)
            batch = self.predict(batch)

            if angle != 0 and any([face.any() for face in batch["prediction"]]):
                logger.verbose("found face(s) by rotating image %s degrees", angle)

            found_faces = [face if not found.any() else found
                           for face, found in zip(batch["prediction"], found_faces)]

            if all([face.any() for face in found_faces]):
                logger.trace("Faces found for all images")
                break

        batch["prediction"] = found_faces
        logger.trace("detect_prediction output: (filenames: %s, prediction: %s, rotmat: %s)",
                     batch["filename"], batch["prediction"], batch["rotmat"])
        return batch </s> remove     def initialize(self, *args, **kwargs):
        """ Create the mtcnn detector """
        try:
            super().initialize(*args, **kwargs)
            logger.info("Initializing MTCNN Detector...")
            is_gpu = False

            # Must import tensorflow inside the spawned process
            # for Windows machines
            import_tensorflow()
            _, vram_free, _ = self.get_vram_free()
            mtcnn_graph = tf.Graph()

            # Windows machines sometimes misreport available vram, and overuse
            # causing OOM. Allow growth fixes that
            config = tf.ConfigProto()
            config.gpu_options.allow_growth = True  # pylint: disable=no-member

            with mtcnn_graph.as_default():  # pylint: disable=not-context-manager
                sess = tf.Session(config=config)
                with sess.as_default():  # pylint: disable=not-context-manager
                    pnet, rnet, onet = create_mtcnn(sess, self.model_path)

                if any("gpu" in str(device).lower()
                       for device in sess.list_devices()):
                    logger.debug("Using GPU")
                    is_gpu = True
            mtcnn_graph.finalize()

            if not is_gpu:
                alloc = 2048
                logger.warning("Using CPU")
            else:
                alloc = vram_free
            logger.debug("Allocated for Tensorflow: %sMB", alloc)

            self.batch_size = int(alloc / self.vram)

            if self.batch_size < 1:
                self.error.set()
                raise ValueError("Insufficient VRAM available to continue "
                                 "({}MB)".format(int(alloc)))

            logger.verbose("Processing in %s threads", self.batch_size)

            self.kwargs["pnet"] = pnet
            self.kwargs["rnet"] = rnet
            self.kwargs["onet"] = onet

            self.init.set()
            logger.info("Initialized MTCNN Detector.")
        except Exception as err:
            self.error.set()
            raise err

    def detect_faces(self, *args, **kwargs):
        """ Detect faces in Multiple Threads """
        super().detect_faces(*args, **kwargs)
        workers = MultiThread(target=self.detect_thread, thread_count=self.batch_size)
        workers.start()
        workers.join()
        sentinel = self.queues["in"].get()
        self.queues["out"].put(sentinel)
        logger.debug("Detecting Faces complete")

    def detect_thread(self):
        """ Detect faces in rgb image """
        logger.debug("Launching Detect")
        while True:
            item = self.get_item()
            if item == "EOF":
                break
            logger.trace("Detecting faces: '%s'", item["filename"])
            [detect_image, scale] = self.compile_detection_image(item["image"], to_rgb=True)

            for angle in self.rotation:
                current_image, rotmat = self.rotate_image(detect_image, angle)
                faces, points = detect_face(current_image, **self.kwargs)
                if angle != 0 and faces.any():
                    logger.verbose("found face(s) by rotating image %s degrees", angle)
                if faces.any():
                    break

            detected_faces = self.process_output(faces, points, rotmat, scale)
            item["detected_faces"] = detected_faces
            self.finalize(item)

        logger.debug("Thread Completed Detect")

    def process_output(self, faces, points, rotation_matrix, scale):
        """ Compile found faces for output """
        logger.trace("Processing Output: (faces: %s, points: %s, rotation_matrix: %s)",
                     faces, points, rotation_matrix)
        faces = self.recalculate_bounding_box(faces, points)
        faces = [self.to_bounding_box_dict(face[0], face[1], face[2], face[3]) for face in faces]
        if isinstance(rotation_matrix, np.ndarray):
            faces = [self.rotate_rect(face, rotation_matrix)
                     for face in faces]
        detected = [self.to_bounding_box_dict(face["left"] / scale, face["top"] / scale,
                                              face["right"] / scale, face["bottom"] / scale)
                    for face in faces]
        logger.trace("Processed Output: %s", detected)
        return detected
 </s> add     def init_model(self):
        """ Initialize S3FD Model"""
        self.model = MTCNN(self.model_path, **self.kwargs) </s> remove     def image_to_face(self, image):
        """ Crop an image around bounding box to the face
            and capture it's dimensions """
        logger.trace("Cropping face from image")
        self.image = image[self.y: self.y + self.h,
                           self.x: self.x + self.w]
 </s> add     @property
    def right(self):
        """int: Right point (in pixels) of face detection bounding box within the parent image """
        return self.x + self.w

    @property
    def bottom(self):
        """int: Bottom point (in pixels) of face detection bounding box within the parent image """
        return self.y + self.h

    @property
    def _extract_ratio(self):
        """ float: The ratio of padding to add for training images """
        return 0.375
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
                      for face in faces]
          logger.trace("Processed Output: %s", detected)
          return detected
  
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
    def process_input(self, batch):
        """ Compile the detection image(s) for prediction """
        batch["feed"] = (batch["scaled_image"] - 127.5) / 127.5
        return batch

    def predict(self, batch):
        """ Run model to get predictions """
        prediction, points = self.model.detect_faces(batch["feed"])
        logger.trace("filename: %s, prediction: %s, mtcnn_points: %s",
                     batch["filename"], prediction, points)
        batch["prediction"], batch["mtcnn_points"] = [prediction], [points]
        return batch

    def process_output(self, batch):
        """ Post process the detected faces """
        return batch


# MTCNN Detector
# Code adapted from: https://github.com/xiangrufan/keras-mtcnn
#
# Keras implementation of the face detection / alignment algorithm
  # found at
  # https://github.com/kpzhang93/MTCNN_face_detection_alignment
  
  # MIT License
  #
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 replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace 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/detect/mtcnn.py