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","}",")"]
docstr: Selects a single box from multiple for a given image using one of multiple heuristics.
  
  Arguments:
          all_boxes {np.ndarray} -- Ix0 ndarray where each element is a Nx4 ndarry of
              bounding boxes for N detected faces in I images (output from self.detect).
          all_probs {np.ndarray} -- Ix0 ndarray where each element is a Nx0 ndarry of
              probabilities for N detected faces in I images (output from self.detect).
          all_points {np.ndarray} -- Ix0 ndarray where each element is a Nx5x2 array of
              points for N detected faces. (output from self.detect).
          imgs {PIL.Image, np.ndarray, or list} -- A PIL image, np.ndarray, torch.Tensor, or list.
  
  Keyword Arguments:
          method {str} -- Which heuristic to use for selection:
              "probability": highest probability selected
              "largest": largest box selected
              "largest_over_theshold": largest box over a certain probability selected
              "center_weighted_size": box size minus weighted squared offset from image center
              (default: {'probability'})
          threshold {float} -- theshold for "largest_over_threshold" method. (default: {0.9})
          center_weight {float} -- weight for squared offset in center weighted size method.
              (default: {2.0})
  
  Returns:
          tuple(numpy.ndarray, numpy.ndarray, numpy.ndarray) -- nx4 ndarray of bounding boxes
              for n images. Ix0 array of probabilities for each box, array of landmark points.
docstr_tok: ["Selects","a","single","box","from","multiple","for","a","given","image","using","one","of","multiple","heuristics",".","Arguments",":","all_boxes","{","np.ndarray","}","--","Ix0","ndarray","where","each","element","is","a","Nx4","ndarry","of","bounding","boxes","for","N","detected","faces","in","I","images","(","output","from","self.detect",")",".","all_probs","{","np.ndarray","}","--","Ix0","ndarray","where","each","element","is","a","Nx0","ndarry","of","probabilities","for","N","detected","faces","in","I","images","(","output","from","self.detect",")",".","all_points","{","np.ndarray","}","--","Ix0","ndarray","where","each","element","is","a","Nx5x2","array","of","points","for","N","detected","faces",".","(","output","from","self.detect",")",".","imgs","{","PIL.Image",",","np.ndarray",",","or","list","}","--","A","PIL","image",",","np.ndarray",",","torch.Tensor",",","or","list",".","Keyword","Arguments",":","method","{","str","}","--","Which","heuristic","to","use","for","selection",":","``","probability","''",":","highest","probability","selected","``","largest","''",":","largest","box","selected","``","largest_over_theshold","''",":","largest","box","over","a","certain","probability","selected","``","center_weighted_size","''",":","box","size","minus","weighted","squared","offset","from","image","center","(","default",":","{","'probability","'","}",")","threshold","{","float","}","--","theshold","for","``","largest_over_threshold","''","method",".","(","default",":","{","0.9","}",")","center_weight","{","float","}","--","weight","for","squared","offset","in","center","weighted","size","method",".","(","default",":","{","2.0","}",")","Returns",":","tuple","(","numpy.ndarray",",","numpy.ndarray",",","numpy.ndarray",")","--","nx4","ndarray","of","bounding","boxes","for","n","images",".","Ix0","array","of","probabilities","for","each","box",",","array","of","landmark","points","."]
code: def select_boxes(
      self,
      all_boxes,
      all_probs,
      all_points,
      imgs,
      method="probability",
      threshold=0.9,
      center_weight=2.0,
  ):
      """Selects a single box from multiple for a given image using one of multiple heuristics.
  
      Arguments:
              all_boxes {np.ndarray} -- Ix0 ndarray where each element is a Nx4 ndarry of
                  bounding boxes for N detected faces in I images (output from self.detect).
              all_probs {np.ndarray} -- Ix0 ndarray where each element is a Nx0 ndarry of
                  probabilities for N detected faces in I images (output from self.detect).
              all_points {np.ndarray} -- Ix0 ndarray where each element is a Nx5x2 array of
                  points for N detected faces. (output from self.detect).
              imgs {PIL.Image, np.ndarray, or list} -- A PIL image, np.ndarray, torch.Tensor, or list.
  
      Keyword Arguments:
              method {str} -- Which heuristic to use for selection:
                  "probability": highest probability selected
                  "largest": largest box selected
                  "largest_over_theshold": largest box over a certain probability selected
                  "center_weighted_size": box size minus weighted squared offset from image center
                  (default: {'probability'})
              threshold {float} -- theshold for "largest_over_threshold" method. (default: {0.9})
              center_weight {float} -- weight for squared offset in center weighted size method.
                  (default: {2.0})
  
      Returns:
              tuple(numpy.ndarray, numpy.ndarray, numpy.ndarray) -- nx4 ndarray of bounding boxes
                  for n images. Ix0 array of probabilities for each box, array of landmark points.
      """
  
      # copying batch detection from extract, but would be easier to ensure detect creates consistent output.
      batch_mode = True
      if (
          not isinstance(imgs, (list, tuple))
          and not (
              isinstance(imgs, np.ndarray) and len(imgs.shape) == 4
          )
          and not (
              isinstance(imgs, torch.Tensor) and len(imgs.shape) == 4
          )
      ):
          imgs = [imgs]
          all_boxes = [all_boxes]
          all_probs = [all_probs]
          all_points = [all_points]
          batch_mode = False
  
      selected_boxes, selected_probs, selected_points = [], [], []
      for boxes, points, probs, img in zip(
          all_boxes, all_points, all_probs, imgs
      ):
          if boxes is None:
              selected_boxes.append(None)
              selected_probs.append([None])
              selected_points.append(None)
              continue
  
          # If at least 1 box found
          boxes = np.array(boxes)
          probs = np.array(probs)
          points = np.array(points)
  
          if method == "largest":
              box_order = np.argsort(
                  (boxes[:, 2] - boxes[:, 0])
                  * (boxes[:, 3] - boxes[:, 1])
              )[::-1]
          elif method == "probability":
              box_order = np.argsort(probs)[::-1]
          elif method == "center_weighted_size":
              box_sizes = (boxes[:, 2] - boxes[:, 0]) * (
                  boxes[:, 3] - boxes[:, 1]
              )
              img_center = (img.width / 2, img.height / 2)
              box_centers = np.array(
                  list(
                      zip(
                          (boxes[:, 0] + boxes[:, 2]) / 2,
                          (boxes[:, 1] + boxes[:, 3]) / 2,
                      )
                  )
              )
              offsets = box_centers - img_center
              offset_dist_squared = np.sum(np.power(offsets, 2.0), 1)
              box_order = np.argsort(
                  box_sizes - offset_dist_squared * center_weight
              )[::-1]
          elif method == "largest_over_threshold":
              box_mask = probs > threshold
              boxes = boxes[box_mask]
              box_order = np.argsort(
                  (boxes[:, 2] - boxes[:, 0])
                  * (boxes[:, 3] - boxes[:, 1])
              )[::-1]
              if sum(box_mask) == 0:
                  selected_boxes.append(None)
                  selected_probs.append([None])
                  selected_points.append(None)
                  continue
  
          box = boxes[box_order][[0]]
          prob = probs[box_order][[0]]
          point = points[box_order][[0]]
          selected_boxes.append(box)
          selected_probs.append(prob)
          selected_points.append(point)
  
      if batch_mode:
          selected_boxes = np.array(selected_boxes)
          selected_probs = np.array(selected_probs)
          selected_points = np.array(selected_points)
      else:
          selected_boxes = selected_boxes[0]
          selected_probs = selected_probs[0][0]
          selected_points = selected_points[0]
  
      return selected_boxes, selected_probs, selected_points
  
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 4 for calling the MTCNN obj's underlying member method code with example usage: obj.select_boxes(all_boxes, all_probs, all_points, imgs, method, threshold, center_weight) and returns: selected_boxes,  selected_probs,  selected_points