Face Detection with OpenCV (for complete Dummies)

This is a very dumb and straightforward tutorial that is meant to be a complete newbie intro into face detection. I’ll be using OpenCV for this, and python for simplicity, however if you want to scale you might want to rewrite this in C++. Python is great for prototyping so I’ll stick with this.

Install Dependencies

You can grab opencv-python from pypi - this is an unoptimised version that works on CPU - more than enough for prototyping.

Write Code

First, import OpenCV and load the image you want to work with, optionally resizing it. You need to grayscale the image before applying further classification.

import cv2 as cv

img1 = cv.imread("band-small-faces.jpg")

# resize if needed
# img2 = cv.resize(img1, None, fx=0.3, fy=0.3, interpolation=cv.INTER_CUBIC)
img2 = img1  # not resizing in this case
img3 = cv.cvtColor(img2, cv.COLOR_BGR2GRAY)

This is the image provided as input:

band-small-faces

Then, you need something called a Haar classifier that does the magic:

haar_cascade_face = cv.CascadeClassifier("./data/haarcascades/haarcascade_frontalface_default.xml")

As an input it needs a model to work with. I’m passing a model that detects frontal faces. I’ve attached available models for you to download (apparently you need to create data/haarcascases folder where your python script is).

If you get an error similar to

cv2.error: OpenCV(4.5.5) ...opencv-python\opencv-python\opencv\modules\objdetect\src\cascadedetect.cpp:1689: error: (-215:Assertion failed) !empty() in function 'cv::CascadeClassifier::detectMultiScale'

it usually means that path to the xml is invalid (thanks for useful messages!).

And to display model results:

for (x, y, w, h) in faces_rects:
    cv.rectangle(img2, (x, y), (x + w, y + h), (0, 255, 0), 3)

cv.imshow("Display", img2)
k = cv.waitKey(0)

image-20220323155153397

As you can see, most of the faces were detected! Last person’s leg looks like a face (you need to play with model parameters to rule this out). Last face wasn’t detected because it’s not frontal! Maybe use another model if you need to detect more.

Same way you can detect other things with OpenCV, just supply another pre-trained model. For instance, face expressions, eyes, eyeglasses, bodies, plate numbers etc.

Thanks! You can always email me or use contact form for more questions/comments etc.