Face Recognition using OpenCV – Part 2

Face Detection and Face Recognition using OpenCV – training

Hello everyone, this is part two of the tutorial face recognition using OpenCV. In part one of the tutorial, we discussed How to set up virtualenv and install necessary dependencies. To get a general idea of what face recognition and face detection is and to follow along with the tutorial, I advise you to check out part one of the tutorial series first if you haven’t already. The part two of the series is titled, “Face Detection and Face Recognition using OpenCV – training”.  In this part of the tutorial, we are going to focus on how to write the necessary code implementation for recording and training the face recognition program. We can further divide this part into:

  1. Create database for face recognition
  2. Record faces
  3. Train Recognizer

Create Database for face recognition

We are going to first create a database which stores the name of the corresponding faces. We will be using SQLite 3 for this purpose. Make a file named create_database.py in the working directory and copy paste the code below:

import sqlite3

conn = sqlite3.connect('database.db')

c = conn.cursor()

sql = """
DROP TABLE IF EXISTS users;
CREATE TABLE users (
           id integer unique primary key autoincrement,
           name text
);
"""
c.executescript(sql)

conn.commit()

conn.close()

Run the python script using the command python3 create_database.pyThis will create a database with filename database.db on the current directory. The database contains a table named users with two columns id and name. Once the database is created, you can use DB Browser for SQLite to view the table structure as well as data and it is going to look something like:

DB Browser for SQLite, OpenCV

Record Faces

Now, we are going to prepare the dataset for face recognition. We will be using haarcascade_frontalface_default.xml file provided in the opencv/data/haarcascades directory of the opencv repo in github. Download the file and place it in the working directory. After that, make a file named record_face.py in the working directory and copy paste the code below:

import cv2
import numpy as np 
import sqlite3
import os

conn = sqlite3.connect('database.db')
if not os.path.exists('./dataset'):
    os.makedirs('./dataset')

c = conn.cursor()

face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

cap = cv2.VideoCapture(0)

uname = input("Enter your name: ")

c.execute('INSERT INTO users (name) VALUES (?)', (uname,))

uid = c.lastrowid

sampleNum = 0

while True:
  ret, img = cap.read()
  gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  faces = face_cascade.detectMultiScale(gray, 1.3, 5)
  for (x,y,w,h) in faces:
    sampleNum = sampleNum+1
    cv2.imwrite("dataset/User."+str(uid)+"."+str(sampleNum)+".jpg",gray[y:y+h,x:x+w])
    cv2.rectangle(img, (x,y), (x+w, y+h), (255,0,0), 2)
    cv2.waitKey(100)
  cv2.imshow('img',img)
  cv2.waitKey(1);
  if sampleNum > 20:
    break
cap.release()

conn.commit()

conn.close()
cv2.destroyAllWindows()

The code above, when run, will ask you to enter the name for the face first. It will then use the haarcascade to find the face in the camera stream. It will look for 20 samples each at the interval of 100ms. Once 20 sample faces have been found, it stores the sample data in the ‘dataset’ directory inside the working directory. In the next step, we are going to train recognizer for face recognition.

Train Recognizer

OpenCV provides three methods of face recognition:

  • Eigenfaces
  • Fisherfaces
  • Local Binary Patterns Histograms (LBPH)

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.

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. The LBPH method is somewhat simpler, in the sense that we characterize each image in the dataset locally; and when a new unknown image is provided, we perform the same analysis on it and compare the result to each of the images in the dataset. We will be using the LBPH Face recognizer for our purpose. To do so, create a file named trainer.py in the working directory and copy paste the code below:

import os
import cv2
import numpy as np 
from PIL import Image

recognizer = cv2.face.LBPHFaceRecognizer_create()
path = 'dataset'
if not os.path.exists('./recognizer'):
    os.makedirs('./recognizer')

def getImagesWithID(path):
  imagePaths = [os.path.join(path,f) for f in os.listdir(path)]
  faces = []
  IDs = []
  for imagePath in imagePaths:
    faceImg = Image.open(imagePath).convert('L')
    faceNp = np.array(faceImg,'uint8')
    ID = int(os.path.split(imagePath)[-1].split('.')[1])
    faces.append(faceNp)
    IDs.append(ID)
    cv2.imshow("training",faceNp)
    cv2.waitKey(10)
  return np.array(IDs), faces

Ids, faces = getImagesWithID(path)
recognizer.train(faces,Ids)
recognizer.save('recognizer/trainingData.yml')
cv2.destroyAllWindows()

Run it using the command python3 trainer.pyThis will create a file named trainingData.yml inside the ‘recognizer’ directory inside the working directory.

This brings us to end of part 2 of the tutorial series, face recognition using OpenCV.  In this part of the series, we created 3 files:

  1. create_database.py: To create database and table
  2. record_face.py: To capture face images and record the corresponding name in the database.
  3. trainer.py: Use of OpenCV’s LBPH Face Recognizer to train the dataset that outputs trainingData.yml file that we’ll be using later in the tutorial for face recognition.

Our face recognition app is almost complete now. All we need to do is recognize the faces and fetch data from SQLite now which is on part 3 of the tutorial series.

 

About Aryal Bibek 16 Articles
Learner and practitioner of Machine Learning and Deep Learning. Ph.D. student at The University of Texas at El Paso. Admin and Founder at python36.com

15 Comments on Face Recognition using OpenCV – Part 2

  1. File “tester.py”, line 21, in
    face_recognizer=fr.train_classifier(faces,faceID)
    File “C:\python_work\Face Recognization\faceRecognition.py”, line 47, in train_classifier
    face_recognizer.train(faces,np.array(faceID))
    cv2.error: OpenCV(3.4.3) C:\projects\opencv-python\opencv_contrib\modules\face\src\lbph_faces.cpp:362: error: (-210:Unsupported format or combination of formats) Empty training data was given. You’ll need more than one sample to learn a model. in function ‘cv::face::LBPH::train’

    • Most probably, you didn’t run the record_face.py. The error tells empty training data was given. It is possible that you didn’t run record_face.py and in turn, no images were captured hence the error.

    • Haven’t tested it on windows yet but the idea is more or less similar. If you run into any problems, you can comment your error and I’ll try to solve it.

  2. Traceback (most recent call last):
    File “trainer.py”, line 25, in
    Ids, faces = getImagesWithID(path)
    File “trainer.py”, line 12, in getImagesWithID
    imagePaths = [os.path.join(path,f) for f in os.listdir(path)]
    FileNotFoundError: [Errno 2] No such file or directory: ‘dataset’

  3. Is there a reason on most computers/web browsers I use, all the code loses it’s indentation?

    I wiped windows and installed ubuntu, but the code all shows up with no indentation. I opened the page on a separate windows computer, both Chrome and IE – no luck. Everything has no indentation

    • It shouldn’t have been so. Anyways, the purpose of this tutorial is to teach you how to implement face recognition. Not just copy/paste the code. If you have understood the concepts, I’m sure you can format the indentations to make it work. Best of luck!

  4. When I try to run the record_face.py, I get the following:

    PS C:\Users\me\Google Drive\Projects\VSCode\pyFace> & C:/Users/me/Anaconda3/python.exe “c:/Users/me/Google Drive/Projects/VSCode/pyFace/record_face.py”
    cv2.error: OpenCV(3.4.3) C:\projects\opencv-python\opencv\modules\core\src\persistence_c.cpp:388: error: (-49:Unknown error code -49) Input file is empty in function ‘cvOpenFileStorage’

    The above exception was the direct cause of the following exception:

    Traceback (most recent call last):
    File “c:/Users/me/Google Drive/Projects/VSCode/pyFace/record_face.py”, line 9, in
    face_cascade = cv2.CascadeClassifier(‘haarcascade_frontalface_default.xml’)
    SystemError: returned a result with an error set

    I also get the following errors:

    E1101:Module ‘cv2’ has no ‘CascadeClassifier’ member
    E1101:Module ‘cv2’ has no ‘VideoCapture’ member
    E1101:Module ‘cv2’ has no ‘cvtColor’ member
    E1101:Module ‘cv2’ has no ‘COLOR_BGR2GRAY’ member
    etc…

  5. I installed opencv-contrib with the following:

    conda install -c michael_wild opencv-contrib

    because pip install opencv-contrib doesn’t work.

    I am still getting:

    recognizer = cv2.face.LBPHFaceRecognizer_create()
    AttributeError: module ‘cv2.cv2’ has no attribute ‘face’

    Any ideas?

  6. Hello Aryal.. i am facing this error ( os.makedirs(‘./dataset’)
    ^
    SyntaxError: expected an indented block) when running record_face.py
    i am using opencv 3.4.1. Please help me..

    • Hello Muzamnil,

      The error might be because of the IDE you are using. Some of the indentations might be spaces, while others are a tab. Please recheck. It should fix the problem. Thanks.

  7. thanks very much you have set a base for me and this tutorials have helped me win many competitions in my country thanks again

Leave a Reply

Your email address will not be published.




This site uses Akismet to reduce spam. Learn how your comment data is processed.