Face detection, seems like magic, yet it’s surprisingly simple. First of all install OpenCV. You can install it easily using the terminal or PowerShell with the python package manger called pip:
Linux users: sudo pip install opencv-python Powershell users: python -m pip install opencv-python
Face detection using OpenCV is easy as it already contains many pre-trained classifiers for face, eyes, smiles, etc.. For our future projects we will be using the face classifier. You can experiment with other classifiers as well. Or even try to write your own for custom detection.
For better face recognition you need to download the trained classifier XML file called haarcascade_frontalface_default.xml, which is available in OpenCv’s GitHub repository. Download or move it to the working directory of your face detection project.
To detect faces in still images:
import cv2
# Load the cascade
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# Read the input image
img = cv2.imread('test.jpg')
# Convert into grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Detect faces
faces = face_cascade.detectMultiScale(gray, 1.1, 4)
# Draw rectangle around the faces
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
# Display the output
cv2.imshow('img', img)
cv2.waitKey()
A few things to note:
- The image to be analysed must be called ‘test.jpg’ and in the working directory. Or you have to change the variable on line 6 to point to the image.
- The detection works only on grayscale images. Therefore we must convert the color image to grayscale. (line 8) Its important to only process grayscale images to reduce image processing time.
- detectMultiScale function (line 10) is used to detect the faces. It takes 3 arguments — the input image, scaleFactor and minNeighbours. scaleFactor specifies how much the image size is reduced with each scale. minNeighbours specifies how many neighbors each candidate rectangle should have to retain it. You can read about it in detail here. You may have to tweak these values to get the best results.
- faces contains a list of coordinates for the rectangular regions where faces were found. We use these coordinates to draw the rectangles in our image.
Now, to get this code to a point we can use for our projects we need to be able to detect faces in videos. As you know videos are made up of frames, which are still images. So the solution is to perform the face detection for each frame of a video. Here is the code:
import cv2
# Load the cascade
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# To capture video from webcam.
cap = cv2.VideoCapture(0)
# To use a video file as input
# cap = cv2.VideoCapture('filename.mp4')
while True:
# Read the frame
_, img = cap.read()
# Convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Detect the faces
faces = face_cascade.detectMultiScale(gray, 1.1, 4)
# Draw the rectangle around each face
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
# Display
cv2.imshow('img', img)
# Stop if escape key is pressed
k = cv2.waitKey(30) & 0xff
if k==27:
break
# Release the VideoCapture object
cap.release()
The only difference here is that we use an infinite loop to analyse each frame in the video. We use cap.read() to read each frame. The first value returned is a flag that indicates if the frame was read correctly. We don’t need it. The second value returned is the still frame on which we will be performing the detection. By changing the integer in the brackets of ‘cv2.VideoCapture(0)’ (line 8) we can select video input devices from those availble on the computer.
Thats it! This is how to achieve computer vision with webcams and a PC.