-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
19 changed files
with
1,897 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
# Created by .ignore support plugin (hsz.mobi) | ||
### macOS template | ||
# General | ||
.DS_Store | ||
.AppleDouble | ||
.LSOverride | ||
|
||
# Icon must end with two \r | ||
Icon | ||
|
||
# Thumbnails | ||
._* | ||
|
||
# Files that might appear in the root of a volume | ||
.DocumentRevisions-V100 | ||
.fseventsd | ||
.Spotlight-V100 | ||
.TemporaryItems | ||
.Trashes | ||
.VolumeIcon.icns | ||
.com.apple.timemachine.donotpresent | ||
|
||
# Directories potentially created on remote AFP share | ||
.AppleDB | ||
.AppleDesktop | ||
Network Trash Folder | ||
Temporary Items | ||
.apdisk | ||
### JetBrains template | ||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm | ||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 | ||
|
||
# User-specific stuff | ||
.idea/**/workspace.xml | ||
.idea/**/tasks.xml | ||
.idea/**/usage.statistics.xml | ||
.idea/**/dictionaries | ||
.idea/**/shelf | ||
|
||
# Sensitive or high-churn files | ||
.idea/**/dataSources/ | ||
.idea/**/dataSources.ids | ||
.idea/**/dataSources.local.xml | ||
.idea/**/sqlDataSources.xml | ||
.idea/**/dynamic.xml | ||
.idea/**/uiDesigner.xml | ||
.idea/**/dbnavigator.xml | ||
|
||
# Gradle | ||
.idea/**/gradle.xml | ||
.idea/**/libraries | ||
|
||
# Gradle and Maven with auto-import | ||
# When using Gradle or Maven with auto-import, you should exclude module files, | ||
# since they will be recreated, and may cause churn. Uncomment if using | ||
# auto-import. | ||
# .idea/modules.xml | ||
# .idea/*.iml | ||
# .idea/modules | ||
|
||
# CMake | ||
cmake-build-*/ | ||
|
||
# Mongo Explorer plugin | ||
.idea/**/mongoSettings.xml | ||
|
||
# File-based project format | ||
*.iws | ||
|
||
# IntelliJ | ||
out/ | ||
|
||
# mpeltonen/sbt-idea plugin | ||
.idea_modules/ | ||
|
||
# JIRA plugin | ||
atlassian-ide-plugin.xml | ||
|
||
# Cursive Clojure plugin | ||
.idea/replstate.xml | ||
|
||
# Crashlytics plugin (for Android Studio and IntelliJ) | ||
com_crashlytics_export_strings.xml | ||
crashlytics.properties | ||
crashlytics-build.properties | ||
fabric.properties | ||
|
||
# Editor-based Rest Client | ||
.idea/httpRequests | ||
### Example user template template | ||
### Example user template | ||
|
||
# IntelliJ project files | ||
.idea | ||
*.iml | ||
out | ||
gen### Python template | ||
# Byte-compiled / optimized / DLL files | ||
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
|
||
# C extensions | ||
*.so | ||
|
||
# Distribution / packaging | ||
.Python | ||
build/ | ||
develop-eggs/ | ||
dist/ | ||
downloads/ | ||
eggs/ | ||
.eggs/ | ||
lib/ | ||
lib64/ | ||
parts/ | ||
sdist/ | ||
var/ | ||
wheels/ | ||
*.egg-info/ | ||
.installed.cfg | ||
*.egg | ||
MANIFEST | ||
|
||
# PyInstaller | ||
# Usually these files are written by a python script from a template | ||
# before PyInstaller builds the exe, so as to inject date/other infos into it. | ||
*.manifest | ||
*.spec | ||
|
||
# Installer logs | ||
pip-log.txt | ||
pip-delete-this-directory.txt | ||
|
||
# Unit test / coverage reports | ||
htmlcov/ | ||
.tox/ | ||
.coverage | ||
.coverage.* | ||
.cache | ||
nosetests.xml | ||
coverage.xml | ||
*.cover | ||
.hypothesis/ | ||
.pytest_cache/ | ||
|
||
# Translations | ||
*.mo | ||
*.pot | ||
|
||
# Django stuff: | ||
*.log | ||
local_settings.py | ||
db.sqlite3 | ||
|
||
# Flask stuff: | ||
instance/ | ||
.webassets-cache | ||
|
||
# Scrapy stuff: | ||
.scrapy | ||
|
||
# Sphinx documentation | ||
docs/_build/ | ||
|
||
# PyBuilder | ||
target/ | ||
|
||
# Jupyter Notebook | ||
.ipynb_checkpoints | ||
|
||
# pyenv | ||
.python-version | ||
|
||
# celery beat schedule file | ||
celerybeat-schedule | ||
|
||
# SageMath parsed files | ||
*.sage.py | ||
|
||
# Environments | ||
.env | ||
.venv | ||
env/ | ||
venv/ | ||
ENV/ | ||
env.bak/ | ||
venv.bak/ | ||
|
||
# Spyder project settings | ||
.spyderproject | ||
.spyproject | ||
|
||
# Rope project settings | ||
.ropeproject | ||
|
||
# mkdocs documentation | ||
/site | ||
|
||
# mypy | ||
.mypy_cache/ | ||
### VirtualEnv template | ||
# Virtualenv | ||
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ | ||
.Python | ||
[Ii]nclude | ||
[Ll]ib | ||
[Ll]ib64 | ||
[Ll]ocal | ||
[Ss]cripts | ||
pyvenv.cfg | ||
.venv | ||
pip-selfcheck.json | ||
|
||
# Ignore Data | ||
data |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import os | ||
import cv2 | ||
import argparse | ||
|
||
|
||
def main(directory, name, test): | ||
cap = cv2.VideoCapture(0) | ||
|
||
i = 0 | ||
while True: | ||
# Capture frame-by-frame | ||
ret, frame = cap.read() | ||
frame = cv2.flip(frame, 1) | ||
|
||
# Display the resulting frame | ||
cv2.imshow(name, frame) | ||
if not test and i != 0 and i % 10 == 0: | ||
cv2.imwrite("{}/{}{}.png".format(directory, name, i / 10), frame) | ||
i += 1 | ||
if cv2.waitKey(1) & 0xFF == ord('q'): | ||
break | ||
|
||
# When everything done, release the captureq | ||
cap.release() | ||
cv2.destroyAllWindows() | ||
|
||
|
||
if __name__ == '__main__': | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument('--person', required=True) | ||
parser.add_argument('--test', action='store_true') | ||
args = parser.parse_args() | ||
directory = 'images/{}'.format(args.person) | ||
if not args.test and not os.path.exists(directory): | ||
os.mkdir(directory) | ||
try: | ||
main(directory, args.person, args.test) | ||
except KeyboardInterrupt: | ||
print "Photo session done for {} :)".format(args.person) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
DATA_PATH = 'data/features/' | ||
MODEL_PATH = 'models/model.pkl' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import pandas as pd | ||
from constants import DATA_PATH | ||
|
||
EMBEDDINGS_PATH = DATA_PATH + 'reps.csv' | ||
LABELS_PATH = DATA_PATH + 'labels.csv' | ||
|
||
|
||
def load_data(): | ||
embeddings = pd.read_csv(EMBEDDINGS_PATH, header=None).values | ||
labels = map(lambda label: label.split('/')[-2].upper(), pd.read_csv(LABELS_PATH, header=None).values[:, 1].tolist()) | ||
return embeddings, labels | ||
|
||
|
||
if __name__ == '__main__': | ||
print load_data() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import openface | ||
import cv2 | ||
import pickle | ||
import numpy as np | ||
from collections import namedtuple | ||
from constants import MODEL_PATH | ||
|
||
Face = namedtuple('Face', 'bb identity probability') | ||
|
||
align = openface.AlignDlib('models/shape_predictor_68_face_landmarks.dat') | ||
net = openface.TorchNeuralNet('models/nn4.small2.v1.t7', imgDim=96, cuda=False) | ||
le, model = pickle.load(open(MODEL_PATH, 'rb')) | ||
|
||
|
||
def faces_embeddings_and_bbs(img): | ||
rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) | ||
bb = align.getAllFaceBoundingBoxes(rgb_img) | ||
|
||
aligned_faces = [] | ||
for box in bb: | ||
aligned_faces.append( | ||
align.align( | ||
96, | ||
rgb_img, | ||
box, | ||
landmarkIndices=openface.AlignDlib.OUTER_EYES_AND_NOSE)) | ||
|
||
embeddings = np.array([net.forward(alignedFace) for alignedFace in aligned_faces]) | ||
|
||
return embeddings, bb | ||
|
||
|
||
def predict(img): | ||
embeddings, bb = faces_embeddings_and_bbs(img) | ||
if embeddings.size == 0 or not bb: | ||
return None | ||
probs = model.predict_proba(embeddings) | ||
predicted = probs.argmax(axis=1) | ||
identities = le.inverse_transform(predicted) | ||
probs = probs[np.arange(len(predicted)), predicted] | ||
return [Face(box, identity, prob * 100) for identity, box, prob in zip(identities, bb, probs)] | ||
|
||
|
||
if __name__ == '__main__': | ||
predict('') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
from __future__ import print_function, division | ||
|
||
import cv2 | ||
from predict import predict | ||
|
||
|
||
def main(): | ||
cap = cv2.VideoCapture(0) | ||
|
||
while True: | ||
# Capture frame-by-frame | ||
ret, frame = cap.read() | ||
frame = cv2.flip(frame, 1) | ||
|
||
faces = predict(frame) | ||
if faces is not None: | ||
for face in faces: | ||
cv2.rectangle(frame, (face.bb.left(), face.bb.top()), (face.bb.right(), face.bb.bottom()), (0, 255, 0), 2) | ||
cv2.putText(frame, "%s %.2f%%" % (face.identity, face.probability), | ||
(face.bb.left(), face.bb.bottom() + 20), cv2.FONT_HERSHEY_TRIPLEX, 0.5, (255, 255, 255), 1) | ||
|
||
# Display the resulting frame | ||
cv2.imshow('frame', frame) | ||
if cv2.waitKey(1) & 0xFF == ord('q'): | ||
break | ||
|
||
# When everything done, release the captureq | ||
cap.release() | ||
cv2.destroyAllWindows() | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import pickle | ||
from sklearn.model_selection import GridSearchCV | ||
from sklearn.svm import SVC | ||
from sklearn.linear_model import LogisticRegression | ||
from sklearn.preprocessing import LabelEncoder | ||
from sklearn.metrics import classification_report | ||
from dataset import load_data | ||
from constants import MODEL_PATH | ||
from sklearn.ensemble import RandomForestClassifier | ||
|
||
CLASSIFIERS = { | ||
'svm': ( | ||
SVC(decision_function_shape='ovr'), | ||
[ | ||
{'C': [0.001, 0.1, 1, 10, 100, 1000], 'kernel': ['linear']}, | ||
{'C': [0.001, 0.1, 1, 10, 100, 1000], 'gamma': [100, 50, 10, 1, 0.01, 0.001, 0.0001], 'kernel': ['rbf']} | ||
] | ||
), | ||
'logreg': ( | ||
LogisticRegression(max_iter=100000), | ||
{'C': [0.001, 0.1, 1, 10, 100, 1000]} | ||
) | ||
} | ||
|
||
|
||
def main(): | ||
X, y = load_data() | ||
le = LabelEncoder() | ||
le.fit(y) | ||
|
||
classifier = CLASSIFIERS['logreg'] | ||
|
||
clf = GridSearchCV(classifier[0], classifier[1], cv=5, verbose=1) | ||
clf.fit(X, le.transform(y)) | ||
|
||
print clf.best_params_ | ||
print classification_report(le.transform(y), clf.predict(X), target_names=le.classes_) | ||
pickle.dump((le, clf), open(MODEL_PATH, 'wb')) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
Empty file.
Oops, something went wrong.