class_docstr: This class contains all needed functions to work with faces in a frame
docstr: full process to extract face, ROI 
  face detection and facial landmark run every 3 frames
  age and gender detection runs every 6 frames
  last values of detections are used in other frames to reduce the time of the process
  ***NOTE: need 2 time facial landmarks, 1 for face alignment and 1 for facial landmarks in aligned face
  ***TODO: find facial landmarks after rotate (find co-ords after rotating) so don't need to do 2 facial landmarks
  Args:
      frame (cv2 image): input frame 
      type (str): 5 or 68 landmarks
      face_detect_on (bool): flag to run face detection and facial landmarks
      age_gender_on (bool): flag to run age gender detection
      
  Outputs:
      rects (array): detected faces as rectangles
      face (cv2 image): face
      (age, gender) (str,str): age and gender
      shape (array): facial landmarks' co-ords in format of tuples (x,y)
      aligned_face (cv2 image): face after alignment
      aligned_shape (array): facial landmarks' co-ords of the aligned face in format of tuples (x,y)
      #mask (cv2 image): mask of the face after fillConvexPoly
docstr_tok: ["full","process","to","extract","face",",","ROI","face","detection","and","facial","landmark","run","every","3","frames","age","and","gender","detection","runs","every","6","frames","last","values","of","detections","are","used","in","other","frames","to","reduce","the","time","of","the","process","*","*","*","NOTE",":","need","2","time","facial","landmarks",",","1","for","face","alignment","and","1","for","facial","landmarks","in","aligned","face","*","*","*","TODO",":","find","facial","landmarks","after","rotate","(","find","co-ords","after","rotating",")","so","do","n't","need","to","do","2","facial","landmarks","Args",":","frame","(","cv2","image",")",":","input","frame","type","(","str",")",":","5","or","68","landmarks","face_detect_on","(","bool",")",":","flag","to","run","face","detection","and","facial","landmarks","age_gender_on","(","bool",")",":","flag","to","run","age","gender","detection","Outputs",":","rects","(","array",")",":","detected","faces","as","rectangles","face","(","cv2","image",")",":","face","(","age",",","gender",")","(","str",",","str",")",":","age","and","gender","shape","(","array",")",":","facial","landmarks","'","co-ords","in","format","of","tuples","(","x",",","y",")","aligned_face","(","cv2","image",")",":","face","after","alignment","aligned_shape","(","array",")",":","facial","landmarks","'","co-ords","of","the","aligned","face","in","format","of","tuples","(","x",",","y",")","#","mask","(","cv2","image",")",":","mask","of","the","face","after","fillConvexPoly"]
code: def face_full_process(
      self, frame, type, face_detect_on, age_gender_on
  ):
      """
      full process to extract face, ROI
      face detection and facial landmark run every 3 frames
      age and gender detection runs every 6 frames
      last values of detections are used in other frames to reduce the time of the process
      ***NOTE: need 2 time facial landmarks, 1 for face alignment and 1 for facial landmarks in aligned face
      ***TODO: find facial landmarks after rotate (find co-ords after rotating) so don't need to do 2 facial landmarks
      Args:
          frame (cv2 image): input frame
          type (str): 5 or 68 landmarks
          face_detect_on (bool): flag to run face detection and facial landmarks
          age_gender_on (bool): flag to run age gender detection
  
      Outputs:
          rects (array): detected faces as rectangles
          face (cv2 image): face
          (age, gender) (str,str): age and gender
          shape (array): facial landmarks' co-ords in format of tuples (x,y)
          aligned_face (cv2 image): face after alignment
          aligned_shape (array): facial landmarks' co-ords of the aligned face in format of tuples (x,y)
          #mask (cv2 image): mask of the face after fillConvexPoly
      """
  
      # assign from last params
      age = self.last_age
      gender = self.last_gender
      rects = self.last_rects
      shape = self.last_shape
      aligned_shape = self.last_aligned_shape
  
      gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  
      if face_detect_on:
          if type == "5":
              shape, rects = self.get_landmarks(frame, "5")
              # mask = None
  
              if shape is None:
                  return None
          else:
              shape, rects = self.get_landmarks(frame, "68")
              # remapped_landmarks = self.facial_landmarks_remap(shape)
              # mask = np.zeros((face.shape[0], face.shape[1]))
              # cv2.fillConvexPoly(mask, remapped_landmarks[0:27], 1)
              if shape is None:
                  return None
  
      (x, y, w, h) = face_utils.rect_to_bb(rects[0])
  
      face = frame[y : y + h, x : x + w]
  
      if age_gender_on:
          age, gender = self.age_gender_detection(face)
  
      aligned_face, aligned_face = self.face_alignment(frame, shape)
  
      # if face_detect_on:
      # if(type=="5"):
      # aligned_shape, rects_2 = self.get_landmarks(aligned_face, "5")
      # if aligned_shape is None:
      # return None
      # else:
      # aligned_shape, rects_2 = self.get_landmarks(aligned_face, "68")
      # if aligned_shape is None:
      # return None
      # print("2: aligned_shape")
      # print(aligned_shape)
      # print("---")
  
      # assign to last params
      self.last_age = age
      self.last_gender = gender
      self.last_rects = rects
      self.last_shape = shape
      self.last_aligned_shape = aligned_shape
  
      # return rects, face, (age, gender), shape, aligned_face, mask
      return (
          rects,
          face,
          (age, gender),
          shape,
          aligned_face,
          aligned_shape,
      )
  
file_path: heart-rate-measurement-camera/new_update/face_utilities.py
imports: import cv2
  import numpy
  import dlib
  from imutils import face_utils
  import imutils
  from collections import OrderedDict
label_desc: Use image node_id 9 for calling the Face_utilities obj's underlying member method code with example usage: obj.face_full_process(frame, type, face_detect_on, age_gender_on) and returns: rects,  face,  age,  gender,  shape,  aligned_face,  aligned_shape, None, None