This face detection algorithm, introduced by Paul Viola and Michael Jones in their paper “Rapid Object Detection using a Boosted Cascade of Simple Features (2001),” was state-of-the-art for many years due to its simplicity and real-time capabilities. It uses 38 cascaded binary classifiers with over 6000 input features (e.g., line, edge, rectangle, center-surround). Initial classifiers are weak and used for early rejection of negative samples, while subsequent classifiers are stricter and handle more complex features. Each classifier processes only the image regions that pass the preceding one.
OpenCV provides pre-trained classifiers for different face poses.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ''' ''' import numpy as np import cv2 img = cv2.imread('../sample.jpg', 1) img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) face_detector = cv2.CascadeClassifier('/usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml') face_rects = face_detector.detectMultiScale(img_gray) for rect in face_rects: cv2.rectangle(img, (rect[0], rect[1]), (rect[0] + rect[2], rect[1] + rect[3]), (0, 0, 255), 2) cv2.imshow('face', img) key = cv2.waitKey(0) |
This classical feature-based detector, available in the DLib library, uses Histogram of Gradients (HoG) as a feature descriptor and a Support Vector Machine (SVM) classifier to identify faces. While efficient in real-time, it suffers in performance with rotated faces due to its lack of rotation invariance.
0 1 2 | ''' ''' face_detector = dlib.get_frontal_face_detector() face_rects = face_detector(img_gray, 0) |
This real-time object detection algorithm uses a single-stage approach, making it faster than two-stage detectors. By combining feature maps from various resolutions, it can detect both small and large faces simultaneously. The SSD face detector is included in OpenCV 3.3 and can be utilized with the DNN module.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | ''' ''' import numpy as np import cv2 img = cv2.imread('../sample.jpg', 1) height, width = img.shape[:2] model = 'opencv_face_detector_uint8.pb' config = 'opencv_face_detector.pbtxt' net = cv2.dnn.readNetFromTensorflow(model, config) blob = cv2.dnn.blobFromImage(img, 1.0, (300, 300), [104, 117, 123], False, False) net.setInput(blob) output = np.squeeze(net.forward()) for i in range(output.shape[0]): confidence = output[i, 2] if confidence > 0.5: top_x = int(output[i, 3] * width) top_y = int(output[i, 4] * height) bottom_x = int(output[i, 5] * width) bottom_y = int(output[i, 6] * height) cv2.rectangle(img, (top_x, top_y), (bottom_x, bottom_y), (0, 0, 255), 2) cv2.imshow('face', img) key = cv2.waitKey(0) cv2.destroyAllWindows() |
Developed by DLib’s creator, Davis E. King, this detector uses a CNN feature extractor followed by binary classification to detect faces. With a receptive field of 50x50 pixels, it performs well but requires faces slightly larger than these dimensions for detection.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | ''' ''' import numpy as np import dlib import cv2 img = cv2.imread('sample.jpg', 1) face_detector = dlib.cnn_face_detection_model_v1("mmod_human_face_detector.dat") face_rects = face_detector(img, 0) for rect in face_rects: cv2.rectangle(img, (rect.rect.left(), rect.rect.top()), (rect.rect.right(), rect.rect.bottom()), (0, 0, 255), 2) cv2.imshow('face', img) key = cv2.waitKey(0) |
MTCNN is a cascaded CNN-based face detector available as a Python package. It consists of three stages: P-Net for region proposals, R-Net for refinement, and O-Net for output. In addition to detecting faces, it also identifies key facial landmarks such as eyes, nose, and mouth.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | ''' ''' import mtcnn import cv2 img = cv2.imread('../sample.jpg', 1) face_detector = mtcnn.MTCNN() face_rects = face_detector.detect_faces(img) for rect in face_rects: if rect['confidence'] > 0.5: top_x = rect['box'][0] top_y = rect['box'][1] bottom_x = top_x + rect['box'][2] bottom_y = top_y + rect['box'][3] cv2.rectangle(img, (top_x, top_y), (bottom_x, bottom_y), (0, 0, 255), 2) cv2.imshow('face', img) key = cv2.waitKey(0) |
Figure 1: Face detection results using different detectors. Image source: Flickr.