  
          logger.trace("Calculated center and scale: %s, %s", center, scale)
          return center, scale
  
      def crop(self, image, center, scale):  # pylint:disable=too-many-locals
          """ Crop image around the center point """
          logger.trace("Cropping image")
          is_color = 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],
                                  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 = image.shape[0]
          width = 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]] = 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]] = image[old_y[0] - 1:old_y[1],
                                                     old_x[0] - 1:old_x[1]]
  
          if new_img.shape[0] < self.input_size:
              interpolation = cv2.INTER_CUBIC  # pylint:disable=no-member
          else:
              interpolation = cv2.INTER_AREA  # pylint:disable=no-member
  
          new_img = cv2.resize(new_img,  # pylint:disable=no-member
                               dsize=(int(self.input_size), int(self.input_size)),
                               interpolation=interpolation)
          logger.trace("Cropped image")
          return new_img
  
      @staticmethod
      def transform(point, center, scale, resolution):
          """ Transform Image """
          logger.trace("Transforming Points")
 
</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         logger.trace("Calculated center and scale: %s, %s", center, scale)
        return center, scale
 </s> add             if new_img.shape[0] < self.input_size:
                interpolation = cv2.INTER_CUBIC  # pylint:disable=no-member
            else:
                interpolation = cv2.INTER_AREA  # pylint:disable=no-member </s> remove 
        box = (detected_face["left"],
               detected_face["top"],
               detected_face["right"],
               detected_face["bottom"])
        height = detected_face["bottom"] - detected_face["top"]
        width = detected_face["right"] - detected_face["left"]
        diff_height_width = height - width
        offset_y = int(abs(diff_height_width / 2))
        box_moved = self.move_box(box, [0, offset_y])

        # Make box square.
        roi = self.get_square_box(box_moved)
        # Pad the image if face is outside of boundaries
        image = self.pad_image(roi, image)
        face = image[roi[1]: roi[3], roi[0]: roi[2]]

        if face.shape[0] < self.input_size:
            interpolation = cv2.INTER_CUBIC  # pylint:disable=no-member
        else:
            interpolation = cv2.INTER_AREA  # pylint:disable=no-member

        face = cv2.resize(face,  # pylint:disable=no-member
                          dsize=(int(self.input_size), int(self.input_size)),
                          interpolation=interpolation)
        return dict(image=face, roi=roi)
 </s> add         rois = []
        faces = []
        for face in detected_faces:
            box = (face.left,
                   face.top,
                   face.right,
                   face.bottom)
            diff_height_width = face.h - face.w
            offset_y = int(abs(diff_height_width / 2))
            box_moved = self.move_box(box, [0, offset_y])

            # Make box square.
            roi = self.get_square_box(box_moved)
            # Pad the image if face is outside of boundaries
            image = self.pad_image(roi, face.image)
            face = image[roi[1]: roi[3], roi[0]: roi[2]]

            if face.shape[0] < self.input_size:
                interpolation = cv2.INTER_CUBIC  # pylint:disable=no-member
            else:
                interpolation = cv2.INTER_AREA  # pylint:disable=no-member

            face = cv2.resize(face,  # pylint:disable=no-member
                              dsize=(int(self.input_size), int(self.input_size)),
                              interpolation=interpolation)
            faces.append(face)
            rois.append(roi)
        return faces, rois </s> remove         if width < target[0] or height < target[1]:
            pad_l = (target[0] - width) // 2
            pad_r = (target[0] - width) - pad_l
            pad_t = (target[1] - height) // 2
            pad_b = (target[1] - height) - pad_t
            img = cv2.copyMakeBorder(  # pylint:disable=no-member
                image, pad_t, pad_b, pad_l, pad_r,
                cv2.BORDER_CONSTANT, (0, 0, 0)  # pylint:disable=no-member
            )
            return img
 </s> add         if width < self.input_size or height < self.input_size:
            pad_l = (self.input_size - width) // 2
            pad_r = (self.input_size - width) - pad_l
            pad_t = (self.input_size - height) // 2
            pad_b = (self.input_size - height) - pad_t
            image = cv2.copyMakeBorder(  # pylint:disable=no-member
                image,
                pad_t,
                pad_b,
                pad_l,
                pad_r,
                cv2.BORDER_CONSTANT)  # pylint:disable=no-member
        logger.trace("Padded image shape: %s", image.shape) </s> remove     # # # # # # # # # # # # #
    # first stage - fast proposal network (pnet) to obtain face candidates
    # # # # # # # # # # # # #
    for scale in scales:
        height_scale = int(np.ceil(height * scale))
        width_scale = int(np.ceil(width * scale))
        im_data = imresample(img, (height_scale, width_scale))
        im_data = (im_data - 127.5) * 0.0078125
        img_x = np.expand_dims(im_data, 0)
        img_y = np.transpose(img_x, (0, 2, 1, 3))
        out = pnet(img_y)
        out0 = np.transpose(out[0], (0, 2, 1, 3))
        out1 = np.transpose(out[1], (0, 2, 1, 3))

        boxes, _ = generate_bounding_box(out1[0, :, :, 1].copy(),
                                         out0[0, :, :, :].copy(),
                                         scale, threshold[0])

        # inter-scale nms
        pick = nms(boxes.copy(), 0.5, 'Union')
        if boxes.size > 0 and pick.size > 0:
            boxes = boxes[pick, :]
            total_boxes = np.append(total_boxes, boxes, axis=0)

    numbox = total_boxes.shape[0]
    if numbox > 0:
        pick = nms(total_boxes.copy(), 0.7, 'Union')
        total_boxes = total_boxes[pick, :]
        regw = total_boxes[:, 2]-total_boxes[:, 0]
        regh = total_boxes[:, 3]-total_boxes[:, 1]
        qq_1 = total_boxes[:, 0]+total_boxes[:, 5] * regw
        qq_2 = total_boxes[:, 1]+total_boxes[:, 6] * regh
        qq_3 = total_boxes[:, 2]+total_boxes[:, 7] * regw
        qq_4 = total_boxes[:, 3]+total_boxes[:, 8] * regh
        total_boxes = np.transpose(np.vstack([qq_1, qq_2, qq_3, qq_4, total_boxes[:, 4]]))
        total_boxes = rerec(total_boxes.copy())
        total_boxes[:, 0:4] = np.fix(total_boxes[:, 0:4]).astype(np.int32)
        d_y, ed_y, d_x, ed_x, var_y, e_y, var_x, e_x, tmpw, tmph = pad(total_boxes.copy(),
                                                                       width, height)

    numbox = total_boxes.shape[0]

    # # # # # # # # # # # # #
    # second stage - refinement of face candidates with rnet
    # # # # # # # # # # # # #

    if numbox > 0:
        tempimg = np.zeros((24, 24, 3, numbox))
        for k in range(0, numbox):
            tmp = np.zeros((int(tmph[k]), int(tmpw[k]), 3))
            tmp[d_y[k] - 1:ed_y[k], d_x[k] - 1:ed_x[k], :] = img[var_y[k] - 1:e_y[k],
                                                                 var_x[k]-1:e_x[k], :]
            if tmp.shape[0] > 0 and tmp.shape[1] > 0 or tmp.shape[0] == 0 and tmp.shape[1] == 0:
                tempimg[:, :, :, k] = imresample(tmp, (24, 24))
            else:
                return np.empty()
        tempimg = (tempimg-127.5)*0.0078125
        tempimg1 = np.transpose(tempimg, (3, 1, 0, 2))
        out = rnet(tempimg1)
        out0 = np.transpose(out[0])
        out1 = np.transpose(out[1])
        score = out1[1, :]
        ipass = np.where(score > threshold[1])
        total_boxes = np.hstack([total_boxes[ipass[0], 0:4].copy(),
                                 np.expand_dims(score[ipass].copy(), 1)])
        m_v = out0[:, ipass[0]]
        if total_boxes.shape[0] > 0:
            pick = nms(total_boxes, 0.7, 'Union')
            total_boxes = total_boxes[pick, :]
            total_boxes = bbreg(total_boxes.copy(), np.transpose(m_v[:, pick]))
            total_boxes = rerec(total_boxes.copy())

    numbox = total_boxes.shape[0]

    # # # # # # # # # # # # #
    # third stage - further refinement and facial landmarks positions with onet
    # NB: Facial landmarks code commented out for faceswap
    # # # # # # # # # # # # #

    if numbox > 0:
        # third stage
        total_boxes = np.fix(total_boxes).astype(np.int32)
        d_y, ed_y, d_x, ed_x, var_y, e_y, var_x, e_x, tmpw, tmph = pad(total_boxes.copy(),
                                                                       width, height)
        tempimg = np.zeros((48, 48, 3, numbox))
        for k in range(0, numbox):
            tmp = np.zeros((int(tmph[k]), int(tmpw[k]), 3))
            tmp[d_y[k] - 1:ed_y[k], d_x[k] - 1:ed_x[k], :] = img[var_y[k] - 1:e_y[k],
                                                                 var_x[k] - 1:e_x[k], :]
            if tmp.shape[0] > 0 and tmp.shape[1] > 0 or tmp.shape[0] == 0 and tmp.shape[1] == 0:
                tempimg[:, :, :, k] = imresample(tmp, (48, 48))
            else:
                return np.empty()
        tempimg = (tempimg-127.5)*0.0078125
        tempimg1 = np.transpose(tempimg, (3, 1, 0, 2))
        out = onet(tempimg1)
        out0 = np.transpose(out[0])
        out1 = np.transpose(out[1])
        out2 = np.transpose(out[2])
        score = out2[1, :]
        points = out1
        ipass = np.where(score > threshold[2])
        points = points[:, ipass[0]]
        total_boxes = np.hstack([total_boxes[ipass[0], 0:4].copy(),
                                 np.expand_dims(score[ipass].copy(), 1)])
        m_v = out0[:, ipass[0]]

        width = total_boxes[:, 2] - total_boxes[:, 0] + 1
        height = total_boxes[:, 3] - total_boxes[:, 1] + 1
        points[0:5, :] = (np.tile(width, (5, 1)) * points[0:5, :] +
                          np.tile(total_boxes[:, 0], (5, 1)) - 1)
        points[5:10, :] = (np.tile(height, (5, 1)) * points[5:10, :] +
                           np.tile(total_boxes[:, 1], (5, 1)) - 1)
        if total_boxes.shape[0] > 0:
            total_boxes = bbreg(total_boxes.copy(), np.transpose(m_v))
            pick = nms(total_boxes.copy(), 0.7, 'Min')
            total_boxes = total_boxes[pick, :]
            points = points[:, pick]

    return total_boxes, points


# function [boundingbox] = bbreg(boundingbox,reg)
def bbreg(boundingbox, reg):
    """Calibrate bounding boxes"""
    if reg.shape[1] == 1:
        reg = np.reshape(reg, (reg.shape[2], reg.shape[3]))

    width = boundingbox[:, 2] - boundingbox[:, 0] + 1
    height = boundingbox[:, 3] - boundingbox[:, 1] + 1
    b_1 = boundingbox[:, 0] + reg[:, 0] * width
    b_2 = boundingbox[:, 1] + reg[:, 1] * height
    b_3 = boundingbox[:, 2] + reg[:, 2] * width
    b_4 = boundingbox[:, 3] + reg[:, 3] * height
    boundingbox[:, 0:4] = np.transpose(np.vstack([b_1, b_2, b_3, b_4]))
    return boundingbox


def generate_bounding_box(imap, reg, scale, threshold):
    """Use heatmap to generate bounding boxes"""
    # pylint: disable=too-many-locals
    stride = 2
    cellsize = 12

    imap = np.transpose(imap)
    d_x1 = np.transpose(reg[:, :, 0])
    d_y1 = np.transpose(reg[:, :, 1])
    d_x2 = np.transpose(reg[:, :, 2])
    d_y2 = np.transpose(reg[:, :, 3])
    dim_y, dim_x = np.where(imap >= threshold)
    if dim_y.shape[0] == 1:
        d_x1 = np.flipud(d_x1)
        d_y1 = np.flipud(d_y1)
        d_x2 = np.flipud(d_x2)
        d_y2 = np.flipud(d_y2)
    score = imap[(dim_y, dim_x)]
    reg = np.transpose(np.vstack([d_x1[(dim_y, dim_x)], d_y1[(dim_y, dim_x)],
                                  d_x2[(dim_y, dim_x)], d_y2[(dim_y, dim_x)]]))
    if reg.size == 0:
        reg = np.empty((0, 3))
    bbox = np.transpose(np.vstack([dim_y, dim_x]))
    q_1 = np.fix((stride * bbox + 1) / scale)
    q_2 = np.fix((stride * bbox + cellsize - 1 + 1) / scale)
    boundingbox = np.hstack([q_1, q_2, np.expand_dims(score, 1), reg])
    return boundingbox, reg


# function pick = nms(boxes,threshold,type)
def nms(boxes, threshold, method):
    """ Non_Max Suppression """
    # pylint: disable=too-many-locals
    if boxes.size == 0:
        return np.empty((0, 3))
    x_1 = boxes[:, 0]
    y_1 = boxes[:, 1]
    x_2 = boxes[:, 2]
    y_2 = boxes[:, 3]
    var_s = boxes[:, 4]
    area = (x_2 - x_1 + 1) * (y_2 - y_1 + 1)
    s_sort = np.argsort(var_s)
    pick = np.zeros_like(var_s, dtype=np.int16)
    counter = 0
    while s_sort.size > 0:
        i = s_sort[-1]
        pick[counter] = i
        counter += 1
        idx = s_sort[0:-1]
        xx_1 = np.maximum(x_1[i], x_1[idx])
        yy_1 = np.maximum(y_1[i], y_1[idx])
        xx_2 = np.minimum(x_2[i], x_2[idx])
        yy_2 = np.minimum(y_2[i], y_2[idx])
        width = np.maximum(0.0, xx_2-xx_1+1)
        height = np.maximum(0.0, yy_2-yy_1+1)
        inter = width * height
        if method == 'Min':
            var_o = inter / np.minimum(area[i], area[idx])
        else:
            var_o = inter / (area[i] + area[idx] - inter)
        s_sort = s_sort[np.where(var_o <= threshold)]
    pick = pick[0:counter]
    return pick


# function [d_y ed_y d_x ed_x y e_y x e_x tmp_width tmp_height] = pad(total_boxes,width,height)
def pad(total_boxes, width, height):
    """Compute the padding coordinates (pad the bounding boxes to square)"""
    tmp_width = (total_boxes[:, 2] - total_boxes[:, 0] + 1).astype(np.int32)
    tmp_height = (total_boxes[:, 3] - total_boxes[:, 1] + 1).astype(np.int32)
    numbox = total_boxes.shape[0]

    d_x = np.ones((numbox), dtype=np.int32)
    d_y = np.ones((numbox), dtype=np.int32)
    ed_x = tmp_width.copy().astype(np.int32)
    ed_y = tmp_height.copy().astype(np.int32)

    dim_x = total_boxes[:, 0].copy().astype(np.int32)
    dim_y = total_boxes[:, 1].copy().astype(np.int32)
    e_x = total_boxes[:, 2].copy().astype(np.int32)
    e_y = total_boxes[:, 3].copy().astype(np.int32)

    tmp = np.where(e_x > width)
    ed_x.flat[tmp] = np.expand_dims(-e_x[tmp] + width + tmp_width[tmp], 1)
    e_x[tmp] = width

    tmp = np.where(e_y > height)
    ed_y.flat[tmp] = np.expand_dims(-e_y[tmp] + height + tmp_height[tmp], 1)
    e_y[tmp] = height

    tmp = np.where(dim_x < 1)
    d_x.flat[tmp] = np.expand_dims(2 - dim_x[tmp], 1)
    dim_x[tmp] = 1

    tmp = np.where(dim_y < 1)
    d_y.flat[tmp] = np.expand_dims(2 - dim_y[tmp], 1)
    dim_y[tmp] = 1

    return d_y, ed_y, d_x, ed_x, dim_y, e_y, dim_x, e_x, tmp_width, tmp_height


# function [bbox_a] = rerec(bbox_a)
def rerec(bbox_a):
    """Convert bbox_a to square."""
    height = bbox_a[:, 3]-bbox_a[:, 1]
    width = bbox_a[:, 2]-bbox_a[:, 0]
    length = np.maximum(width, height)
    bbox_a[:, 0] = bbox_a[:, 0] + width * 0.5 - length * 0.5
    bbox_a[:, 1] = bbox_a[:, 1] + height * 0.5 - length * 0.5
    bbox_a[:, 2:4] = bbox_a[:, 0:2] + np.transpose(np.tile(length, (2, 1)))
    return bbox_a


def imresample(img, size):
    """ Resample image """
    # pylint: disable=no-member
    im_data = cv2.resize(img, (size[1], size[0]),
                         interpolation=cv2.INTER_AREA)  # @UndefinedVariable
    return im_data
 </s> add def rect2square(rectangles):
    """ change rectangles into squares (matrix version)
    Input:
        rectangles: rectangles[i][0:3] is the position, rectangles[i][4] is score
    Output:
        squares: same as input
    """
    width = rectangles[:, 2] - rectangles[:, 0]
    height = rectangles[:, 3] - rectangles[:, 1]
    length = np.maximum(width, height).T
    rectangles[:, 0] = rectangles[:, 0] + width * 0.5 - length * 0.5
    rectangles[:, 1] = rectangles[:, 1] + height * 0.5 - length * 0.5
    rectangles[:, 2:4] = rectangles[:, 0:2] + np.repeat([length], 2, axis=0).T
    return rectangles
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
  
          logger.trace("Calculated center and scale: %s, %s", center, scale)
          return center, scale
  
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
            new_images.append(cv2.resize(new_img,  # pylint:disable=no-member
                                         dsize=(int(self.input_size), int(self.input_size)),
                                         interpolation=interpolation))
        logger.trace("Cropped images")
        return new_images
  
      @staticmethod
      def transform(point, center, scale, resolution):
          """ Transform Image """
          logger.trace("Transforming Points")
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 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/align/fan.py