In the last article, we learned how to install and configure OpenCV and Python, and then wrote some code to play around with face detection. Now we’re going to take the next step, which is to create a facial recognition program, which is not just to detect but to recognize who the person is.

Let’s do face recognition

To create a face recognition program, we first need to train a recognizer with pre-cropped, annotated photos of faces. For example, our recognizer needs to recognize two people, one with ID 1 and the other with ID 2, so in the data set, all photos of person 1 will have ID 1 and person 2. We then use these data set photos to train the recognizer to identify person 1 from a video.

We divided the tasks into three parts:

  1. Creating a data set
  2. training
  3. identify

In this article, we will try to write a program to generate a dataset.

Generating data set

Let’s write a data set generation script.

Start by opening up our Python environment, whether it’s an IDE like Pycharm or a simple notepad. What you need to prepare in advance is to put haarcascade_frontalface_default. XML in the directory. We also used this XML file in the last article, which is the one that comes with OpenCV.

Next, use CV2 to get camera data and XML files:

import cv2
cam = cv2.VideoCapture(0)
detector=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')Copy the code

For our data set, we need to take some sample photos of faces from the camera, of course, only the same person. The program then adds ids to the sample photos and saves them in a folder called dataSet.

Let’s create a dataSet folder in the same directory as the py script. In order not to confuse different photos of faces, we need to have a naming convention for the photos.

For example, the naming rule is user. [ID].[SampleNumber].jpg. If it’s the tenth photo of person 2, we can name it user.2.10.jpg.

Why define this format? Because of this, when loading the photo training, we can simply determine the user’s face photo by the file name of the photo.

Next, we try a simpler approach, using shell input to get the id of the person and initialize the calculator variable to store the number of examples of the person.

Id = raw_input('enter your id: ')
sampleNum = 0Copy the code

Then we added a main loop in which we entered 20 examples from the video stream and saved them all to the dataSet folder we had created.

This is the version of the code I wrote earlier for face detection:

while True: Ret, img = cap. The read () gray. = cv2 cvtColor (img, cv2. COLOR_BGR2GRAY) faces = detector. DetectMultiScale (gray, 1.3, 5) for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) cv2.imshow('frame', img) if cv2.waitKey(1) & 0xFF == ord('q'): breakCopy the code

Now let’s transform it into a dataset generator:

while True: Ret, img = cap. The read () gray. = cv2 cvtColor (img, cv2. COLOR_BGR2GRAY) faces = detector. DetectMultiScale (gray, 1.3, 5) for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), Cv2. imwrite("dataSet/user." + STR (Id) + '.' + STR (sampleNum) + ".jpg", gray[y:y + h, x:x + w]) cv2.imshow('frame', img) if cv2.waitKey(1) & 0xFF == ord('q'): breakCopy the code

We added two lines of code to count the examples and save the face photo as JPG according to our naming rules.

One notable feature is gray[y: y + h, x: x + W]. Here, we treat a grayscale image as a two-dimensional array (or two-dimensional vector), and then use Python [] to intercept the face region detected by OpenCV.

But such code would quickly generate many photos in a second, say 20. We don’t want it to be that fast, we need better material, like photos from different angles, in that case, slower.

To slow things down, we need to increase the lag between takes. At the same time, we don’t need too much material, just 20.

while True: Ret, img = cap. The read () gray. = cv2 cvtColor (img, cv2. COLOR_BGR2GRAY) faces = detector. DetectMultiScale (gray, 1.3, 5) for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), Cv2. imwrite("dataSet/User." + STR (Id) + '.' + STR (sampleNum) + ".jpg", gray[y:y + h, x:x + w]) # cv2.imshow('frame', img) # delay cv2.waitKey(100) &0xff == ord('q'): Elif sampleNum > 20: breakCopy the code

Ok, moving on, now the code will delay 100 milliseconds between shots, 100 milliseconds is enough for us to move the Angle of our face (add more if not longer). Also, it stopped after 20 shots.

Finally, remember to release resources:

cap.release()
cv2.destroyAllWindows()Copy the code

Release the complete code:

import cv2 detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') cap = cv2.VideoCapture(0) sampleNum =  0 Id = raw_input('enter your id: ') while True: Ret, img = cap. The read () gray. = cv2 cvtColor (img, cv2. COLOR_BGR2GRAY) faces = detector. DetectMultiScale (gray, 1.3, 5) for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) # incrementing sample number sampleNum = sampleNum + 1 # saving the captured face in the dataset folder cv2.imwrite("dataSet/User." + str(Id) + '.' + str(sampleNum) + ".jpg", gray[y:y + h, x:x + w]) # cv2.imshow('frame', img) # wait for 100 miliseconds if cv2.waitKey(100) & 0xFF == ord('q'): break # break if the sample number is morethan 20 elif sampleNum > 20: break cap.release() cv2.destroyAllWindows()Copy the code

Generate results

As shown, a bunch of training materials have been generated.

This first

In the original text, please point out if there is anything wrong, pay more attention to fried fish.