Source code for pftracker.modules.facedetection.Face_detection

"""
Compute one face detection.

@author: Bessie Domínguez-Dáger
"""

import os
import cv2
from imutils.face_utils import rect_to_bb
import numpy as np
#import dlib
  

[docs]class detect_one_face(): """One face detection class. Class used for detecting one face in the first frame of video where particle filter algorithm is going to be applied. Args: image (array): image where the face detection is perfomed Supported Face detectors: - 'HaarCascade': Viola and Jones (V&J) detector - 'CaffeModel': Single Shot Detector (SSD) - 'dlib': Histogram of Oriented Gradient (HOG) """ def __init__(self, image): # Load the input image self.image = image self.box = (0,0,0,0) self.dir_path = os.path.dirname(os.path.realpath(__file__))
[docs] def detector(self, face_detector): """Run a face detector algortihm on image. Args: face_detector (str): Face detector algorithm to apply Returns: (tuple) with bounding box coordinates resulting from face detection on image in the format (startX, startY, endX, endY). Raises: AssertionError: Exception raised if the face detector algorithm couldn't detect any face (box iqual to (0, 0, 0, 0). """ if face_detector == "HaarCascade": # Run Viola and Jones (V&J) face detector self.haarCascade_detector() elif face_detector == "CaffeModel": # Run Single Shot Detector (SSD) algorithm self.caffeModel_detector() elif face_detector == "dlib": # Run Histogram of Oriented Gradient (HOG) face detector self.dlib_detector() # Raise an AssertionError if there's not any face detected assert self.box != (0,0,0,0), face_detector + " detector couldn't detect any face" return self.box
[docs] def bb_faces(self, face): """ Returns face bounding box coordinates in the format (startX, startY, endX, endY). Args: faces (tuple): face detection resulting from a detector algorithm in the format (startX, startY, w, h). Where w and h are the weight and height of the face bounding box respectevely. """ (startX, startY, w, h) = face endX = startX + w endY = startY + h self.box = (startX, startY, endX, endY)
[docs] def get_cascade_faces_from_model(self, model, minN): """Returns a list of face detections from Viola and Jones (V&J) algorithm. Args: model (str): HaarCascade face detector model (frontal, left profile or right profile) minN (int): Minimum of neighbors needed for retaining each candidate bounding box detected """ # Load face detector model from disk haarcascademodel = os.path.sep.join([self.dir_path, "models", model]) face_cascade = cv2.CascadeClassifier(haarcascademodel) # Obtain multiscale face detections faces = face_cascade.detectMultiScale(self.gray, scaleFactor=1.2, minNeighbors=minN) return faces
[docs] def haarCascade_detector(self): """Run Viola and Jones (V&J) face detector on image. Returns: (tuple) with face bounding box coordinates resulting from detection. """ # Convert the input image to grayscale self.gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY) # Load HaarCascade frontal face detector model from disk print("[INFO] loading HaarCascade frontal face detector model...") frontal_model = 'haarcascade_frontalface_default.xml' # Obtain frontal face detections frontal_faces = self.get_cascade_faces_from_model(frontal_model, 3) # Ensure at least one frontal face was detected if len(frontal_faces) != 0: # Get the bounding box coordinates of the frontal face with the # largest confidence in the format (startX, startY, endX, endY) self.bb_faces(frontal_faces[0]) else: # Load HaarCascade left profile face detector model from disk print("[INFO] loading HaarCascade left profile face detector model...") left_profile_model = 'haarcascade_profileface.xml' # Obtain left profile face detections left_profile_faces = self.get_cascade_faces_from_model(left_profile_model, 3) # Ensure at least one left profile face was detected if len(left_profile_faces) != 0: # Get the bounding box coordinates of the left profile face with the # largest confidence in the format (startX, startY, endX, endY) self.bb_faces(left_profile_faces[0]) else: # Load HaarCascade right profile face detector model from disk print("[INFO] loading HaarCascade right profile face detector model...") right_profile_model = 'haarcascade_profileface_left2.xml' # Obtain right profile face detections right_profile_faces = self.get_cascade_faces_from_model(right_profile_model, 3) # Ensure at least one right profile face was detected if len(right_profile_faces) != 0: # Get the bounding box coordinates of the right profile face with the # largest confidence in the format (startX, startY, endX, endY) self.bb_faces(right_profile_faces[0])
[docs] def caffeModel_detector(self, confidence = 0.5): """Run Single Shot Detector (SSD) algorithm for face detection on image. Args: confidence (float, optional): minimum algorithm confidence boundary for detection. Returns: (tuple) with face bounding box coordinates resulting from detection. """ # Load face detector model from disk print("[INFO] loading CaffeModel face detector model...") protoPath = os.path.sep.join([self.dir_path, "models", "deploy.prototxt.txt"]) modelPath = os.path.sep.join([self.dir_path, "models", "res10_300x300_ssd_iter_140000.caffemodel"]) net = cv2.dnn.readNetFromCaffe(protoPath, modelPath) # Grab the image dimensions (h, w) = self.image.shape[:2] # Create an input blob blob = cv2.dnn.blobFromImage(cv2.resize(self.image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0)) # Pass the input blob through the network and obtain face detections net.setInput(blob) detections = net.forward() # Ensure at least one face was detected if len(detections) > 0: # Get the index of the detection with the largest confidence. # The tracking is going to be performaced over the face with the # largest confidence (One Face Tracking). i = np.argmax(detections[0, 0, :, 2]) # Grab the confidence associated with the largest confidence face confidence_det = detections[0, 0, i, 2] # Discard weak detections (smaller than the minimum confidence) if confidence_det > confidence: # Compute face bounding box coordinates box = detections[0, 0, i, 3:7] * np.array([w, h, w, h]) (startX, startY, endX, endY) = box.astype("int") self.box = (startX, startY, endX, endY)
[docs] def dlib_detector(self): """Run Histogram of Oriented Gradient (HOG) face detector on image. Returns: (tuple) with face bounding box coordinates resulting from detection. """ # Initialize dlib's face detector (HOG-based detector) print("[INFO] loading HOG face detector model...")
# detector = dlib.get_frontal_face_detector() # # # Convert the input image to grayscale # gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY) # # # Obtain face detections # rects = detector(gray, 2) # # # Ensure at least one face was detected # if len(rects) != 0: # # Get the face detection with the largest confidence # face = rect_to_bb(rects[0]) # # # Get face bounding box coordinates in the format # # (startX, startY, endX, endY) # self.bb_faces(face)