Setup

Here is our layout

├── faceDataSet
├── haarcascade
│   ├── haarcascade_frontalface.xml
├── trainers
│   ├── savedTrainer.yml
├── clearData.py
├── faceDataCreator.py
├── trainer.py
├── faceDetector.py

First get the haarcascade data from here.

Requirements
OpenCv
Numpy
Pillow

Lets start with creating our data. We will create a program to take pictures of faces, then store them in faceDataSet. I will name my file faceDataCreator.py. The index is used to only take 20 pictures of one subject. Create an input in order to save a label to your image. Write the images to faceDataSet. You can show the frame but it is not necessary.

from cv2 import cv2
import os

currentPath = os.path.dirname(os.path.abspath(__file__))
detector=cv2.CascadeClassifier(currentPath+r'\haarcascade\haarcascade_frontalface.xml')

index = 0

camera = cv2.VideoCapture(0)
id=input('enter your id: ')
while True:
    ret, frame = camera.read()
    gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)

    faces = detector.detectMultiScale(gray, 
        scaleFactor=1.2, 
        minNeighbors=3, 
        minSize=(100, 100)
    )
    # print(faces)

    for (x,y,w,h) in faces:
        index=index+1
        cv2.imwrite("faceDataSet/personface-"+ id +'.'+ str(index) + ".jpg", gray[y:y+h,x:x+w])
        
        cv2.rectangle(frame,(x,y),(x+w,y+h),(0,250,0),2)
        cv2.imshow('current',frame[y:y+h,x:x+w])
        
        cv2.waitKey(1)

    #change to higher number if needed
    if index>19:
        camera.release()
        cv2.destroyAllWindows()
        exit()


You can run this file multiple times, create a new id for each new face you want to add to the folder. Running it with the same id will overwrite the current picture. If you need to delete the files in the folder use the code below.

import os
import glob

files = glob.glob('faceDataSet/*')
for f in files:
    print(f)
    os.remove(f)

Next, we will create our trainer. This trainer will take in data from the pictures taken from faceDataCreator.py. The trainer is what will be learning in order to recognize faces. Create a file called trainer.py. Classify the cascade and create your recognizer. I will use a function to create a list of images and labels. Next train and save the recognizer. Include cv2.imshow() in the for loop if you want to see which picture the program is currently on.

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

currentPath = os.path.dirname(os.path.abspath(__file__))
print(currentPath)

faceCascade = cv2.CascadeClassifier(currentPath+r"\haarcascade\haarcascade_frontalface.xml")
recognizer = cv2.face.LBPHFaceRecognizer_create() 

faceDataPath = currentPath+r'\faceDataSet'


def returnImageLabel(path):
    images = list()
    labels = list()
    image_paths = [os.path.join(path, i) for i in os.listdir(path)]

    for image_path in image_paths:
         # convert to grayscale (L converts to gray scale), then convert image format to numpy
        image = Image.open(image_path).convert('L')
        image = np.array(image, 'uint8')

        currentLabel = int(os.path.split(image_path)[1].split(".")[0].replace("personface-", ""))
        print(currentLabel)

         # detect the current faces
        faces = faceCascade.detectMultiScale(image)


        # append detected faces
        for (x, y, w, h) in faces:
            images.append(image[y: y + h, x: x + w])
            labels.append(currentLabel)
            


    return images, labels


images, labels = returnImageLabel(faceDataPath)
recognizer.train(images, np.array(labels))
recognizer.save(currentPath+r'\trainers\savedTrainer.yml')

The final file will be faceDetector.py. In this file we will launch the camera, recognize and predict who it is, draw a rectangle around the face and name who it is.

import os
from cv2 import cv2
import numpy as np


currentPath = os.path.dirname(os.path.abspath(__file__))
print(currentPath)


faceRecog = cv2.face.LBPHFaceRecognizer_create()
faceRecog.read(currentPath+r'\trainers\savedTrainer.yml')


faceCascade = cv2.CascadeClassifier(currentPath+r'\haarcascade\haarcascade_frontalface.xml')



cam = cv2.VideoCapture(0)
font = cv2.FONT_HERSHEY_SIMPLEX


while True:
    ret, frame =cam.read()
    
    gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)

    faces = faceCascade.detectMultiScale(gray, 
      scaleFactor=1.2, 
      minNeighbors=3, 
      minSize=(100, 100)
      )

    for(x,y,w,h) in faces:

        #create prediction
        predictedPerson, conf = faceRecog.predict(gray[y:y+h,x:x+w])

        ##create rectangle
        cv2.rectangle(frame,(x,y),(x+w,y+h),(225,0,0),2)
        
        #change this to your id and name. Create a new if statement for new faces.
        if(predictedPerson==1):
          predictedPerson='Abhilash'


        cv2.putText(frame,str(predictedPerson), (x,y+h),font, 1.0, (255,0,0)) 
        
        cv2.imshow('Video',frame)
        cv2.waitKey(10)
Categories: Python