code: def extract_faces(
      img: Union[str, np.ndarray],
      target_size: tuple = (224, 224),
      detector_backend: str = "opencv",
      grayscale: bool = False,
      enforce_detection: bool = True,
      align: bool = True,
  ) -> list:
      """Extract faces from an image.
  
      Args:
          img: a path, url, base64 or numpy array.
          target_size (tuple, optional): the target size of the extracted faces.
          Defaults to (224, 224).
          detector_backend (str, optional): the face detector backend. Defaults to "opencv".
          grayscale (bool, optional): whether to convert the extracted faces to grayscale.
          Defaults to False.
          enforce_detection (bool, optional): whether to enforce face detection. Defaults to True.
          align (bool, optional): whether to align the extracted faces. Defaults to True.
  
      Raises:
          ValueError: if face could not be detected and enforce_detection is True.
  
      Returns:
          list: a list of extracted faces.
      """
  
      # this is going to store a list of img itself (numpy), it region and confidence
      extracted_faces = []
  
      # img might be path, base64 or numpy array. Convert it to numpy whatever it is.
      img, img_name = load_image(img)
      img_region = [0, 0, img.shape[1], img.shape[0]]
  
      if detector_backend == "skip":
          face_objs = [(img, img_region, 0)]
      else:
          face_detector = FaceDetector.build_model(detector_backend)
          face_objs = FaceDetector.detect_faces(
              face_detector, detector_backend, img, align
          )
  
      # in case of no face found
      if len(face_objs) == 0 and enforce_detection is True:
          if img_name is not None:
              raise ValueError(
                  f"Face could not be detected in {img_name}."
                  "Please confirm that the picture is a face photo "
                  "or consider to set enforce_detection param to False."
              )
          else:
              raise ValueError(
                  "Face could not be detected. Please confirm that the picture is a face photo "
                  "or consider to set enforce_detection param to False."
              )
  
      if len(face_objs) == 0 and enforce_detection is False:
          face_objs = [(img, img_region, 0)]
  
      for current_img, current_region, confidence in face_objs:
          if current_img.shape[0] > 0 and current_img.shape[1] > 0:
              if grayscale is True:
                  current_img = cv2.cvtColor(
                      current_img, cv2.COLOR_BGR2GRAY
                  )
  
              # resize and padding
              factor_0 = target_size[0] / current_img.shape[0]
              factor_1 = target_size[1] / current_img.shape[1]
              factor = min(factor_0, factor_1)
  
              dsize = (
                  int(current_img.shape[1] * factor),
                  int(current_img.shape[0] * factor),
              )
              current_img = cv2.resize(current_img, dsize)
  
              diff_0 = target_size[0] - current_img.shape[0]
              diff_1 = target_size[1] - current_img.shape[1]
              if grayscale is False:
                  # Put the base image in the middle of the padded image
                  current_img = np.pad(
                      current_img,
                      (
                          (diff_0 // 2, diff_0 - diff_0 // 2),
                          (diff_1 // 2, diff_1 - diff_1 // 2),
                          (0, 0),
                      ),
                      "constant",
                  )
              else:
                  current_img = np.pad(
                      current_img,
                      (
                          (diff_0 // 2, diff_0 - diff_0 // 2),
                          (diff_1 // 2, diff_1 - diff_1 // 2),
                      ),
                      "constant",
                  )
  
              # double check: if target image is not still the same size with target.
              if current_img.shape[0:2] != target_size:
                  current_img = cv2.resize(current_img, target_size)
  
              # normalizing the image pixels
              # what this line doing? must?
              img_pixels = image.img_to_array(current_img)
              img_pixels = np.expand_dims(img_pixels, axis=0)
              img_pixels /= 255  # normalize input in [0, 1]
  
              # int cast is for the exception - object of type 'float32' is not JSON serializable
              region_obj = {
                  "x": int(current_region[0]),
                  "y": int(current_region[1]),
                  "w": int(current_region[2]),
                  "h": int(current_region[3]),
              }
  
              extracted_face = [img_pixels, region_obj, confidence]
              extracted_faces.append(extracted_face)
  
      if len(extracted_faces) == 0 and enforce_detection == True:
          raise ValueError(
              f"Detected face shape is {img.shape}. Consider to set enforce_detection arg to False."
          )
  
      return extracted_faces
  
file_path: deepface/deepface/commons/functions.py
imports: import os
  from typing import Union, Tuple
  import base64
  from pathlib import Path
  from PIL import Image
  import requests
  import numpy
  import cv2
  import tensorflow
  from deprecated import deprecated
  from deepface.detectors import FaceDetector
  from deepface.commons.logger import Logger
label_desc: Use image node_id 5 for calling a global function with example usage: extract_faces(img, target_size, detector_backend, grayscale, enforce_detection, align) and returns: extracted_faces