LBPs for face recognition algorithm has the added benefit of being updatable as new faces are introduced to the dataset.
LBPs for face recognition algorithm can simply insert new face samples without having to be re-trained at all — an obvious benefit when working with face datasets where people are being added or removed from the dataset with routine frequency.
after training with LBPs algorithm, AI recognizes all faces
sample image set of a person
AI is trained with images sets from many persons
#project directory
assets
faces
googleNet
deploy.prototxt
res10_300x300_ssd_iter_140000.caffemodel
LBP_face.py
--------------------------
#LBP_face.py
from imutils import paths
import numpy as np
import cv2
import os
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import argparse
import imutils
import time
from os.path import dirname, abspath
def detect_faces(net, image, minConfidence=0.5):
# grab the dimensions of the image and then construct a blob
# from it
(h, w) = image.shape[:2]
blob = cv2.dnn.blobFromImage(image, 1.0, (300, 300), (104.0, 177.0, 123.0))
# pass the blob through the network to obtain the face detections,
# then initialize a list to store the predicted bounding boxes
net.setInput(blob)
detections = net.forward()
boxes = []
# loop over the detections
for i in range(0, detections.shape[2]):
# extract the confidence (i.e., probability) associated with
# the detection
confidence = detections[0, 0, i, 2]
# filter out weak detections by ensuring the confidence is
# greater than the minimum confidence
if confidence > minConfidence:
# compute the (x, y)-coordinates of the bounding box for
# the object
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
# update our bounding box results list
boxes.append((startX, startY, endX, endY))
# return the face detection bounding boxes
return boxes
def load_face_dataset(inputPath, net, minConfidence=0.5, minSamples=15):
# grab the paths to all images in our input directory, extract
# the name of the person (i.e., class label) from the directory
# structure, and count the number of example images we have per
# face
imagePaths = list(paths.list_images(inputPath))
#print(imagePaths)
names = [p.split(os.path.sep)[-2] for p in imagePaths]
(names, counts) = np.unique(names, return_counts=True)
names = names.tolist()
#print(names)
# initialize lists to store our extracted faces and associated
# labels
faces = []
labels = []
# loop over the image paths
for imagePath in imagePaths:
# load the image from disk and extract the name of the person
# from the subdirectory structure
image = cv2.imread(imagePath)
name = imagePath.split(os.path.sep)[-2]
#print(name, minSamples)
# only process images that have a sufficient number of
# examples belonging to the class
if counts[names.index(name)] < minSamples:
continue
# perform face detection
boxes = detect_faces(net, image, minConfidence)
# loop over the bounding boxes
for (startX, startY, endX, endY) in boxes:
# extract the face ROI, resize it, and convert it to
# grayscale
faceROI = image[startY:endY, startX:endX]
faceROI = cv2.resize(faceROI, (47, 62))
faceROI = cv2.cvtColor(faceROI, cv2.COLOR_BGR2GRAY)
# update our faces and labels lists
faces.append(faceROI)
labels.append(name)
# convert our faces and labels lists to NumPy arrays
faces = np.array(faces)
labels = np.array(labels)
# return a 2-tuple of the faces and labels
return (faces, labels)
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--input", type=str,
default=dirname(dirname(abspath(__file__))) + "\\assets\\faces",
help="path to input directory of images")
ap.add_argument("-f", "--face", type=str,
default="",
help="path to face detector model directory")
ap.add_argument("-c", "--confidence", type=float, default=0.5,
help="minimum probability to filter weak detections")
args = vars(ap.parse_args())
# load our serialized face detector model from disk
print("[INFO] loading face detector model...")
prototxtPath = "deploy.prototxt"
weightsPath = "res10_300x300_ssd_iter_140000.caffemodel"
net = cv2.dnn.readNet(prototxtPath, weightsPath)
# load the CALTECH faces dataset
print("[INFO] loading dataset...")
print(args["input"])
(faces, labels) = load_face_dataset(args["input"], net,
minConfidence=0.5, minSamples=20)
print("[INFO] {} images in dataset".format(len(faces)))
# encode the string labels as integers
le = LabelEncoder()
labels = le.fit_transform(labels)
# construct our training and testing split
(trainX, testX, trainY, testY) = \
train_test_split(faces, labels, test_size=0.25, stratify=labels, random_state=42)
# train our LBP face recognizer
print("[INFO] training face recognizer...")
# The radius=2 and neighbors=16 parameters control the number of
# pixels included in the computation of the histogram,
# along with the radius these pixels lie on.
# using an 8×8 grid which allows for more granularity, resulting in higher accuracy.
recognizer = cv2.face.LBPHFaceRecognizer_create(
radius=2, neighbors=16, grid_x=8, grid_y=8)
start = time.time()
recognizer.train(trainX, trainY)
end = time.time()
print("[INFO] training took {:.4f} seconds".format(end - start))
# initialize the list of predictions and confidence scores
print("[INFO] gathering predictions...")
predictions = []
confidence = []
start = time.time()
# loop over the test data
for i in range(0, len(testX)):
# classify the face and update the list of predictions and
# confidence scores
(prediction, conf) = recognizer.predict(testX[i])
predictions.append(prediction)
confidence.append(conf)
print("predicting test image " + str(i) + " of " + str(len(testX)) + ". confidence: " + str(conf))
# measure how long making predictions took
end = time.time()
print("[INFO] inference took {:.4f} seconds".format(end - start))
# show the classification report
print(classification_report(testY, predictions,
target_names=le.classes_))
# generate a sample of testing data
idxs = np.random.choice(range(0, len(testY)), size=10, replace=False)
# loop over a sample of the testing data
for i in idxs:
# grab the predicted name and actual name
predName = le.inverse_transform([predictions[i]])[0]
actualName = le.classes_[testY[i]]
# grab the face image and resize it such that we can easily see
# it on our screen
face = np.dstack([testX[i]] * 3)
face = imutils.resize(face, width=250)
# draw the predicted name and actual name on the image
cv2.putText(face, "pred: {}".format(predName), (5, 25),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
cv2.putText(face, "actual: {}".format(actualName), (5, 60),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)
# display the predicted name, actual name, and confidence of the
# prediction (i.e., chi-squared distance; the *lower* the distance
# is the *more confident* the prediction is)
print("[INFO] prediction: {}, actual: {}, confidence: {:.2f}".format(
predName, actualName, confidence[i]))
# display the current face to our screen
cv2.imshow("Face " + str(i), face)
cv2.waitKey(0)
----------------------------
#logs
(venv) C:\Users\zchen\PycharmProjects\opencv\googleNet>python LBP_face.py
[INFO] loading face detector model...
[INFO] loading dataset...
C:\Users\zchen\PycharmProjects\opencv\assets\faces
[INFO] 401 images in dataset
[INFO] training face recognizer...
[INFO] training took 1.2571 seconds
[INFO] gathering predictions...
predicting test image 0 of 101. confidence: 156.05066784335756
predicting test image 1 of 101. confidence: 172.55934680514434
predicting test image 2 of 101. confidence: 167.60806582007518
predicting test image 3 of 101. confidence: 168.3895046348667
predicting test image 4 of 101. confidence: 161.68402620047547
predicting test image 5 of 101. confidence: 175.46755127545347
predicting test image 6 of 101. confidence: 176.313718416004
predicting test image 7 of 101. confidence: 195.20015753599705
...
predicting test image 95 of 101. confidence: 182.50191107376187
predicting test image 96 of 101. confidence: 173.7080780628902
predicting test image 97 of 101. confidence: 177.55615542852405
predicting test image 98 of 101. confidence: 168.53302297795474
predicting test image 99 of 101. confidence: 182.47141327232762
predicting test image 100 of 101. confidence: 163.67195972658968
[INFO] inference took 129.4641 seconds
precision recall f1-score support
abraham 0.83 1.00 0.91 5
alberta 1.00 1.00 1.00 5
carmen 1.00 1.00 1.00 6
conrad 1.00 1.00 1.00 5
cynthia 1.00 1.00 1.00 6
darrell 1.00 1.00 1.00 5
flyod 1.00 0.71 0.83 7
jacques 1.00 1.00 1.00 5
judy 0.86 1.00 0.92 6
julie 1.00 1.00 1.00 6
kathleen 0.75 1.00 0.86 6
mae 1.00 1.00 1.00 5
phil 1.00 0.86 0.92 7
raymond 1.00 1.00 1.00 5
rick 1.00 0.80 0.89 5
ronald 1.00 1.00 1.00 6
tiffany 1.00 1.00 1.00 5
willie 1.00 1.00 1.00 6
accuracy 0.96 101
macro avg 0.97 0.97 0.96 101
weighted avg 0.97 0.96 0.96 101
[INFO] prediction: willie, actual: willie, confidence: 159.70
[INFO] prediction: alberta, actual: alberta, confidence: 170.80
[INFO] prediction: conrad, actual: conrad, confidence: 187.61
[INFO] prediction: jacques, actual: jacques, confidence: 191.64
[INFO] prediction: judy, actual: judy, confidence: 169.71
[INFO] prediction: phil, actual: phil, confidence: 193.52
[INFO] prediction: raymond, actual: raymond, confidence: 166.94
[INFO] prediction: cynthia, actual: cynthia, confidence: 170.20
[INFO] prediction: ronald, actual: ronald, confidence: 161.68
[INFO] prediction: darrell, actual: darrell, confidence: 127.59
reference:
face dataset
googleNet face detection
No comments:
Post a Comment