Face recognition is an easy task for humans. we are already given the more tutorials about face detection, mouth detection, nose detection, eyes detection. one to three day old babies are able to distinguish between known faces. So how hard could it be for a computer? It turns out we know little about human recognition to date. Are inner features (eyes, nose, mouth) or outer features (head shape, hairline) used for a successful face recognition? How do we analyze an image and how does the brain encode it?. our brain has specialized nerve cells responding to specific local features of a scene, such as lines, edges, angles or movement. Since we don’t see the world as scattered pieces, our visual cortex must somehow combine the different sources of information into useful patterns. Automatic face recognition is all about extracting those meaningful features from an image, putting them into a useful representation and performing some kind of classification on them.
Face recognition based on the geometric features of a face is probably the most intuitive approach to face recognition. One of the first automated face recognition systems was described. marker points (position of eyes, ears, nose, …) were used to build a feature vector (distance between the points, angle between them, …). The recognition was performed by calculating the euclidean distance between feature vectors of a probe and reference image. Such a method is robust against changes in illumination by its nature, but has a huge drawback: the accurate registration of the marker points is complicated, even with state of the art algorithms. A 22-dimensional feature vector was used and experiments on large datasets have shown, that geometrical features alone my not carry enough information for face recognition. A facial image is a point from a high-dimensional image space and a lower-dimensional representation is found, where classification becomes easy. The lower-dimensional subspace is found with Principal Component Analysis, which identifies the axes with maximum variance. While this kind of transformation is optimal from a reconstruction standpoint, it doesn’t take any class labels into account. Imagine a situation where the variance is generated from external sources, let it be light. The axes with maximum variance do not necessarily contain any discriminative information at all, hence a classification becomes impossible.
Recently, I wanted to perform Face Recognition using OpenCV in Python but sadly, I could not find any good resource for the same. So, after a few hours of work, I wrote my own face recognition program using OpenCV and Python. The actual code is less than 40 lines of python code, thanks to the terse syntax of python and now, I am sharing with you what I did.
The whole process can be divided in three major steps –
- The first step is to find a good database of faces with multiple images for each induvidual.
- The next step is to detect faces in the database images and use them to train the face recognizer.
- The last step is to test the face recognizer to recognize faces it was trained for.
Database
We will use this database by using 9 images of the
total 10 images of each individual in training our face recognizer and
the remaining single image of each individual to test our face
recognition algorithm.
Implementation
Now, we have an understanding of how our database looks like and it’s time to start programming the face recognition algorithm.Import the required modules
The first step is to import the required modules –cv2
– This is the OpenCV module and contains the functions for face detection and recognition.os
– This module will be used to maneuver with image and directory names. First, we will use this module to extract the image names in the database directory and then from these names we will extract the individual number, which will be used as a label for the face in that image.Image
– Since, the dataset images are in gif format and as of now, OpenCV does not support gif format, we will use Image module from PIL to read the image in grayscale format.numpy
– Our images will be stored in numpy arrays.- sys – System initialization to system commands
import numpy as np
import cv2, os
import sys
from PIL import Image
Load the face detection Cascade
The first step is to detect the face in each image. Once, we get the region of interest containing the face in the image, we will use it for training the recognizer. For the purpose of face detection, we will use the Haar Cascade provided by OpenCV. The haar cascades that come with OpenCV are located in the/data/haarcascades>
directory of your OpenCV installation. We will use haarcascade_frontalface_default.xml
for detecting the face. So, we load the cascade using the cv2.CascadeClassifier
function
which takes the path to the cascade xml file. I have copied the xml
file in the current working directory, so I have used the relative path.
In case, you cannot locate the haar cascade file on your computer, I
have included it in the zip file available for download at the bottom of
the post.
cascadePath = "haarcascade_frontalface_default.xml face_cascade = cv2.CascadeClassifier(cascadePath)
Create the Face Recognizer Object
The next step is creating the face recognizer object. The face recognizer object has functions likeFaceRecognizer.train
to train the recognizer and FaceRecognizer.predict
to recognize a face. OpenCV currently provides 3 face recognizers –- Eigenface Recognizer –
createEigenFaceRecognizer()
- Fisherface Recognizer –
createFisherFaceRecognizer()
- Local Binary Patterns Histograms Face Recognizer –
createLBPHFaceRecognizer()
recognizer = cv2.createBPHFaceRecognizer()
Create the function to prepare the training set
Now, we will define a functionget_images_and_labels
that
takes the absolute path to the image database as input argument and
returns tuple of 2 list, one containing the detected faces and the other
containing the corresponding label for that face. For example, if the
ith index in the list of faces represents the 5th individual in the
database, then the corresponding ith location in the list of labels has
value equal to 5.def get_images_and_labels(path): # Append all the absolute image paths in a list image_paths # We will not read the image with the .sad extension in the training set # Rather, we will use them to test our accuracy of the training - See image_paths = [os.path.join(path, f) for f in os.listdir(path) if not f.endswith('.sad')] # images will contains face images images = [] # labels will contains the label that is assigned to the image labels = [] for image_path in image_paths: # Read the image and convert to grayscale image_pil = Image.open(image_path).convert('L # Convert the image format into numpy array image = np.array(image_pil, 'uint8') # Get the label of the image nbr = int(os.path.split(image_path)[1].split(".")[0].replace("subject", "")) # Detect the face in the image faces = faceCascade.detectMultiScale(image) # If face is detected, append the face to images and the label to labels for (x, y, w, h) in faces: images.append(image[y: y + h, x: x + w]) labels.append(nbr)#sthash.wBCaaSGc.dpuf # return the images list and labels list return images, labels
In line 19, we are appending all the absolute path names of the database images in the list
Read the video from camera and detect the faces
images_path
. We, are not appending images with the .sad extension, as we will use them to test the accuracy of the recognizer. In line 21 and 23,
we declare 2 list – images and labels. These are 2 list, that I had
discussed in the previous paragraph that will be returned by the
recognizer. In the list images, we append the region of interest
containing the face and in the list labels, we append the corresponding
label for that face. From line 24 – 38, we loop around each image to detect the face in it and update our 2 lists. So, in line 26 – 28
we load the current image in a 2D numpy array image. We cannot read the
images directly using cv2.imread because as of now, OpenCV doesn’t
support gif format images and unfortunately, our database images are in
this format. So, we use the Image module from PIL to read the images in
grayscale format and convert them into numpy arrays which are compatible
with OpenCV. In** line 30, from the image name, we extract the individual number. This number will be the label for that face. **In line 32, we use CascadeClassifier.detectMultiScale
to detect faces in the image. Although, in most cases, we need to tune the CascadeClassifier.detectMultiScale
function
to correctly recognize faces in the image, but for sake of simplicity, I
am leaving this part to the default values. You can refer to this Real Python post for more insights on this. The CascadeClassifier.detectMultiScale
function returns a list of faces. For each face it returns a rectangle in the format (Top-Left x pixel value, Top-Left y pixel value, Width of rectangle, Height of rectangle.). In lines 34-38, we slice the ROI from the image and append it to the list images
and the corresponding label in the list labels
. Once, we are done with this loop, we return the 2 lists in the form of a tuple.Read the video from camera and detect the faces
cap = cv2.VideoCapture(0) while(True): ret, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.3, 5) for (x, y, w, h) in faces: cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2) roi_gray = gray[y:y+h, x:x+w] roi_color = image[y:y+h, x:x+w] face_file_name = "img.jpg" cv2.imwrite(face_file_name, roi_color)
Load the faces from image:
src = cv2.LoadImage("img.jpg", cv2.CV_LOAD_IMAGE_COLOR)
src0 = cv2.LoadImage("img0.jpg", cv2.CV_LOAD_IMAGE_COLOR)
Load the faces from image what you are given the input.Testing the face recognizer
sc0= cv2.CompareHist(src, src0, cv2.CV_COMP_BHATTACHARYYA) sc1= cv2.CompareHist(src, src1, cv2.CV_COMP_BHATTACHARYYA)In above each instruction compare the image faces with database faces. cv2.CompareHist will return value. If the value is ‘0’ then the face is detected correctly. the person names will display on image.
if sc0==0.0: cv2.putText(image, 'Raghava', (x, y), cv2.FONT_ITALIC, 1, (200,255,155),2) if sc1==0.0: cv2.putText(image, 'Abdul kalam Sir', (x, y), cv2.FONT_ITALIC, 1, (200,255,155),2)finally show the image with proper names
cv2.imshow("Face found" ,image)Finally the output shown like bellow video:
No comments:
Post a Comment