Face Spoofing Detection in Python
By: Vardan Agarwal
Tags: Artificial Intelligence, Computer Vision, Machine Learning, Data Science, Programming

Face Spoofing Detection in Python

Learn to detect if the face in front of the camera is a real person or a fake photograph or phone screen in Python.

Photo by NeONBRAND on Unsplash

Imagine if you are have applied face lock on your phone and your friend takes it and opens a photograph of you on his phone and shows it and your phone unlocks. To prevent these thoughts from becoming a reality we can use face spoofing techniques to find out if the face is a real person or merely a printed photograph or a picture of his on a digital device. It is also known as liveliness detection or replay attack detection. In this article, I will be covering a technique provided by Costa et al. in their paper, “Image-Based Object Spoofing Detection” whose code they have open-sourced as well. We will also make a change to make it better.

Method Overview

Their approach is to use different colorspaces like YCrCb and CIE L*u*v* and create histograms in these channels. Normal RGB colorspace is not used because the correlation between the red, green, and blue channels means that it obstructs separation between luminance and chrominance which is essential in spoofing attacks. In the paper they discussed the mathematics of converting RGB to YCrCb and CIE L*u*v*, however, we do not need to that to do that here as there are already predefined functions in OpenCV to do that. The histograms are concatenated into a feature vector FV = (Y, Cr, Cb, L, u, v) of size 1536 that is passed as input to an extra tree classifier for training purposes. They not only tested their method on faces but also on real and printed cork stoppers of wine bottles.

Requirements

To use the pre-trained model we require Sklearn version 0.19.1 as the model was trained using it and due to some depreciations, the current version 0.23.1 does not run it. Other than that we would need OpenCV to use the webcam or handle images and for changing the color channels.

#Using pip

pip install opencv-python

pip install scikit-learn==0.19.1 #Using conda

conda install -c conda-forge opencv

conda install -c anaconda scikit-learn==0.19.1

Code

In their open-sourced implementation available here on GitHub, they have used Haar cascades to detect faces. However, Haar cascades generally do not provide the best accuracies along with producing a lot of false positives. So instead of using that we will be using a Caffe module of OpenCV’s DNN module which provides much better results as can be seen in the article attached below which you can read to know more about it in detail.

You can download the required models for face detection from my GitHub repository.

import cv2

import numpy as np modelFile = "models/res10_300x300_ssd_iter_140000.caffemodel"

configFile = "models/deploy.prototxt.txt"

net = cv2.dnn.readNetFromCaffe(configFile, modelFile) img = cv2.imread('test.jpg')

h, w = img.shape[:2]

blob = cv2.dnn.blobFromImage(cv2.resize(img, (300, 300)), 1.0,

(300, 300), (104.0, 117.0, 123.0))

net.setInput(blob)

faces = net.forward() #to draw faces on image

for i in range(faces.shape[2]):

confidence = faces[0, 0, i, 2]

if confidence > 0.5:

box = faces[0, 0, i, 3:7] * np.array([w, h, w, h])

(x, y, x1, y1) = box.astype("int")

cv2.rectangle(img, (x, y), (x1, y1), (0, 0, 255), 2)

Load the network using cv2.dnn.readNetFromCaffe and pass the model's layers and weights as its arguments. It performs best on images resized to 300x300 and returns normalized coordinates which can then be estimated to the original size of the image.

After recognizing the face, that region of interest is extracted and converted to the required colorspaces. Histograms are calculated and concatenated together as required by the model. You can download the required model from here. The model predicts whether the face is live or a photo. The model is trained on a replay attack database which contains 1300 videos of 50 clients under different lighting conditions. It has both printed photos and faces on digital devices for the attacks of the clients. Below you can find the full code which takes input from a webcam.

From lines 5 to 11, we calculate the histogram of the image and normalize it to cover the range of 0–255. Then from lines 13–41, we find the faces in the images as explained above using OpenCV’s DNN module. From lines 42 to 53 the region of interest, i.e. the face area is extracted and the converted to YCrCb and Luv from BGR (OpenCV uses BGR instead of RGB) and then histograms are calculated, followed by their concatenation to make a feature vector which we will pass to our extra trees model. Finally, then we predict the probability of whether it is genuine or fake and the threshold for real is set to 0.7. The required text along with the bounding box is drawn on the image and the result is shown.