Face Detection With OpenCV Haar Cascade vs Dlib HOG

by Sabbir Ahmed


Posted on: 3 years, 3 months ago


Members of IEEE, HSTU Student Brach (2018-2019)
Members of IEEE, HSTU Student Brach (2018-2019)

Face detection is the step 1 process for various vision projects. Face detection, as the name suggests, is identifying human faces in a digital image. Detecting face is an essential step in many computer vision applications like face analysis, face tracking, face recognition.

Haar Feature Based Cascades Classifier

It is a machine learning based approach in which the classifier is trained with a lot of positive images (with face) and a lot of negative images (without face). To extract haar features the classifier uses 3 images.

Haar Features

Now, we need to find the sum of all the pixel intensities in the black and white region which is a very process hungry. So we use Integral Image (preprocessed image) which trims down the operation in constant time. Enough jargon, for now, a piece of very important information to remember is OpenCV's classifier was trained with 24x24. So The smallest detected face from any image would be at least 24x24.

Opencv Haar Cascade Detection

Opencv has many pretrained classifiers, ie. face, eye, full/half body, smile, etc. We will learn to user frontal face classifier others will follow the same direction. Let's begin -

Step 1: Defining the detector/classifier


import cv2
# loading the haar cascade classifier from XML file
clf = cv2.CascadeClassifier('./data/haarcascade_frontalface_default.xml')

Step 2: Loading image and converting the image into grayscale

well, this is pretty obvious, right? We won't be needing any RGB or BGR (OpenCV format) as the classifier is trained on black and white features. 


# loading image
img = cv2.imread('./data/blog_post_face_detection.jpg')
print(img.shape) # image shape (height x width x number of channel)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

Step 3:  Detecting and marking the Region of Interest (RIO)

Detecting is easy, we will use OpenCV's detectMultiScale method on the classifier with some parameters. some useful parameters can be -

  • scaleFactor - which specifies how much the image will be reduced/resized. values < 1 will scale up the image and > 1 will scale down the image size. scale factor greater than 1.3 may cause performance issue
  • minNeighbour - this essentially indicates the quality of detection. Using rule of thumb 3 - 7 may serve great accuracy.
  • minSize - Objects smaller than the specified size will be ignored. We will specify (30, 30)

Now, we have to specify and draw the ROI. the detectMultiScale returns list of detected faces with their initial co-ordinate(x, y) and width, height. With this information, we can easily finalize our solution - 


# detect and draw rectangle
faces = clf.detectMultiScale(gray, 1.3, 5, (30, 30))
print(f"total face detected: {len(faces)}")
for (x,y,w,h) in faces:
    img = cv2.rectangle(img, (x, y),(x + w, y + h), (255, 0, 0), 2)
# displaying the image and cleaning up
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows() 

Output:
Detected 29 faces with 1 false positive.

opencv haar cascade output


Face Detection with Dlib HOG(Histogram of Oriented Gradients)

The idea of HOG descriptor is to create a vector of features so that the vector can be feed into a classification algorithm like SVM to predict the result. to calculate the HOG descriptor we need to calculate the gradients of x-axis and y-axis using Sobel kernel.

The code for Dlib face detector is pretty similar so I am going to write the code in one go... 


import cv2
import dlib

# loading the haar cascade classifier from XML file
detector = dlib.get_frontal_face_detector()

# loading image
img = cv2.imread('./data/blog_post_face_detection.jpg')
faces = detector(img, 1)

for face in faces:
    x1, y1 = face.tl_corner().x, face.tl_corner().y
    x2, y2 = face.br_corner().x, face.br_corner().y
    cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 1)

# displaying the image and cleaning up
cv2.imshow(f'face detected: {len(faces)}',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Output:
Detected 28 faces with 0 false positive.

dlib hog output