class_docstr: MTCNN face detection module.
  
  This class loads pretrained P-, R-, and O-nets and returns images cropped to include the face
  only, given raw input images of one of the following types:
      - PIL image or list of PIL images
      - numpy.ndarray (uint8) representing either a single image (3D) or a batch of images (4D).
  Cropped faces can optionally be saved to file
  also.
  
  Keyword Arguments:
      image_size {int} -- Output image size in pixels. The image will be square. (default: {160})
      margin {int} -- Margin to add to bounding box, in terms of pixels in the final image. 
          Note that the application of the margin differs slightly from the davidsandberg/facenet
          repo, which applies the margin to the original image before resizing, making the margin
          dependent on the original image size (this is a bug in davidsandberg/facenet).
          (default: {0})
      min_face_size {int} -- Minimum face size to search for. (default: {20})
      thresholds {list} -- MTCNN face detection thresholds (default: {[0.6, 0.7, 0.7]})
      factor {float} -- Factor used to create a scaling pyramid of face sizes. (default: {0.709})
      post_process {bool} -- Whether or not to post process images tensors before returning.
          (default: {True})
      select_largest {bool} -- If True, if multiple faces are detected, the largest is returned.
          If False, the face with the highest detection probability is returned.
          (default: {True})
      selection_method {string} -- Which heuristic to use for selection. Default None. If
          specified, will override select_largest:
                  "probability": highest probability selected
                  "largest": largest box selected
                  "largest_over_threshold": largest box over a certain probability selected
                  "center_weighted_size": box size minus weighted squared offset from image center
              (default: {None})
      keep_all {bool} -- If True, all detected faces are returned, in the order dictated by the
          select_largest parameter. If a save_path is specified, the first face is saved to that
          path and the remaining faces are saved to <save_path>1, <save_path>2 etc.
          (default: {False})
      device {torch.device} -- The device on which to run neural net passes. Image tensors and
          models are copied to this device before running forward passes. (default: {None})
class_docstr_tok: ["MTCNN","face","detection","module",".","This","class","loads","pretrained","P-",",","R-",",","and","O-nets","and","returns","images","cropped","to","include","the","face","only",",","given","raw","input","images","of","one","of","the","following","types",":","-","PIL","image","or","list","of","PIL","images","-","numpy.ndarray","(","uint8",")","representing","either","a","single","image","(","3D",")","or","a","batch","of","images","(","4D",")",".","Cropped","faces","can","optionally","be","saved","to","file","also",".","Keyword","Arguments",":","image_size","{","int","}","--","Output","image","size","in","pixels",".","The","image","will","be","square",".","(","default",":","{","160","}",")","margin","{","int","}","--","Margin","to","add","to","bounding","box",",","in","terms","of","pixels","in","the","final","image",".","Note","that","the","application","of","the","margin","differs","slightly","from","the","davidsandberg\/facenet","repo",",","which","applies","the","margin","to","the","original","image","before","resizing",",","making","the","margin","dependent","on","the","original","image","size","(","this","is","a","bug","in","davidsandberg\/facenet",")",".","(","default",":","{","0","}",")","min_face_size","{","int","}","--","Minimum","face","size","to","search","for",".","(","default",":","{","20","}",")","thresholds","{","list","}","--","MTCNN","face","detection","thresholds","(","default",":","{","[","0.6",",","0.7",",","0.7","]","}",")","factor","{","float","}","--","Factor","used","to","create","a","scaling","pyramid","of","face","sizes",".","(","default",":","{","0.709","}",")","post_process","{","bool","}","--","Whether","or","not","to","post","process","images","tensors","before","returning",".","(","default",":","{","True","}",")","select_largest","{","bool","}","--","If","True",",","if","multiple","faces","are","detected",",","the","largest","is","returned",".","If","False",",","the","face","with","the","highest","detection","probability","is","returned",".","(","default",":","{","True","}",")","selection_method","{","string","}","--","Which","heuristic","to","use","for","selection",".","Default","None",".","If","specified",",","will","override","select_largest",":","``","probability","''",":","highest","probability","selected","``","largest","''",":","largest","box","selected","``","largest_over_threshold","''",":","largest","box","over","a","certain","probability","selected","``","center_weighted_size","''",":","box","size","minus","weighted","squared","offset","from","image","center","(","default",":","{","None","}",")","keep_all","{","bool","}","--","If","True",",","all","detected","faces","are","returned",",","in","the","order","dictated","by","the","select_largest","parameter",".","If","a","save_path","is","specified",",","the","first","face","is","saved","to","that","path","and","the","remaining","faces","are","saved","to","<","save_path",">","1",",","<","save_path",">","2","etc",".","(","default",":","{","False","}",")","device","{","torch.device","}","--","The","device","on","which","to","run","neural","net","passes",".","Image","tensors","and","models","are","copied","to","this","device","before","running","forward","passes",".","(","default",":","{","None","}",")"]
code: def extract(self, img, batch_boxes, save_path):
      # Determine if a batch or single image was passed
      batch_mode = True
      if (
          not isinstance(img, (list, tuple))
          and not (isinstance(img, np.ndarray) and len(img.shape) == 4)
          and not (
              isinstance(img, torch.Tensor) and len(img.shape) == 4
          )
      ):
          img = [img]
          batch_boxes = [batch_boxes]
          batch_mode = False
  
      # Parse save path(s)
      if save_path is not None:
          if isinstance(save_path, str):
              save_path = [save_path]
      else:
          save_path = [None for _ in range(len(img))]
  
      # Process all bounding boxes
      faces = []
      for im, box_im, path_im in zip(img, batch_boxes, save_path):
          if box_im is None:
              faces.append(None)
              continue
  
          if not self.keep_all:
              box_im = box_im[[0]]
  
          faces_im = []
          for i, box in enumerate(box_im):
              face_path = path_im
              if path_im is not None and i > 0:
                  save_name, ext = os.path.splitext(path_im)
                  face_path = save_name + "_" + str(i + 1) + ext
  
              face = extract_face(
                  im, box, self.image_size, self.margin, face_path
              )
              if self.post_process:
                  face = fixed_image_standardization(face)
              faces_im.append(face)
  
          if self.keep_all:
              faces_im = torch.stack(faces_im)
          else:
              faces_im = faces_im[0]
  
          faces.append(faces_im)
  
      if not batch_mode:
          faces = faces[0]
  
      return faces
  
imports: import torch
  from torch import nn
  import numpy
  import os
  from .utils.detect_face import detect_face, extract_face
label_desc: Use image node_id 5 for calling the MTCNN obj's underlying member method code with example usage: obj.extract(img, batch_boxes, save_path) and returns: faces