OpenCV - Face recognition using Haar Cascade Classifiers

wordcloud

1. Haar Cascade Classifiers

Haar Cascade is a machine learning object detection algorithm proposed by Paul Viola and Michael Jones in their paper “Rapid Object Detection using a Boosted Cascade of Simple Features” in 2001. More information can be found on how a cascade classifier works here. OpenCV offers pre-trained Haar cascade algorithms organized into categories such as face, eye, smile, upperbody, lowerbody, etc. Haar cascade classifiers can be downloaded from they github repository.

We are going to attempt to use Haar cascade classifiers to detect the following:

  • Cat face
  • Human face
  • Eye

Select relevant classifiers from the link above, or just download the zip file from https://go.allika.eu.org/HaarCascadeClassifiers

2. Face detection in an image

Cat face detection

Here is an image of my cat sitting on a wall. Let's attempt to detect its face from the image.

Cat on a wall
In [1]:
# Importing libraries
import cv2
from matplotlib import pyplot as plt
from PIL import Image

OpenCV provides an imshow() function to display images, however, they are displayed in a seperate window and not inline. We can use matplotlib or pillow to display images inline, but we need to convert an OpenCV image from BGR to RGB first. Let's write functions to do that to save time.

In [2]:
# A function to display an OpenCV image using matplotlib
def plot_cv_image(img):
    plt.figure(figsize=(20,10))
    plt.imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
    plt.show()
    return None

# A function to display an OpenCV image using pillow
def pillow_cv_image(img):
    return Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
In [3]:
# Path to Haar Cascade classifier
haar_classifier="../../files/ml/003/haarcascade_frontalcatface.xml"
# Declaring cascade classifier
haar_cascade=cv2.CascadeClassifier(haar_classifier)
# Reading the input image
cv_img=cv2.imread("../../images/ml/003/001.jpg")
# Convertng to grayscale before classifying
cv_gray=cv2.cvtColor(cv_img,cv2.COLOR_BGR2GRAY)
# Detect cat faces using the Haar classifier
faces=haar_cascade.detectMultiScale(cv_gray,scaleFactor=1.3,minNeighbors=3)
# Display the number of faces detected
print(len(faces))
1
In [4]:
# Draw a rectangle around the detected face
for (x,y,w,h) in faces:
    cv2.rectangle(cv_img,(x,y),(x+w,y+h),color=(255,0,0),thickness=2)
In [5]:
# Display the output image using matplotlib
plot_cv_image(cv_img)
No description has been provided for this image
In [6]:
# Display the output image using pillow
pillow_cv_image(cv_img)
Out[6]:
No description has been provided for this image

Multiple cat faces detection in an image

Let's try to detect cat faces from the following image of kittens

Kitten
In [7]:
# Reading the input image
cv_img=cv2.imread("../../images/ml/003/002.jpg")
# Convertng to grayscale before classifying
cv_gray=cv2.cvtColor(cv_img,cv2.COLOR_BGR2GRAY)
# Detect cat faces using the Haar classifier
faces=haar_cascade.detectMultiScale(cv_gray,scaleFactor=1.3,minNeighbors=3)
# Display the number of faces detected
print(len(faces))
3
In [8]:
# Draw rectanges around detected faces
for (x,y,w,h) in faces:
    cv2.rectangle(cv_img,(x,y),(x+w,y+h),color=(255,0,0),thickness=2)
# Display the output image using pillow
plot_cv_image(cv_img)
No description has been provided for this image

Detect Human Faces in an Image

Human faces can be detected using haarcascade_frontalface_default.xml classifier file. Let's attempt to detect human faces from the following poster.

Rational Thinking poster
In [9]:
# Path to Haar Cascade classifier
haar_classifier="../../files/ml/003/haarcascade_frontalface_default.xml"
# Declaring cascade classifier
haar_cascade=cv2.CascadeClassifier(haar_classifier)
# Reading the input image
cv_img=cv2.imread("../../images/ml/003/003.jpg")
# Convertng to grayscale before classifying
cv_gray=cv2.cvtColor(cv_img,cv2.COLOR_BGR2GRAY)
# Detect cat faces using the Haar classifier
faces=haar_cascade.detectMultiScale(cv_gray,scaleFactor=1.3,minNeighbors=3)
# Display the number of faces detected
print(len(faces))
10
In [10]:
# Draw rectanges around detected faces
for (x,y,w,h) in faces:
    cv2.rectangle(cv_img,(x,y),(x+w,y+h),color=(255,0,0),thickness=2)
# Display the output image using pillow
plot_cv_image(cv_img)
No description has been provided for this image

[^top]

3. Face detection in a video

We are going to detect faces in the video https://go.allika.eu.org/FaceDetection and save the output in a video file.

In [11]:
# Path to Haar Cascade classifier
haar_classifier="../../files/ml/003/haarcascade_frontalface_default.xml"
# Declaring cascade classifier
haar_cascade=cv2.CascadeClassifier(haar_classifier)
# Input video
input_video=cv2.VideoCapture("https://go.allika.eu.org/FaceDetection")

if input_video.isOpened():
    # Get input video properties
    width=int(input_video.get(cv2.CAP_PROP_FRAME_WIDTH))
    height=int(input_video.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fps=int(input_video.get(cv2.CAP_PROP_FPS))
    print("Video size: {}x{}\nFrame rate: {}FPS".format(width,height,fps))
    # Defining output object
    output_video=cv2.VideoWriter("../../files/ml/003/face_detection.mp4", # Output file
                                cv2.VideoWriter_fourcc(*'X264'), # FOURCC codec
                                fps, # Frame rate
                                (width,height)) # video size
    while True:
        flag,frame=input_video.read() # reading input video frames
        if flag: # Process only if frame is read successfully
            gray_frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) # converting frames to grayscale
            faces=haar_cascade.detectMultiScale(gray_frame,scaleFactor=1.3,minNeighbors=3) # face detection
            # Drawing rectangles around faces
            for (x,y,w,h) in faces:
                cv2.rectangle(frame,(x,y),(x+w,y+h),color=(255,0,0),thickness=2)
            # write frame to output
            output_video.write(frame)
        else:
            break
input_video.release() # Release VideoCapture object (input file)
output_video.release() # Release VideoCapture object (output file)
cv2.destroyAllWindows() # close all display windows
Video size: 500x300
Frame rate: 30FPS

Following is the video output.

[^top]

4. Eye detection in a video

Eye detection works the same way as face detection, except that we will use the Haar cascade classifier trained for eye recognition instead.

In [12]:
# Path to Haar Cascade classifier for eye detection
haar_classifier="../../files/ml/003/haarcascade_eye.xml"
# Declaring cascade classifier
haar_cascade=cv2.CascadeClassifier(haar_classifier)
# Input video
input_video=cv2.VideoCapture("https://go.allika.eu.org/FaceDetection")

if input_video.isOpened():
    # Get input video properties
    width=int(input_video.get(cv2.CAP_PROP_FRAME_WIDTH))
    height=int(input_video.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fps=int(input_video.get(cv2.CAP_PROP_FPS))
    print("Video size: {}x{} pixels\nFrame rate: {} FPS".format(width,height,fps))
    # Defining output object
    output_video=cv2.VideoWriter("../../files/ml/003/eye_detection.mp4", # Output file
                                cv2.VideoWriter_fourcc(*'X264'), # FOURCC codec
                                fps, # Frame rate
                                (width,height)) # video size
    while True:
        flag,frame=input_video.read() # reading input video frames
        if flag: # Process only if frame is read successfully
            gray_frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) # converting frames to grayscale
            eyes=haar_cascade.detectMultiScale(gray_frame,scaleFactor=1.3,minNeighbors=3) # eye detection
            # Drawing rectangles around eyes
            for (x,y,w,h) in eyes:
                cv2.rectangle(frame,(x,y),(x+w,y+h),color=(0,255,0),thickness=2)
            # write frame to output
            output_video.write(frame)
        else:
            break
input_video.release() # Release VideoCapture object (input file)
output_video.release() # Release VideoCapture object (output file)
cv2.destroyAllWindows() # close all display windows
Video size: 500x300 pixels
Frame rate: 30 FPS

Following is the video output:

[^top]

5. Face and Eye detection together in a video

Let's combine face recognition with eye detection. However, in this case, we will attempt to detect eyes only within faces. We first detect faces and then detect eyes in them.

In [13]:
# Path to Haar Cascade classifiers
haar_classifier_face="../../files/ml/003/haarcascade_frontalface_default.xml"
haar_classifier_eye="../../files/ml/003/haarcascade_eye.xml"
# Declaring cascade classifiers
haar_cascade_face=cv2.CascadeClassifier(haar_classifier_face)
haar_cascade_eye=cv2.CascadeClassifier(haar_classifier_eye)
# Input video
input_video=cv2.VideoCapture("https://go.allika.eu.org/FaceDetection")

if input_video.isOpened():
    # Get input video properties
    width=int(input_video.get(cv2.CAP_PROP_FRAME_WIDTH))
    height=int(input_video.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fps=int(input_video.get(cv2.CAP_PROP_FPS))
    print("Video size: {}x{} pixels\nFrame rate: {} FPS".format(width,height,fps))
    # Defining output object
    output_video=cv2.VideoWriter("../../files/ml/003/face_eye_detection.mp4", # Output file
                                cv2.VideoWriter_fourcc(*'X264'), # FOURCC codec
                                fps, # Frame rate
                                (width,height)) # video size
    while True:
        flag,frame=input_video.read() # reading input video frames
        if flag: # Process only if frame is read successfully
            gray_frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) # converting frames to grayscale
            faces=haar_cascade_face.detectMultiScale(gray_frame,scaleFactor=1.3,minNeighbors=3) # face detection
            # Eye detection and blue rectangles around faces
            for (x,y,w,h) in faces:
                cv2.rectangle(frame,(x,y),(x+w,y+h),color=(255,0,0),thickness=2)
                # Extract each face from the frame
                face=frame[y:y+h,x:x+w]
                # Convert face to grayscale for eye detection
                gray_face=gray_frame[y:y+h,x:x+w]
                # Eye detection using default parameters i.e. 1.1 , 3
                eyes=haar_cascade_eye.detectMultiScale(gray_face) 
                # Green rectangles around eyes
                for (ex,ey,ew,eh) in eyes:
                    cv2.rectangle(face,(ex,ey),(ex+ew,ey+eh),color=(0,255,0),thickness=2)
            # write frame to output
            output_video.write(frame)
        else:
            break
input_video.release() # Release VideoCapture object (input file)
output_video.release() # Release VideoCapture object (output file)
cv2.destroyAllWindows() # close all display windows
Video size: 500x300 pixels
Frame rate: 30 FPS

Following is the video output:

[^top]

Last updated 2020-12-16 17:16:50.874422 IST

Comments