1.OpenFace Introduction
http://cmusatyalab.github.io/openface/
Installation just follow the official tutorial.
Run a command after you've loaded all the dependencies
Https://github.com/cmusatyalab/openface.git--recursive
cd openface
sudo python setup.py install
sh modles/get-models.sh
2. Material Preparation
Prepare photos of two people in different angles I'm ready for the two of you. Li, Wang, each of the 30 photos as a training set, each of the six Zhang as a test set; training data is placed under the Openface/ws_train_data path
The following figure is a picture of the training set:
Test Set Data:
It is important to note that BMP files are not supported for target detection 3. Preprocessing (target detection)
Enter the root directory of the Openface, enter
$./util/align-dlib.py ws_train_data/align Outereyesandnose ws_pre_process
ws_train_data/the data of the training set under this path, ws_pre_process is the path of the preprocessing result
If all goes well, you'll see output similar to the following:
In the corresponding path you will see the results of the pretreatment of these two people, and the human face is individually intercepted.
.
4. Generate the corresponding facial feature representation data
./batch-represent/main.lua-outdir Ws_represent_data-data ws_pre_process/
Ws_represent_data is the output path, ws_pre_process/allows us to preprocess the result path
will see the corresponding two CSV files in the corresponding Ws_represent_data
5. Training Model
./demos/classifier.py Train ws_represent_data/
will get the following output
I found a bug here that the LDA () function in the classifier.py file under demos under the Openface root path has not been replaced by the Sklearn library in order to Lineardiscriminantanalysis ()
The original is this:
CLF = Pipeline ([' Lda ', LDA (N_components=args.ldadim)),
(' CLF ', clf_final)])
You should import the appropriate module and modify it as follows:
CLF = Pipeline ([' Lda ', Lineardiscriminantanalysis (N_components=args.ldadim)),
(' CLF ', clf_final)])
The complete classifier.py is posted here.
#!/usr/bin/env Python2 # # Example to classify faces. # Brandon Amos # 2015/10/11 # # Copyright 2015-2016 Carnegie Mellon University # # Licensed under the Apache License, Vers
Ion 2.0 (the "License");
# You are not a use of this file except in compliance with the License. # Obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # unless required by applic Able law or agreed to in writing, software # Distributed under the License are distributed on a "as is" BASIS, # without W
Arranties or CONDITIONS of any KIND, either express OR implied.
# See the License for the specific language governing permissions and # Limitations under the License. Import time start = Time.time () Import argparse import cv2 import OS import pickle import sys from operator import ITEMG Etter import NumPy as NP np.set_printoptions (precision=2) Import pandas as PD import Openface from Sklearn.discriminant_ Analysis Import lineardiscriminantanalysis from sklearn.pipeline import PipeLine # from Sklearn.lda import lda from sklearn.preprocessing import Labelencoder to SKLEARN.SVM import SVC from Sklearn . Grid_search import GRIDSEARCHCV from sklearn.mixture import GMM from sklearn.tree import decisiontreeclassifier from Skle Arn.naive_bayes import Gaussiannb Filedir = Os.path.dirname (Os.path.realpath (__file__)) Modeldir = Os.path.join ( Filedir, ' ... ', ' models ') Dlibmodeldir = Os.path.join (Modeldir, ' dlib ') Openfacemodeldir = Os.path.join (Modeldir, ' Openface ') def getrep (Imgpath, multiple=false): start = Time.time () bgrimg = Cv2.imread (imgpath) if bgrimg i S none:raise Exception ("Unable to load image: {}". Format (imgpath)) rgbimg = Cv2.cvtcolor (bgrimg, Cv2.
COLOR_BGR2RGB) If Args.verbose:print ("+ Original size: {}". Format (Rgbimg.shape)) if Args.verbose: Print ("Loading the image took {} seconds.") Format (Time.time ()-start)) start = Time.time () If Multiple:bbs = Align.getallfaceboundingboxes (rgbimg )
ELSE:BB1 = Align.getlargestfaceboundingbox (rgbimg) BBS = [BB1] If Len (BBS) = = 0 or (not multiple and BB1 is None): Raise Exception ("Unable to find a face: {}". Format (Imgpath)) if Args.verbose:print ("Face detection took {} seconds.") Format (Time.time ()-start)) reps = [] for bb in Bbs:start = Time.time () Alignedface = Align.ali GN (Args.imgdim, Rgbimg, BB, Landmarkindices=openface. Aligndlib.outer_eyes_and_nose) If Alignedface is none:raise Exception (' Unable to align image: {} '. for Mat (Imgpath)) if Args.verbose:print ("Alignment took {} seconds.")
Format (Time.time ()-start)) print ("This bbox was centered at {}, {}". Format (Bb.center (). x, Bb.center (). Y)) Start = Time.time () Rep = Net.forward (alignedface) if Args.verbose:print ("Neural networ K forward pass took {} seconds. ".
Format Time.time ()-start)) Reps.append ((Bb.center (). x, Rep)) Sreps = sorted (Reps, Key=lambda x:x[0])
Return Sreps def train (args): Print ("Loading embeddings.") FName = "{}/labels.csv". Format (args.workdir) labels = pd.read_csv (fname, Header=none). As_matrix () [:, 1] labels = m AP (Itemgetter (1), map (os.path.split, map (os.path.dirname, labels)) # Get The Direc
Tory. FName = "{}/reps.csv". Format (args.workdir) embeddings = Pd.read_csv (fname, Header=none). As_matrix () le = Labelenco Der (). Fit (labels) labelsnum = le.transform (labels) nclasses = Len (le.classes_) print ("Training for {} classes.
". Format (nclasses)) if args.classifier = = ' LINEARSVM ': CLF = SVC (c=1, kernel= ' linear ', probability=true) elif Args.classifier = = ' GRIDSEARCHSVM ': Print ("" "Warning:in our experiences, using a grid search over S VM Hyper-parameters only gives marginally better performAnce than a linear SVM with c=1 and are not worth the extra computations of performing a grid search. "" ") Param_grid = [{' C ': [1, ten, +, +], ' kernel ': [' linear ']}, {' C ': [1 , "gamma": [0.001, 0.0001], ' kernel ': [' RBF ']}] CLF = Gridsearc HCV (SVC (C=1, Probability=true), Param_grid, cv=5) elif args.classifier = ' GMM ': # doesn ' t work best CLF = GM M (n_components=nclasses) # Ref: # http://scikit-learn.org/stable/auto_examples/classification/plot_classifier_com Parison.html#example-classification-plot-classifier-comparison-py elif Args.classifier = = ' RADIALSVM ': # Radial Basis Function Kernel # works better with C = 1 and gamma = 2 CLF = SVC (c=1, kernel= ' RBF ', Probability=true, GA
mma=2) elif Args.classifier = = ' DecisionTree ': # doesn ' t work best CLF = Decisiontreeclassifier (max_depth=20) elif Args.classifier = =' GAUSSIANNB ': CLF = GAUSSIANNB () # ref:https://jessesw.com/deep-learning/elif Args.classifier = = ' DBN ': From NOLEARN.DBN import DBN CLF = DBN ([embeddings.shape[1], $, labelsnum[-1:][0] + 1], # i/p nodes, HI Dden nodes, o/p nodes learn_rates=0.3, # Smaller steps mean a possibly more accurate r Esult, but the # training'll take longer learn_rate_decays=0.9, #
A factor the initial learning rate would be multiplied by # after each iteration of the training
epochs=300, # No of iternation # dropouts = 0.25, # Express The percentage of nodes that
# would be randomly dropped as a decimal. verbose=1) If Args.ldadim > 0:clf_final = CLF CLF = Pipeline ([' Lda ', lineardiscriminantanalysis (
N_components=args.ldadim)), (' CLF ', clf_final)]) # CLF = Pipeline ([' Lda ', LDA (N_components=args.ldadim)), # (' CLF ', clf_final)]) CLF. Fit (embeddings, labelsnum) FName = "{}/classifier.pkl". Format (args.workdir) print ("Saving classifier to ' {} '". Mat (FName)) with open (FName, ' W ') as F:pickle.dump ((Le, CLF), F) def infer (args, multiple=false): With
Open (Args.classifiermodel, ' RB ') as F:if sys.version_info[0] < 3: (LE, CLF) = Pickle.load (f) else: (LE, CLF) = Pickle.load (f, encoding= ' latin1 ') for IMG in Args.imgs:print ("\n=== {} = = = ". Format (img)) reps = Getrep (img, multiple) If Len (reps) > 1:print (" List of Faces I
n image from left to right ") for r in Reps:rep = R[1].reshape (1,-1) bbx = r[0]
Start = Time.time () predictions = Clf.predict_proba (Rep). Ravel () MaxI = Np.argmax (predictions) Person = le.Inverse_transform (MaxI) confidence = Predictions[maxi] If Args.verbose:print ("Pre Diction took {} seconds. ". Format (Time.time ()-start)) if Multiple:print ("Predict {} @ x={} with {:. 2f} confidence.".
Format (Person.decode (' Utf-8 '), BBX, confidence)) Else:print ("Predict {} with {:. 2f} confidence.") Format (Person.decode (' utf-8 '), confidence)) if Isinstance (CLF, GMM): dist = Np.linalg.norm (rep
-Clf.means_[maxi]) print ("+ Distance from the mean: {}". Format (Dist)) if __name__ = = ' __main__ ': Parser = Argparse. Argumentparser () parser.add_argument ('--dlibfacepredictor ', Type=str, help= "Path to Dlib ' s F Ace Predictor. ", Default=os.path.join (Dlibmodeldir," Shape_predictor_68_face_landmarks.da T ")) Parser.add_argumENT ('--networkmodel ', Type=str, help= "Path to Torch network model.", Default=os.path.join
(Openfacemodeldir, ' nn4.small2.v1.t7 ')) Parser.add_argument ('--imgdim ', Type=int, help= "Default image dimension.", default=96) parser. Add_argument ('--cuda ', action= ' store_true ') parser.add_argument ('--verbose ', action= ' store_true ') Subparsers = PA
Rser.add_subparsers (dest= ' mode ', help= "mode") Trainparser = Subparsers.add_parser (' Train ',
Help= "Train a new classifier.") Trainparser.add_argument ('--ldadim ', Type=int, Default=-1) trainparser.add_argument ('--classifier ', t Ype=str, choices=[' LINEARSVM ', ' gridsearchsvm ', ' GMM ', ' RADIALSVM ', ' decisiontree ', ' gaussiannb ', ' DBN ', help= ' the type of classifier to use. ' , default= ' LINEARSVM') trainparser.add_argument (' Workdir ', Type=str, help= "The input work directory containing ' r Eps.csv ' and ' labels.csv '.
Obtained from aligning a directory with ' Align-dlib ' and getting the representations with ' batch-represent '. ")
Inferparser = Subparsers.add_parser (' Infer ', help= ' Predict who an image contains from a trained classifier. ') Inferparser.add_argument (' Classifiermodel ', type=str, help= ' The Python pickle representing the Classifier.
The Torch network model, which can set with--networkmodel. ')
Inferparser.add_argument (' IMGs ', type=str, nargs= ' + ', help= "Input image.") Inferparser.add_argument ('--multi ', help= "infer multiple faces in image", action= "Store_true" ) args = Parser.parse_args () if Args.verbose:print ("Argument parsing and import libraries took {} second S. ".
Format (Time.time ()-start)) if Args.mode = = ' Infer ' and Args.classifierModel.endswith (". T7"): Raise Exception ("" "Torch Network Model Pass Ed as the classification model, which should is a Python pickle (. pkl) See the documentation for the distinction between The Torch Network and classification Models:http://cmusatyalab.github.io/openface/demo-3-classifier/htt P://cmusatyalab.github.io/openface/training-new-models/use '--networkmodel ' to set a non-standard Torch network model. " "") Start = Time.time () align = Openface. Aligndlib (args.dlibfacepredictor) net = Openface. Torchneuralnet (Args.networkmodel, Imgdim=args.imgdim, Cuda=args.cuda) if Args.verbo Se:print ("Loading the Dlib and Openface models took {} seconds.")
Format (Time.time ()-start)) start = Time.time () if Args.mode = = ' Train ': Train (args)
elif Args.mode = = ' infer ': infer (args, Args.multi)
6. Face Recognition
./demos/classifier.py Infer./ws_represent_data/classifier.pkl ws_test_data/{test6,test7}/*.jpg
Judging from the test results of the current test set, the accuracy rate is 100%
But there is a problem here, when the system does not detect a face in the test set, it can not continue to predict the next picture under the current path
I think a slight modification of classifier.py should solve this problem.