OpenCV Training
These are my notes based on Jason Dsouza’s excellent OpenCV video course.
Installation
python3 -m pip install opencv-contrib-python
Setup
We assume you have a the following folders:
train
|- Name A
|- Name B
|- ...etc
validate
|- Name A
|- Name B
|- ...etc
Each sub-folder should have multiple images in them for training and verifying.
Make sure you have downloaded the face detection cascade data from opencv detection.
Training
import cv2 as cv
import os
import numpy as np
DIR = "train"
people = []
for i in os.listdir(DIR):
people.append(i)
cascade_file = 'haarcascade_frontalface_default.xml'
haar_cascade = cv.CascadeClassifier(cascade_file)
def detect_face(img):
return haar_cascade.detectMultiScale(img,
scaleFactor=1.1, minNeighbors=4)
def create_train():
features = []
labels = []
for person in people:
path = os.path.join(DIR, person)
label = people.index(person)
for img in os.listdir(path):
img_path = os.path.join(path, img)
img_array = cv.imread(img_path)
gray = cv.cvtColor(img_array, cv.COLOR_BGR2GRAY)
for (x,y,w,h) in faces_rect:
faces_roi = gray[y:y+h, x:x+w]
features.append(faces_roi)
labels.append(label)
return np.array(features, dtype='object'), np.array(labels)
features, labels = create_train()
# Train the recognizer on the features list and labels list
face_recogniser = cv.face.LBPHFaceRecognizer_create()
face_recogniser.train(features, labels)
face_recogniser.save('face-trained.yml')
Recognition
In this code, we use our trained face recognizer to determine if a detected face is who we expect it to be.
import numpy as np
import cv2 as cv
import os
DIR = "train"
people = []
for i in os.listdir(DIR):
people.append(i)
# Load model
face_recognizer = cv.face.LBPHFaceRecognizer_create()
face_recognizer.read('3-faces/face-trained.yml')
# Load a face
img = cv.imread('validate/elton_john/1.jpg')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# Detect face
cascade_file = 'haarcascade_frontalface_default.xml'
haar_cascade = cv.CascadeClassifier(cascade_file)
faces_rect = haar_cascade.detectMultiScale(gray, 1.1, 4)
for (x,y,w,h) in faces_rect:
faces_roi = gray[y:y+h, x:x+w]
label, confidence = face_recognizer.predict(faces_roi)
cv.putText(img, str(people[label]), (20,40),
cv.FONT_HERSHEY_COMPLEX, 1.0, (0, 255, 0), 2)
cv.rectangle(img, (x,y), (x+w, y+h), (0,255,0), thickness=2)
cv.imshow('Detected face', img)
cv.waitKey(0)
This works sometimes from my poorly trained model.
Funnily enough, it thought Jerry Seinfeld is Elton John when wearing glasses.