Skip to content

Commit 8290c23

Browse files
committed
edit face recognition with documentation and prediction
1 parent 488561f commit 8290c23

File tree

3 files changed

+103
-29
lines changed

3 files changed

+103
-29
lines changed

FaceRecognition/README.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22

33
Modern face recognition with deep learning and HOG algorithm.
44

5-
1. Find faces in image
6-
2. Affine Transformations
7-
3. Encoding Faces
8-
4. Make a prediction
9-
10-
Using the pipeline described [in this post from Adam Geitgey](https://medium.com/@ageitgey/machine-learning-is-fun-part-4-modern-face-recognition-with-deep-learning-c3cffc121d78).
5+
1. Find faces in image (HOG Algorithm)
6+
2. Affine Transformations (Face alignment using an ensemble of regression
7+
trees)
8+
3. Encoding Faces (FaceNet)
9+
4. Make a prediction (Linear SVM)
1110

1211
We are using the [Histogram of Oriented Gradients](http://lear.inrialpes.fr/people/triggs/pubs/Dalal-cvpr05.pdf) (HOG) method. Instead of computing gradients for every pixel of the image (way too much detail). We compute the weighted vote orientation gradients of 16x16 pixels squares. Afterward, we have a simple representation (HOG image) that captures the basic structure of a face.
1312
All we have to do is find the part of our image that looks the most similar to a known trained HOG pattern.
@@ -34,5 +33,11 @@ The training process works by looking at 3 face images at a time:
3433
- Load a picture of a different person and generate for the two pictures the 128 measurements
3534
Then we tweak the neural network slightly so that it makes sure the measurements for the same person are slightly closer while making sure the measurements for the two different persons are slightly further apart.
3635
Once the network has been trained, it can generate measurements for any face, even ones it has never seen before!
36+
```
37+
face_encoder = dlib.face_recognition_model_v1(face_recognition_model)
38+
face_encoding = np.array(face_encoder.compute_face_descriptor(image, pose_landmarks, 1))
39+
```
40+
41+
Finally, we need a classifier (Linear SVM or other classifier) to find the person in our database of known people who has the closest measurements to our test image. We train the classifier with the measurements as input.
3742

38-
Finally, we need a classifier (Linear SVM or other classifier) to find the person in our database of known people who has the closest measurements to our test image. We train the classifier with the measurements as input.
43+
Thanks to Adam Geitgey who wrote a great [post](https://medium.com/@ageitgey/machine-learning-is-fun-part-4-modern-face-recognition-with-deep-learning-c3cffc121d78) about this, I followed his pipeline.

FaceRecognition/detect_recognize.py

Lines changed: 75 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,42 @@
99
import pickle
1010
import os
1111
import sys
12+
import argparse
13+
import time
1214

1315
from sklearn.svm import SVC
1416
from sklearn.preprocessing import LabelEncoder
1517

16-
import face_recognition_models
17-
1818
face_detector = dlib.get_frontal_face_detector()
19-
face_recognition_model = face_recognition_models.face_recognition_model_location()
20-
face_encoder = dlib.face_recognition_model_v1(face_recognition_model)
19+
face_encoder = dlib.face_recognition_model_v1('./model/dlib_face_recognition_resnet_model_v1.dat')
2120
face_pose_predictor = dlib.shape_predictor('./model/shape_predictor_68_face_landmarks.dat')
2221

2322
def get_detected_faces(filename):
23+
"""
24+
Detect faces in a picture using HOG
25+
:param filename: picture filename
26+
:return: picture numpy array, face detector object with detected faces
27+
"""
2428
image = cv2.imread(filename)
2529
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
2630
return image, face_detector(image, 1)
2731

2832
def get_face_encoding(image, detected_face):
33+
"""
34+
Encode face into 128 measurements using a neural net
35+
:param image: picture numpy array
36+
:param detected_face: face detector object with one detected face
37+
:return: measurement (128,) numpy array
38+
"""
2939
pose_landmarks = face_pose_predictor(image, detected_face)
3040
face_encoding = face_encoder.compute_face_descriptor(image, pose_landmarks, 1)
3141
return np.array(face_encoding)
3242

3343
def training(people):
3444
"""
35-
We need to have only one person/face per picture
45+
Training our classifier (Linear SVC). Saving model using pickle.
46+
We need to have only one person/face per picture.
47+
:param people: people to classify and recognize
3648
"""
3749
# parsing labels and reprensations
3850
df = pd.DataFrame()
@@ -51,6 +63,7 @@ def training(people):
5163
y = le.fit_transform(df[128])
5264
print("Training for {} classes.".format(len(le.classes_)))
5365
X = df.drop(128, axis=1)
66+
print("Training with {} pictures.".format(len(X)))
5467

5568
# training
5669
clf = SVC(C=1, kernel='linear', probability=True)
@@ -62,21 +75,71 @@ def training(people):
6275
with open(fName, 'wb') as f:
6376
pickle.dump((le, clf), f)
6477

65-
def predict(filename):
66-
with open("./classifier.pkl", 'rb') as f:
67-
(le, clf) = pickle.load(f)
78+
def predict(filename, le=None, clf=None, verbose=False):
79+
"""
80+
Detect and recognize a face using a trained classifier.
81+
:param filename: picture filename
82+
:param le:
83+
:paral clf:
84+
:param verbose:
85+
:return: picture with bounding boxes and prediction
86+
"""
87+
if not le and not clf:
88+
with open("./classifier.pkl", 'rb') as f:
89+
(le, clf) = pickle.load(f)
6890
image, detected_faces = get_detected_faces(filename)
91+
prediction = []
92+
# Verbose for debugging
93+
if verbose:
94+
print('{} faces detected.'.format(len(detected_faces)))
6995
img = np.copy(image)
7096
font = cv2.FONT_HERSHEY_SIMPLEX
7197
for face_detect in detected_faces:
7298
# draw bounding boxes
7399
cv2.rectangle(img, (face_detect.left(), face_detect.top()),
74100
(face_detect.right(), face_detect.bottom()), (255, 0, 0), 2)
101+
start_time = time.time()
102+
# predict each face
75103
p = clf.predict_proba(get_face_encoding(image, face_detect).reshape(1, 128))
76-
if np.max(p) > 0.8:
104+
# throwing away prediction with low confidence
105+
a = np.sort(p[0])[::-1]
106+
if a[0]-a[1] > 0.5:
77107
y_pred = le.inverse_transform(np.argmax(p))
78-
cv2.putText(img, y_pred, (face_detect.left(), face_detect.top()-5), font, 0.3, (255, 0, 0))
79-
return img
108+
prediction.append([y_pred, (face_detect.left(), face_detect.top()),
109+
(face_detect.right(), face_detect.bottom())])
110+
else:
111+
y_pred = 'unknown'
112+
# Verbose for debugging
113+
if verbose:
114+
print('\n'.join(['%s : %.3f' % (k[0], k[1]) for k in list(zip(map(le.inverse_transform,
115+
np.argsort(p[0])),
116+
np.sort(p[0])))[::-1]]))
117+
print('Prediction took {:.2f}s'.format(time.time()-start_time))
118+
119+
cv2.putText(img, y_pred, (face_detect.left(), face_detect.top()-5), font, np.max(img.shape[:2])/1800, (255, 0, 0))
120+
return img, prediction
80121

81122
if __name__ == '__main__':
82-
people = os.listdir('./data/')
123+
parser = argparse.ArgumentParser()
124+
parser.add_argument('mode', type=str, help='train or predict')
125+
parser.add_argument('--training_data',
126+
type=str,
127+
help="Path to training data folder.",
128+
default='./data/')
129+
parser.add_argument('--testing_data',
130+
type=str,
131+
help="Path to test data folder.",
132+
default='./test/')
133+
134+
args = parser.parse_args()
135+
people = os.listdir(args.training_data)
136+
print('{} people will be classified.'.format(len(people)))
137+
if args.mode == 'train':
138+
training(people)
139+
elif args.mode == 'test':
140+
with open("./classifier.pkl", 'rb') as f:
141+
(le, clf) = pickle.load(f)
142+
for i, f in enumerate(glob.glob(args.testing_data)):
143+
img, _ = predict(f, le, clf)
144+
cv2.imwrite(args.testing_data + 'test_{}.jpg'.format(i), img)
145+

README.md

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,27 @@ The goal of this challenge is to build a model that predicts the count of bike s
1010

1111
-->[French Explanations PDF](https://github.com/alexattia/Data-Science-Projects/blob/master/KaggleBikeSharing/Kaggle_BikeSharing_Explanations_French.pdf)
1212

13-
## [Kaggle Understanding the Amazon from Space](https://github.com/alexattia/Data-Science-Projects/tree/master/KaggleAmazon)
14-
Use satellite data to track the human footprint in the Amazon rainforest.
15-
Deep Learning model (using Keras) to label satellite images.
13+
## [Twitter Parsing](https://github.com/alexattia/Data-Science-Projects/tree/master/TwitterParsing)
1614

17-
## [Predicting IMDB movie rating](https://github.com/alexattia/Data-Science-Projects/tree/master/KaggleMovieRating)
18-
Project inspired by Chuan Sun [work](https://www.kaggle.com/deepmatrix/imdb-5000-movie-dataset)
19-
How can we tell the greatness of a movie ?
20-
Scrapping and Machine Learning
15+
I've recently discovered the Chris Albon Machine Learning flash cards and I want to download those flash cards but the official Twitter API has a limit rate of 2 weeks old tweets so I had to find a way to bypass this limitation : use Selenium and PhantomJS.
16+
Purpose of this project : Check every 2 hours, if he posted new flash cards. In this case, download them and send me a summary email.
17+
18+
## [Face Recognition](https://github.com/alexattia/Data-Science-Projects/tree/master/FaceRecognition)
19+
20+
Modern face recognition with deep learning and HOG algorithm. Using dlib C++ library, I have a quick face recognition tool using few pictures (20 per person).
2121

2222
## [Playing with Soccer data](https://github.com/alexattia/Data-Science-Projects/tree/master/KaggleSoccer)
2323

2424
As a soccer fan and a data passionate, I wanted to play and analyze with soccer data.
2525
I don't know currently what's the aim of this project but I will parse data from diverse websites, for differents teams and differents players.
2626

27-
## [Twitter Parsing](https://github.com/alexattia/Data-Science-Projects/tree/master/TwitterParsing)
2827

29-
I've recently discovered the Chris Albon Machine Learning flash cards and I want to download those flash cards but the official Twitter API has a limit rate of 2 weeks old tweets so I had to find a way to bypass this limitation : use Selenium and PhantomJS.
30-
Purpose of this project : Check every 2 hours, if he posted new flash cards. In this case, download them and send me a summary email.
28+
29+
## [Kaggle Understanding the Amazon from Space](https://github.com/alexattia/Data-Science-Projects/tree/master/KaggleAmazon)
30+
Use satellite data to track the human footprint in the Amazon rainforest.
31+
Deep Learning model (using Keras) to label satellite images.
32+
33+
## [Predicting IMDB movie rating](https://github.com/alexattia/Data-Science-Projects/tree/master/KaggleMovieRating)
34+
Project inspired by Chuan Sun [work](https://www.kaggle.com/deepmatrix/imdb-5000-movie-dataset)
35+
How can we tell the greatness of a movie ?
36+
Scrapping and Machine Learning

0 commit comments

Comments
 (0)