          """ The ratio of padding to add for training images """
          return 0.375
  
      @property
      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)
  
      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")
 
</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 </s> remove                      self.x, self.w, self.y, self.h, self.landmarksXY)
 </s> add                      self.x, self.w, self.y, self.h, self.landmarks_xy)

    def _image_to_face(self, image):
        """ set self.image to be the cropped face from detected bounding box """
        logger.trace("Cropping face from image")
        self.image = image[self.top: self.bottom,
                           self.left: self.right] </s> remove     def extract_ratio(self):
        """ The ratio of padding to add for training images """
        return 0.375
 </s> add     def left(self):
        """int: Left point (in pixels) of face detection bounding box within the parent image """
        return self.x </s> remove     """ Detected face and landmark information """
    def __init__(  # pylint: disable=invalid-name
            self, image=None, x=None, w=None, y=None, h=None,
            landmarksXY=None):
        logger.trace("Initializing %s", self.__class__.__name__)
 </s> add     """ Detected face and landmark information

    Holds information about a detected face, it's location in a source image
    and the face's 68 point landmarks.

    Methods for aligning a face are also callable from here.

    Parameters
    ----------
    image: np.ndarray, optional
        This is a generic image placeholder that should not be relied on to be holding a particular
        image. It may hold the source frame that holds the face, a cropped face or a scaled image
        depending on the method using this object.
    x: int
        The left most point (in pixels) of the face's bounding box as discovered in
        :mod:`plugins.extract.detect`
    w: int
        The width (in pixels) of the face's bounding box as discovered in
        :mod:`plugins.extract.detect`
    y: int
        The top most point (in pixels) of the face's bounding box as discovered in
        :mod:`plugins.extract.detect`
    h: int
        The height (in pixels) of the face's bounding box as discovered in
        :mod:`plugins.extract.detect`
    landmarks_xy: list
        The 68 point landmarks as discovered in :mod:`plugins.extract.align`. Should be a ``list``
        of 68 `(x, y)` ``tuples`` with each of the landmark co-ordinates.
    """
    def __init__(self, image=None, x=None, w=None, y=None, h=None, landmarks_xy=None):
        logger.trace("Initializing %s: (image: %s, x: %s, w: %s, y: %s, h:%s, landmarks_xy: %s)",
                     self.__class__.__name__,
                     image.shape if image is not None and image.any() else image,
                     x, w, y, h, landmarks_xy) </s> remove     @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
 </s> add     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 top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
          """ The ratio of padding to add for training images """
          return 0.375
  
      @property
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
    def top(self):
        """int: Top point (in pixels) of face detection bounding box within the parent image """
        return self.y
  
      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")
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 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 
lib/faces_detect.py