Face Detection Using Haar Features and AdaBoost with OpenCV
This article explains the principles and implementation of face detection based on statistical methods, detailing Haar feature types, integral image computation, feature normalization, cascade classifiers, and provides step‑by‑step OpenCV code examples for static images, eye detection, and real‑time webcam detection.
Face detection belongs to computer vision; early research focused on face recognition, but detecting faces in complex backgrounds has become an independent research direction.
Two main categories of face detection methods are introduced: knowledge‑based (using anatomical priors such as eyes, nose, mouth) and statistical (treating the face as a whole pixel matrix and learning patterns from large datasets). This article concentrates on the statistical approach, employing the AdaBoost algorithm together with Haar features to build a Haar classifier that distinguishes face from non‑face regions.
Algorithm Highlights
1.1 Haar Classifier Training Steps
Prepare face and non‑face sample sets.
Extract Haar features from the samples.
Use an integral image to accelerate Haar feature evaluation.
Train a strong classifier with AdaBoost to separate faces from non‑faces.
Combine strong classifiers in a cascade to improve accuracy.
Details of each step are discussed in later sections.
1.2 Limitations of Haar
Only detects face location, not identity.
Cannot perform liveness detection, posing security risks for applications like face‑based login.
Relies on traditional machine‑learning techniques rather than deep learning.
Haar Principle Analysis
2.1 Haar Features
Haar features consist of four types: edge, line, center, and diagonal. They are analogous to convolution kernels, extracting simple intensity patterns such as darker eyes or nose bridges compared to surrounding skin.
Examples of the three basic Haar feature categories are shown in the accompanying images.
2.2 Integral Image Construction
The integral image (summed‑area table) stores the cumulative sum of pixel values up to each location, allowing any rectangular region’s sum to be computed with only four array accesses, reducing the complexity to O(1).
2.3 Computing Haar Feature Values
After building the integral image, the sum of any rectangular region can be obtained quickly. Rotated Haar features use a tilted integral image, which is computed with similar recursive formulas.
2.4 Haar Feature Normalization
Because raw Haar values can have a large dynamic range, they are normalized using the mean and variance of the detection window, making the features more comparable across different scales.
2.5 Cascade Classifier
The cascade combines many weak classifiers (each based on a single Haar feature) into a strong classifier. Early stages contain few features to quickly reject non‑face windows, while later stages apply more features to the remaining candidates. This dramatically reduces computation.
Face Detection Examples
3.1 Basic Face Detection
Using OpenCV, a pre‑trained Haar cascade XML file can be loaded and applied to an image:
img = cv2.imread("Pic/1.jpg")
face_engine = cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_frontalface_default.xml')
faces = face_engine.detectMultiScale(img, scaleFactor=1.3, minNeighbors=5)
for (x, y, w, h) in faces:
img = cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()The resulting image shows bounding boxes around detected faces.
3.2 Face and Eye Detection
By first detecting faces and then restricting eye detection to the face region, computation is saved:
# Load cascades
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_eye.xml')
# Read image
img = cv2.imread('image3.png')
# Detect faces
faces = face_cascade.detectMultiScale(img, 1.3, 5)
for (x, y, w, h) in faces:
img = cv2.rectangle(img, (x, y), (x+w, y+h), (255,0,0), 2)
face_area = img[y:y+h, x:x+w]
eyes = eye_cascade.detectMultiScale(face_area)
for (ex, ey, ew, eh) in eyes:
cv2.rectangle(face_area, (ex, ey), (ex+ew, ey+eh), (0,255,0), 1)
cv2.imshow('img2', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('output.jpg', img)The output image displays both face and eye bounding boxes.
3.3 Real‑Time Detection with Webcam
For live detection, the webcam stream is processed frame‑by‑frame, applying the same cascades:
import cv2
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_eye.xml')
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
faces = face_cascade.detectMultiScale(frame, 1.3, 5)
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (255,0,0), 2)
face_area = frame[y:y+h, x:x+w]
eyes = eye_cascade.detectMultiScale(face_area)
for (ex, ey, ew, eh) in eyes:
cv2.rectangle(face_area, (ex, ey), (ex+ew, ey+eh), (0,255,0), 1)
cv2.imshow('frame2', frame)
if cv2.waitKey(5) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()This script shows live face and eye detection until the user presses 'q'.
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.