Face-Recognition Using OpenCv

Ayindrilla Maiti
Sep 3, 2018 · 5 min read

So what comes to your mind when you come across the term Face-Recognition? You have seen a face many times and kept it in your memory that this face belongs to this person, and then when you come across that known face you recollect from memory and recognize that face! so it is as simple as that!!

So how does your computer do that task??

Face/Image Recognition is a part of Computer Vision, and a process to identify and detect objects or attributes in a digital video or image.

We consider here Python’s OpenCv for accomplishing this task.

OpenCv is python’s library build to improve computer vision problem. OpenCv comes with its prebuilt FaceRecognizer class for face recognition.

The technique used here is pretty straightforward :

  1. Collecting image of the faces we want to identify.
  2. Training the model over the collected images.
  3. Testing the model by feeding it with different images of the faces.

Here the git link of the entire code https://github.com/ayindrilla-maiti/Face-Reco-openCV.

There are two main python files that are involved here. trainer.py and face detection.py.

The trainer is for training the model and face-recognition is for recognizing images using the training.

Here we will discuss how we are training the model.

Training Data

Usually, for training, a large number of images are used. A large number of images of a person is used so that the Recognizer can learn from the different looks of the person.

The training data is inside the training-data folder. The training data folder or the subject directory is named in the type slabel i.e first folder containing the images as s1, second as s2.

Preparing the Training Data

Two lists are taken for storing the images of faces and their labels. Since the subject directories start with ‘s’ we ignore the other non-relevant directories if any.

def prepare_training_data(data_folder_path):
faces = []
labels = []
for dir_name in dirs:
if not dir_name.startswith("s"):
continue;


Next we extract label number of subject from each dir_name.
Since the format of the dir_name is sLabel so removing
the s will give us the label:
label = int(dir_name.replace("s", ""))
subject_dir_path = data_folder_path + "/" + dir_name
subject_images_names = os.listdir(subject_dir_path)

Go through each image name, read image,
detect face and add face to list of faces:
for image_name in subject_images_names:

ignore system files like .DS_Store
if image_name.startswith("."):
continue;

Next build image path,sample image path = training-data/s1/1.pgm:
image_path = subject_dir_path + "/" + image_name
image = cv2.imread(image_path)cv2.imshow("Training on image...", cv2.resize(image, (400, 500)))
cv2.waitKey(100)
face, rect = detect_face(image)image = cv2.imread(image_path)cv2.imshow("Training on image...", cv2.resize(image, (400, 500))) cv2.waitKey(100)face, rect = detect_face(image)

Detecting Faces

First, the images are needed to be converted in grayscale as sometimes color information doesn’t help in identifying the edges and other important features.

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

Next, the OpenCv haarcascade classifiers is used. OpenCv comes with a set of pre-trained classifiers for face, eyes, smile. Also, you can create a classifier for your own objects. Haar cascades classifiers consist of XML files which contain a lot of features for a specific set of objects. The XML files are stored in –> opencv/data/haarcascade folder. In our case, we are using the haarcascade_frontalface_xml.

face_cascade = cv2.CascadeClassifier('opencv-files/haarcascade_frontalface_alt.xml')

Next, these XML features are used to detect the face in our image, so that is basically the Region of Image or ROI.

faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5);

here the parameters scaleFactor: It is for creating an image pyramid. An image pyramid is a multi-scale representation of the image so that it is scale-invariant i.e in simple word it could detect both small and large picture. Here the value 1.2 denotes that the image is reduced by 20% in each step.

minNeighbors: it denotes the minimum no. of neighboring rectangles. Haar classifier uses the concept of sliding window. In every image that is being used, Haar classifier creates small resizable rectangles within each object that are been detected. Among those objects, some are termed as false positives meaning they are not the actual object we want to detect. Thus to eliminate the false positives and to get the actual object comes to the concept of neighboring rectangles. It is that a rectangle is the neighbor of some other rectangles then that could be the actual object we want to detect.

Here is the issue that I encountered, that in some images that is used in training data the Region of Image(ROI) could not be identified using the haarcascade classifier, hence the variable faces can return null values and as a result, it throws an exception like :

OpenCV Error: Assertion failed (size.width>0 && size.height>0) in cv.resize, file .../opencv/modules/imgproc/src/resize.cpp, line 4044

at runtime. I have analyzed that this could be because it is not getting the ROI. so to identify the ROI cv2.selectROI() can be used. This enables the user to manually select the region of the image using a bounding box. Although this might not look like an optimized solution, I am still looking at how to do it better.

if (len(faces) == 0): print("No face detected") r = cv2.selectROI(gray) faces = r (x, y, w, h) = faces return gray[y:y + w, x:x + h], faces

Training Recognizer OpenCv has its built-in Recognizer class which can be easily used in the for face-recognizing. OpenCv has three algorithms for face recognition:

  • EigenFaces — cv2.face.createEigenFaceRecognizer()
  • FisherFaces — cv2.face.createFisherFaceRecognizer()
  • Local Binary Patterns Histogram(LBPH) — cv2.face.createLBPHFaceRecognizer()

All three methods perform the recognition by comparing the face to be recognized with some training set of known faces. In the training set, we supply the algorithm faces and tell it to which person they belong. When the algorithm is asked to recognize some unknown face, it uses the training set to make the recognition. Each of the three aforementioned methods uses the training set a bit differently. Eigenfaces and FisherFaces find a mathematical description of the most dominant features of the training set as a whole. LBPH analyzes each face in the training set separately and independently. Here LBPH recognizer is being used.

face_recognizer = cv2.face.LBPHFaceRecognizer_create()

Next, we train the recognizer for around 1 million steps and in each step store it in a trainer.yml file, which will be used for recognizing faces.

for t in range(100000):
face_recognizer.train(faces, np.array(labels))
face_recognizer.save('trainer/trainer.yml')

Recognize Images

Now after the training is completed run the face-recognizer.py. Remember to feed it the input image you want it to recognize.

test_img = cv2.imread("test-data/image9.jpg")

And again for some images, it fails to detect the ROI and for that, we are selecting it manually. Although am trying to do some better method for this, I will update again if I find any.

Okay, finally we are almost at the end of our mission where this face-recognizer correctly recognizes the image.

Now you might get an incorrect result, in that case, increasing the training data and again training the model will help, also the system is not 100% accurate I am working in it still and would always welcome feedback and contributions!

Thanks!


Originally published at ayindrilla.wordpress.com on September 3, 2018.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade