├── .github ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── stale.yml ├── .gitignore ├── .gitmodules ├── .readthedocs.yaml ├── .travis.yml ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.md ├── api-docs ├── Makefile ├── README.md ├── _static │ ├── sp.js │ └── track.js ├── conf.py ├── index.rst ├── openface.rst └── requirements.txt ├── batch-represent ├── batch-represent.lua ├── batch_represent.py ├── dataset.lua ├── main.lua └── opts.lua ├── cloc.sh ├── conversion ├── convert_to_pytorch.py └── test_luatorch.lua ├── data ├── casia-facescrub │ └── remove-lfw-names.py ├── download-lfw-subset.sh ├── ms-celeb-1m │ └── extract.py └── vgg │ └── download-and-align.py ├── demos ├── classifier.py ├── classifier_new.py ├── classifier_webcam.py ├── compare.py ├── compare_new.py ├── sphere.py ├── vis-outputs.lua └── web │ ├── bower.json │ ├── create-cert.sh │ ├── create-unknown-vectors.py │ ├── css │ └── main.css │ ├── examples.md │ ├── favicon.ico │ ├── images │ └── FacerecWebDemo.ai │ ├── index.html │ ├── install-deps.sh │ ├── js │ ├── openface-demo.js │ └── utils.js │ ├── requirements.txt │ ├── simpleSSLServer.py │ ├── start-servers.sh │ ├── tls │ ├── server.crt │ ├── server.key │ └── server.pem │ ├── update-vendor-deps.sh │ ├── vendor │ ├── bower.json │ ├── css │ │ ├── bootstrap-dialog.css │ │ ├── bootstrap-dialog.min.css │ │ ├── bootstrap-theme.css │ │ ├── bootstrap-theme.css.map │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap-toggle.min.css │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ ├── bootstrap2-toggle.min.css │ │ ├── font-awesome.css │ │ ├── font-awesome.css.map │ │ └── font-awesome.min.css │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ ├── fontawesome-webfont.woff2 │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ ├── js │ │ ├── bootstrap-dialog.js │ │ ├── bootstrap-dialog.min.js │ │ ├── bootstrap-toggle.min.js │ │ ├── bootstrap-toggle.min.js.map │ │ ├── bootstrap.js │ │ ├── bootstrap.min.js │ │ ├── bootstrap2-toggle.min.js │ │ ├── bootstrap2-toggle.min.js.map │ │ ├── handlebars.min.js │ │ ├── jquery.js │ │ ├── jquery.min.js │ │ ├── jquery.min.map │ │ ├── jstat.min.js │ │ ├── npm.js │ │ └── ping.min.js │ ├── less │ │ ├── animated.less │ │ ├── bootstrap-dialog.less │ │ ├── bordered-pulled.less │ │ ├── core.less │ │ ├── fixed-width.less │ │ ├── font-awesome.less │ │ ├── icons.less │ │ ├── larger.less │ │ ├── list.less │ │ ├── mixins.less │ │ ├── path.less │ │ ├── rotated-flipped.less │ │ ├── stacked.less │ │ └── variables.less │ └── scss │ │ ├── _animated.scss │ │ ├── _bordered-pulled.scss │ │ ├── _core.scss │ │ ├── _fixed-width.scss │ │ ├── _icons.scss │ │ ├── _larger.scss │ │ ├── _list.scss │ │ ├── _mixins.scss │ │ ├── _path.scss │ │ ├── _rotated-flipped.scss │ │ ├── _stacked.scss │ │ ├── _variables.scss │ │ └── font-awesome.scss │ └── websocket-server.py ├── docs ├── css │ └── extra.css ├── demo-1-web.md ├── demo-2-comparison.md ├── demo-3-classifier.md ├── demo-4-sphere.md ├── faq.md ├── index.md ├── js │ ├── extra.js │ └── sp.js ├── models-and-accuracies.md ├── release-notes.md ├── setup.md ├── training-new-models.md ├── usage.md └── visualizations.md ├── evaluation ├── attic │ └── lfw.nn4.v1.epoch-177.orig-alignment │ │ └── accuracies.txt ├── classification.nn4.small2.v1 │ ├── accuracies.png │ ├── predictTimes.png │ └── trainTimes.png ├── comparisons │ ├── BaiduIDLFinal.TPFP │ ├── deepface_ensemble.txt │ ├── eigenfaces-original-roc.txt │ ├── kumar_human_crop.txt │ ├── openbr.v1.0.0.DET.csv │ └── openbr.v1.1.0.DET.csv ├── lfw-classification-unknown.py ├── lfw-classification.py ├── lfw.nn4.small1.v1 │ ├── accuracies.txt │ └── roc.png ├── lfw.nn4.small2.v1 │ ├── accuracies.txt │ └── roc.png ├── lfw.nn4.v1 │ ├── accuracies.txt │ └── roc.png ├── lfw.nn4.v2 │ ├── accuracies.txt │ └── roc.png └── lfw.py ├── images ├── dlib-landmark-mean.png ├── examples-aligned │ ├── adams.png │ ├── carell.png │ ├── clapton-1.png │ ├── clapton-2.png │ ├── lennon-1.png │ └── lennon-2.png ├── examples │ ├── adams.jpg │ ├── carell.jpg │ ├── clapton-1.jpg │ ├── clapton-2.jpg │ ├── lennon-1.jpg │ ├── lennon-2.jpg │ └── longoria-cooper.jpg ├── nn4.v1.conv1.lennon-1.png ├── nn4.v1.conv1.lennon-2.png ├── nn4.v1.loss.png ├── performance.png ├── sphere-demo │ ├── data-afterlives-poster.jpg │ ├── demo.gif │ ├── exhibit-amos.png │ ├── exhibits-all.png │ ├── exhibits-nosenzo.png │ └── screenshot.png ├── summary.ai ├── summary.jpg ├── train-tsne.png ├── val-tsne.png └── youtube-web.gif ├── mkdocs.yml ├── models ├── dlib │ ├── mean.csv │ └── std.csv ├── get-models.sh └── openface │ ├── nn2.def.lua │ ├── nn4.def.lua │ ├── nn4.small1.def.lua │ ├── nn4.small2.def.lua │ ├── resnet1.def.lua │ ├── vgg-face.def.lua │ └── vgg-face.small1.def.lua ├── opencv-dlib-torch.Dockerfile ├── openface ├── __init__.py ├── align_dlib.py ├── data.py ├── helper.py ├── openface_server.lua ├── openfacenet.py ├── torch_neural_net.lutorpy.py └── torch_neural_net.py ├── requirements.txt ├── run-tests.sh ├── setup.py ├── tests ├── __init__.py ├── openface_api_tests.py ├── openface_batch_represent_tests.py ├── openface_demo_tests.py └── openface_neural_net_training_tests.py ├── training ├── OpenFaceOptim.lua ├── attic │ ├── OpenFaceOptim.lua │ ├── model.lua │ ├── sanitize.lua │ ├── test-hardNeg.lua │ ├── test.lua │ └── train.lua ├── data.lua ├── dataset-issue-132.lua ├── dataset.lua ├── donkey.lua ├── lfw-latest.sh ├── main.lua ├── model.lua ├── opts.lua ├── plot-loss.py ├── requirements.txt ├── test.lua ├── train.lua └── util.lua └── util ├── align-dlib.py ├── annotate-image.py ├── check-links.py ├── create-train-val-split.py ├── detect-outliers.py ├── email-broken-links.sh ├── print-network-table.lua ├── profile-network.lua ├── profile-pipeline.py ├── prune-dataset.py └── tsne.py /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | ### Context of the issue. 14 | [Provide more detailed introduction to the issue itself and why it is relevant] 15 | 16 | ### Expected behavior. 17 | [Describe what you would expect to have resulted from this process.] 18 | 19 | ### Actual behavior. 20 | [Describe what you currently experience from this process, and thereby explain the bug.] 21 | 22 | ### Steps to reproduce. 23 | [Present a minimal example and steps to produce the issue.] 24 | 25 | ### OS and hardware information. 26 | 27 | + Operating system: [todo] 28 | + Torch version: [todo] 29 | + CPU architecture: [todo] 30 | + GPU type (if using): [todo] 31 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### What does this PR do? 2 | 3 | ### Where should the reviewer start? 4 | 5 | ### How should this PR be tested? 6 | 7 | ### Any background context you want to provide? 8 | 9 | ### What are the relevant issues? 10 | 11 | [You can link directly to issues by entering # then the 12 | number of the issue, for example, #3 links to issue 3] 13 | 14 | # Screenshots (if appropriate) 15 | 16 | # Questions: 17 | 18 | + Do the docs need to be updated? 19 | + Does this PR add new (Python) dependencies? 20 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: stale 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | _build 3 | plots 4 | work* 5 | *reps 6 | 7 | data 8 | !data/vgg/download-and-align.py 9 | !data/download-lfw-subset.sh 10 | 11 | *.pyc 12 | *.mp4 13 | 14 | images/examples-aligned 15 | 16 | evaluation/*/ 17 | evaluation/attic/*/*.csv 18 | evaluation/attic/*/*.pdf 19 | 20 | demos/web/bower_components 21 | 22 | celeb-classifier* 23 | 24 | site 25 | dist 26 | openface.egg-info 27 | 28 | **/.idea 29 | **/*.t7 30 | **/*.pt 31 | **/*.pkl 32 | **/*.dat 33 | **/*.npy 34 | **/*.png 35 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "training/torch-TripletEmbedding"] 2 | path = training/torch-TripletEmbedding 3 | url = https://github.com/Atcold/torch-TripletEmbedding 4 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | build: 4 | os: ubuntu-22.04 5 | tools: 6 | python: "3.11" 7 | 8 | sphinx: 9 | configuration: api-docs/conf.py 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: requires 2 | services: 3 | - docker 4 | 5 | language: python 6 | python: 7 | - "2.7" 8 | 9 | install: 10 | # - pip install flake8 pep257 11 | - sudo apt-get update -qq 12 | # - sudo apt-get install -y luarocks wget 13 | # - sudo luarocks install luacheck 14 | - docker pull bamos/openface 15 | 16 | script: 17 | # - flake8 --ignore=E402,E501 . 18 | # - pep257 --ignore D104,D203,D400,D402 openface 19 | # - luacheck . --no-global --no-self --exclude-files '*/torch-TripletEmbedding' 20 | - | 21 | docker run -v $PWD:/root/src/openface bamos/openface \ 22 | /bin/bash -l -c \ 23 | "source /root/torch/install/bin/torch-activate; \ 24 | cd /root/src/openface; \ 25 | ./models/get-models.sh && \ 26 | ./data/download-lfw-subset.sh && \ 27 | wget -nv https://cmusatyalab.org/openface-models/nn4.v1.t7 \ 28 | -O ./models/openface/nn4.v1.t7 && \ 29 | python2 setup.py install && \ 30 | ./run-tests.sh" 31 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Thank you for your interest in contributing to OpenFace! 2 | 3 | Please direct most questions and discussions to the 4 | [cmu-openface group](https://groups.google.com/forum/#!forum/cmu-openface) 5 | or the 6 | [gitter chat](https://gitter.im/cmusatyalab/openface). 7 | The [issue tracker](https://github.com/cmusatyalab/openface/issues) 8 | is only for development discussions and specific bug reports. 9 | For archival and management purposes, 10 | please do not post the same issue in multiple places. 11 | 12 | If you have found a bug in the code, please file an issue with a 13 | [minimal, complete, and verifiable example](http://stackoverflow.com/help/mcve) 14 | as well as your hardware and operating system information 15 | to help us track and reproduce it. 16 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nvidia/cuda:11.8.0-cudnn8-devel-ubuntu22.04 2 | 3 | ARG DEBIAN_FRONTEND=noninteractive 4 | 5 | RUN apt-get update && apt-get install -y \ 6 | curl \ 7 | git \ 8 | software-properties-common \ 9 | build-essential \ 10 | cmake \ 11 | pkg-config \ 12 | python3 \ 13 | python3-dev \ 14 | python3-distutils \ 15 | python3-pip \ 16 | python3-opencv \ 17 | wget \ 18 | zip \ 19 | libatlas-base-dev \ 20 | libboost-all-dev \ 21 | libopenblas-dev \ 22 | liblapack-dev \ 23 | libswscale-dev \ 24 | libssl-dev \ 25 | libffi-dev \ 26 | libsm6 \ 27 | libxext6 \ 28 | libxrender1 \ 29 | && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 30 | 31 | ADD . /root/openface 32 | RUN python3 -m pip install --upgrade pip 33 | 34 | WORKDIR /root/openface 35 | 36 | RUN ./models/get-models.sh && \ 37 | python3 -m pip install -r requirements.txt && \ 38 | python3 -m pip install . 39 | # python3 -m pip install --user --ignore-installed -r demos/web/requirements.txt && \ 40 | # python3 -m pip install -r training/requirements.txt 41 | 42 | EXPOSE 8000 9000 43 | -------------------------------------------------------------------------------- /api-docs/README.md: -------------------------------------------------------------------------------- 1 | # OpenFace API Docs 2 | 3 | + Create `openface.rst` with `sphinx-apidoc -o . ../openface`. 4 | -------------------------------------------------------------------------------- /api-docs/_static/track.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | try { 3 | var snowplowTracker = Snowplow.getTrackerUrl('joule.isr.cs.cmu.edu:8081'); 4 | snowplowTracker.enableLinkTracking(); 5 | snowplowTracker.trackPageView(); 6 | } catch (err) {} 7 | }); 8 | -------------------------------------------------------------------------------- /api-docs/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | import sys 4 | import mock 5 | import os 6 | 7 | sys.path.insert(0, os.path.abspath('..')) 8 | 9 | MOCK_MODULES = ['argparse', 'cv2', 'dlib', 'numpy', 'numpy.linalg', 'pandas'] 10 | for mod_name in MOCK_MODULES: 11 | sys.modules[mod_name] = mock.MagicMock() 12 | 13 | extensions = [ 14 | 'sphinx.ext.autodoc', 15 | 'sphinx.ext.coverage', 16 | 'sphinx.ext.mathjax', 17 | 'sphinx.ext.viewcode', 18 | ] 19 | 20 | autoclass_content = 'both' 21 | 22 | templates_path = ['_templates'] 23 | 24 | source_suffix = '.rst' 25 | 26 | # The master toctree document. 27 | master_doc = 'index' 28 | 29 | project = 'OpenFace API Docs' 30 | copyright = '2015-2016, Carnegie Mellon University' 31 | author = 'Carnegie Mellon University' 32 | 33 | version = '0.1.1' 34 | release = '0.1.1' 35 | 36 | language = None 37 | 38 | exclude_patterns = ['_build'] 39 | 40 | pygments_style = 'sphinx' 41 | 42 | todo_include_todos = True 43 | 44 | 45 | def setup(app): 46 | app.add_javascript("sp.js") 47 | app.add_javascript("track.js") 48 | 49 | # html_theme = 'alabaster' 50 | html_theme = 'sphinx_rtd_theme' 51 | html_static_path = ['_static'] 52 | htmlhelp_basename = 'OpenFacedoc' 53 | 54 | latex_elements = { 55 | 'papersize': 'letterpaper', 56 | 'pointsize': '12pt', 57 | } 58 | 59 | latex_documents = [ 60 | (master_doc, 'OpenFace.tex', 'OpenFace Documentation', 61 | 'Carnegie Mellon University', 'manual'), 62 | ] 63 | 64 | man_pages = [ 65 | (master_doc, 'openface', 'OpenFace Documentation', 66 | [author], 1) 67 | ] 68 | 69 | texinfo_documents = [ 70 | (master_doc, 'OpenFace', 'OpenFace Documentation', 71 | author, 'OpenFace', 'One line description of project.', 72 | 'Miscellaneous'), 73 | ] 74 | -------------------------------------------------------------------------------- /api-docs/index.rst: -------------------------------------------------------------------------------- 1 | OpenFace API Documentation 2 | ========================== 3 | 4 | + The code is available on GitHub at 5 | `cmusatyalab/openface `_ 6 | + The main website is available at 7 | http://cmusatyalab.github.io/openface. 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | openface 15 | 16 | 17 | Indices and tables 18 | ================== 19 | 20 | * :ref:`genindex` 21 | * :ref:`modindex` 22 | * :ref:`search` 23 | -------------------------------------------------------------------------------- /api-docs/openface.rst: -------------------------------------------------------------------------------- 1 | openface package 2 | ================ 3 | 4 | openface.AlignDlib class 5 | ------------------------ 6 | .. autoclass:: openface.AlignDlib 7 | :members: 8 | :undoc-members: 9 | :show-inheritance: 10 | 11 | openface.TorchNeuralNet class 12 | ----------------------------- 13 | .. autoclass:: openface.TorchNeuralNet 14 | :members: 15 | :undoc-members: 16 | :show-inheritance: 17 | 18 | 19 | openface.data module 20 | -------------------- 21 | 22 | .. automodule:: openface.data 23 | :members: 24 | :undoc-members: 25 | :show-inheritance: 26 | 27 | openface.helper module 28 | ---------------------- 29 | 30 | .. automodule:: openface.helper 31 | :members: 32 | :undoc-members: 33 | :show-inheritance: 34 | -------------------------------------------------------------------------------- /api-docs/requirements.txt: -------------------------------------------------------------------------------- 1 | mock 2 | -------------------------------------------------------------------------------- /batch-represent/batch-represent.lua: -------------------------------------------------------------------------------- 1 | local ffi = require 'ffi' 2 | 3 | local batchNumber, nImgs = 0 4 | 5 | torch.setdefaulttensortype('torch.FloatTensor') 6 | 7 | function batchRepresent() 8 | local loadSize = {3, opt.imgDim, opt.imgDim} 9 | print(opt.data) 10 | local cacheFile = paths.concat(opt.data, 'cache.t7') 11 | print('cache lotation: ', cacheFile) 12 | local dumpLoader 13 | if paths.filep(cacheFile) then 14 | print('Loading metadata from cache.') 15 | print('If your dataset has changed, delete the cache file.') 16 | dumpLoader = torch.load(cacheFile) 17 | else 18 | print('Creating metadata for cache.') 19 | dumpLoader = dataLoader{ 20 | paths = {opt.data}, 21 | loadSize = loadSize, 22 | sampleSize = loadSize, 23 | split = 0, 24 | verbose = true 25 | } 26 | torch.save(cacheFile, dumpLoader) 27 | end 28 | collectgarbage() 29 | nImgs = dumpLoader:sizeTest() 30 | print('nImgs: ', nImgs) 31 | assert(nImgs > 0, "Failed to get nImgs") 32 | 33 | batchNumber = 0 34 | 35 | for i=1,math.ceil(nImgs/opt.batchSize) do 36 | local indexStart = (i-1) * opt.batchSize + 1 37 | local indexEnd = math.min(nImgs, indexStart + opt.batchSize - 1) 38 | local batchSz = indexEnd-indexStart+1 39 | local inputs, labels = dumpLoader:get(indexStart, indexEnd) 40 | local paths = {} 41 | for j=indexStart,indexEnd do 42 | table.insert(paths, 43 | ffi.string(dumpLoader.imagePath[dumpLoader.testIndices[j]]:data())) 44 | end 45 | repBatch(paths, inputs, labels, batchSz) 46 | if i % 5 == 0 then 47 | collectgarbage() 48 | end 49 | end 50 | 51 | if opt.cuda then 52 | cutorch.synchronize() 53 | end 54 | end 55 | 56 | function repBatch(paths, inputs, labels, batchSz) 57 | batchNumber = batchNumber + batchSz 58 | 59 | if opt.cuda then 60 | inputs = inputs:cuda() 61 | end 62 | local embeddings = model:forward(inputs):float() 63 | if opt.cuda then 64 | cutorch.synchronize() 65 | end 66 | 67 | if batchSz == 1 then 68 | embeddings = embeddings:reshape(1, embeddings:size(1)) 69 | end 70 | 71 | for i=1,batchSz do 72 | labelsCSV:write({labels[i], paths[i]}) 73 | repsCSV:write(embeddings[i]:totable()) 74 | end 75 | 76 | print(('Represent: %d/%d'):format(batchNumber, nImgs)) 77 | end 78 | -------------------------------------------------------------------------------- /batch-represent/main.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env th 2 | 3 | require 'torch' 4 | require 'optim' 5 | 6 | require 'paths' 7 | 8 | require 'xlua' 9 | require 'csvigo' 10 | 11 | require 'nn' 12 | require 'dpnn' 13 | 14 | local opts = paths.dofile('opts.lua') 15 | 16 | opt = opts.parse(arg) 17 | print(opt) 18 | 19 | torch.setdefaulttensortype('torch.FloatTensor') 20 | 21 | if opt.cuda then 22 | require 'cutorch' 23 | require 'cunn' 24 | cutorch.setDevice(opt.device) 25 | end 26 | 27 | opt.manualSeed = 2 28 | torch.manualSeed(opt.manualSeed) 29 | 30 | paths.dofile('dataset.lua') 31 | paths.dofile('batch-represent.lua') 32 | 33 | model = torch.load(opt.model) 34 | model:evaluate() 35 | if opt.cuda then 36 | model:cuda() 37 | end 38 | 39 | repsCSV = csvigo.File(paths.concat(opt.outDir, "reps.csv"), 'w') 40 | labelsCSV = csvigo.File(paths.concat(opt.outDir, "labels.csv"), 'w') 41 | 42 | batchRepresent() 43 | 44 | repsCSV:close() 45 | labelsCSV:close() 46 | -------------------------------------------------------------------------------- /batch-represent/opts.lua: -------------------------------------------------------------------------------- 1 | local M = { } 2 | 3 | -- http://stackoverflow.com/questions/6380820/get-containing-path-of-lua-file 4 | function script_path() 5 | local str = debug.getinfo(2, "S").source:sub(2) 6 | return str:match("(.*/)") 7 | end 8 | 9 | function M.parse(arg) 10 | local cmd = torch.CmdLine() 11 | cmd:text() 12 | cmd:text('OpenFace') 13 | cmd:text() 14 | cmd:text('Options:') 15 | 16 | ------------ General options -------------------- 17 | cmd:option('-outDir', './reps/', 'Subdirectory to output the representations') 18 | cmd:option('-data', 19 | paths.concat(script_path(), '..', 'data', 'lfw', 'dlib-affine-sz:96'), 20 | 'Home of dataset') 21 | cmd:option('-model', 22 | paths.concat(script_path(), '..', 'models', 'openface', 'nn4.small2.v1.t7'), 23 | 'Path to model to use.') 24 | cmd:option('-imgDim', 96, 'Image dimension. nn1=224, nn4=96') 25 | cmd:option('-batchSize', 50, 'mini-batch size') 26 | cmd:option('-cuda', false, 'Use cuda') 27 | cmd:option('-device', 1, 'Cuda device to use') 28 | cmd:option('-cache', false, 'Cache loaded data.') 29 | cmd:text() 30 | 31 | local opt = cmd:parse(arg or {}) 32 | os.execute('mkdir -p ' .. opt.outDir) 33 | 34 | return opt 35 | end 36 | 37 | return M 38 | -------------------------------------------------------------------------------- /cloc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cloc batch-represent evaluation openface models training util \ 4 | demos/*.py \ 5 | demos/web/{*.{py,html,sh},js,css} 6 | -------------------------------------------------------------------------------- /conversion/test_luatorch.lua: -------------------------------------------------------------------------------- 1 | require 'nn' 2 | require 'dpnn' 3 | 4 | torch.setdefaulttensortype('torch.FloatTensor') 5 | model = torch.load('/root/openface/models/openface/nn4.small2.v1.t7') 6 | model.save('nn4.small2.v1.resaved.t7') 7 | 8 | model:evaluate() 9 | ones = torch.ones(1,3,96,96) 10 | x = model:forward(ones) 11 | torch.save('l'..tostring(#model.modules)..'out.t7',x) 12 | 13 | 14 | for i=#model.modules,2,-1 do 15 | model:remove(i) 16 | x = model:forward(ones) 17 | torch.save('l'..tostring(i-1)..'out.t7',x) 18 | end 19 | -------------------------------------------------------------------------------- /data/casia-facescrub/remove-lfw-names.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | import os 4 | import shutil 5 | 6 | lfwDir = '../lfw/raw' 7 | lfwNames = os.listdir(lfwDir) 8 | lfwNames = [name.replace("_", "").lower() for name in lfwNames] 9 | 10 | names = os.listdir('raw') 11 | 12 | 13 | def inLfw(name): 14 | name = name.strip().lower() 15 | for lfwName in lfwNames: 16 | if lfwName == name: 17 | # print("(lfwName, name): ({}, {})".format(lfwName, name)) 18 | return True 19 | return False 20 | 21 | for name in names: 22 | if inLfw(name): 23 | print('Deleting: {}'.format(name)) 24 | shutil.rmtree(os.path.join('raw', name)) 25 | -------------------------------------------------------------------------------- /data/download-lfw-subset.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Download data. 3 | 4 | cd "$(dirname "$0")" 5 | 6 | die() { 7 | echo >&2 $* 8 | exit 1 9 | } 10 | 11 | checkCmd() { 12 | command -v $1 >/dev/null 2>&1 \ 13 | || die "'$1' command not found. Please install from your package manager." 14 | } 15 | 16 | checkCmd wget 17 | checkCmd tar 18 | 19 | printf "\n\n====================================================\n" 20 | printf "Downloading lfw-a (subset of people with name starting with A)" 21 | printf "====================================================\n\n" 22 | rm -rf lfw-subset 23 | mkdir -p lfw-subset 24 | cd lfw-subset 25 | wget -nv http://vis-www.cs.umass.edu/lfw/lfw-a.tgz 26 | [ $? -eq 0 ] || ( rm lfw-a.tgz && die "+ lfw-a: Error in wget." ) 27 | 28 | printf "\n\n====================================================\n" 29 | printf "Verifying checksums.\n" 30 | printf "====================================================\n\n" 31 | 32 | md5str() { 33 | local FNAME=$1 34 | case $(uname) in 35 | "Linux") 36 | echo $(md5sum "$FNAME" | cut -d ' ' -f 1) 37 | ;; 38 | "Darwin") 39 | echo $(md5 -q "$FNAME") 40 | ;; 41 | esac 42 | } 43 | 44 | checkmd5() { 45 | local FNAME=$1 46 | local EXPECTED=$2 47 | local ACTUAL=$(md5str "$FNAME") 48 | if [ $EXPECTED == $ACTUAL ]; then 49 | printf "+ $FNAME: successfully checked\n" 50 | else 51 | printf "+ ERROR! $FNAME md5sum did not match.\n" 52 | printf " + Expected: $EXPECTED\n" 53 | printf " + Actual: $ACTUAL\n" 54 | printf " + Please manually delete this file and try re-running this script.\n" 55 | return -1 56 | fi 57 | printf "\n" 58 | } 59 | 60 | set -e 61 | 62 | checkmd5 \ 63 | lfw-a.tgz \ 64 | 678b1f67c300002fedafbb0705d22e8d 65 | 66 | tar xf lfw-a.tgz 67 | mkdir raw 68 | mv lfw/{Ann_Veneman,Adrien_Brody,Anna_Kournikova} raw 69 | rm -rf lfw 70 | 71 | rm lfw-a.tgz 72 | -------------------------------------------------------------------------------- /data/ms-celeb-1m/extract.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright 2016 Carnegie Mellon University 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # 18 | # This script extracts the MS-Celeb-1M TSV file into images on disk. 19 | # For more information, see http://arxiv.org/abs/1607.08221 and http://msceleb.com 20 | # 21 | # Brandon Amos 22 | # 2016-07-29 23 | 24 | import argparse 25 | import base64 26 | import csv 27 | import os 28 | # import magic # Detect image type from buffer contents (disabled, all are jpg) 29 | 30 | parser = argparse.ArgumentParser() 31 | parser.add_argument('croppedTSV', type=str) 32 | parser.add_argument('--outputDir', type=str, default='raw') 33 | args = parser.parse_args() 34 | 35 | with open(args.croppedTSV, 'r') as tsvF: 36 | reader = csv.reader(tsvF, delimiter='\t') 37 | i = 0 38 | for row in reader: 39 | MID, imgSearchRank, faceID, data = row[0], row[1], row[4], base64.b64decode(row[-1]) 40 | 41 | saveDir = os.path.join(args.outputDir, MID) 42 | savePath = os.path.join(saveDir, "{}-{}.jpg".format(imgSearchRank, faceID)) 43 | 44 | # assert(magic.from_buffer(data) == 'JPEG image data, JFIF standard 1.01') 45 | 46 | os.makedirs(saveDir, exist_ok=True) 47 | with open(savePath, 'wb') as f: 48 | f.write(data) 49 | 50 | i += 1 51 | 52 | if i % 1000 == 0: 53 | print("Extracted {} images.".format(i)) 54 | -------------------------------------------------------------------------------- /data/vgg/download-and-align.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # 3 | # Copyright 2015-2016 Carnegie Mellon University 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # 18 | # This script downloads the VGG Face Dataset from 19 | # http://www.robots.ox.ac.uk/~vgg/data/vgg_face/ 20 | # and aligns the images with OpenFace. 21 | # 22 | # Brandon Amos 23 | # 2016-02-29 24 | 25 | import argparse 26 | import cv2 27 | import dlib 28 | import os 29 | import urllib2 30 | import hashlib 31 | 32 | from multiprocessing import Pool 33 | 34 | import openface 35 | from openface.helper import mkdirP 36 | 37 | fileDir = os.path.dirname(os.path.realpath(__file__)) 38 | modelDir = os.path.join(fileDir, '..', '..', 'models') 39 | dlibModelDir = os.path.join(modelDir, 'dlib') 40 | openfaceModelDir = os.path.join(modelDir, 'openface') 41 | 42 | landmarkIndices = openface.AlignDlib.OUTER_EYES_AND_NOSE 43 | 44 | parser = argparse.ArgumentParser() 45 | parser.add_argument('--dlibFacePredictor', type=str, help="Path to dlib's face predictor.", 46 | default=os.path.join(dlibModelDir, "shape_predictor_68_face_landmarks.dat")) 47 | parser.add_argument("--txt", help="VGG's directory of text files of people with images.", 48 | default='raw-txt') 49 | parser.add_argument("--raw", help="Directory to save raw images to.", 50 | default='raw') 51 | parser.add_argument("--aligned", help="Directory to save aligned images to.", 52 | default='aligned') 53 | 54 | args = parser.parse_args() 55 | 56 | align = openface.AlignDlib(args.dlibFacePredictor) 57 | 58 | jobs = [] 59 | for person in os.listdir(args.txt): 60 | fullPersonPath = os.path.join(args.txt, person) 61 | with open(fullPersonPath, 'r') as f: 62 | contents = f.readlines() 63 | 64 | for line in contents: 65 | id, uid, url, l, t, r, b, pose, detection, curation = line.split() 66 | l, t, r, b = [int(float(x)) for x in [l, t, r, b]] 67 | # if int(curation) == 1: 68 | jobs.append((person[:-4], url, (l, t, r, b))) 69 | 70 | 71 | def download(person, url, bb): 72 | imgName = os.path.basename(url) 73 | rawPersonPath = os.path.join(args.raw, person) 74 | rawImgPath = os.path.join(rawPersonPath, imgName) 75 | alignedPersonPath = os.path.join(args.aligned, person) 76 | alignedImgPath = os.path.join(alignedPersonPath, 77 | hashlib.md5(imgName).hexdigest() + ".png") 78 | 79 | mkdirP(rawPersonPath) 80 | mkdirP(alignedPersonPath) 81 | 82 | if not os.path.isfile(rawImgPath): 83 | urlF = urllib2.urlopen(url, timeout=5) 84 | with open(rawImgPath, 'wb') as f: 85 | f.write(urlF.read()) 86 | 87 | if not os.path.isfile(alignedImgPath): 88 | bgr = cv2.imread(rawImgPath) 89 | if bgr is None: 90 | return 91 | 92 | rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB) 93 | 94 | dlibBB = dlib.rectangle(*bb) 95 | outRgb = align.align(96, rgb, 96 | bb=dlibBB, 97 | landmarkIndices=landmarkIndices) 98 | 99 | if outRgb is not None: 100 | outBgr = cv2.cvtColor(outRgb, cv2.COLOR_RGB2BGR) 101 | cv2.imwrite(alignedImgPath, outBgr) 102 | 103 | 104 | def download_packed(args): 105 | try: 106 | download(*args) 107 | except Exception as e: 108 | print("\n".join((str(args), str(e)))) 109 | pass 110 | 111 | pool = Pool(16) 112 | pool.map(download_packed, jobs) 113 | -------------------------------------------------------------------------------- /demos/compare.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # 3 | # Example to compare the faces in two images. 4 | # Brandon Amos 5 | # 2015/09/29 6 | # 7 | # Copyright 2015-2016 Carnegie Mellon University 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | 21 | import time 22 | 23 | start = time.time() 24 | 25 | import argparse 26 | import cv2 27 | import itertools 28 | import os 29 | 30 | import numpy as np 31 | np.set_printoptions(precision=2) 32 | 33 | import openface 34 | 35 | fileDir = os.path.dirname(os.path.realpath(__file__)) 36 | modelDir = os.path.join(fileDir, '..', 'models') 37 | dlibModelDir = os.path.join(modelDir, 'dlib') 38 | openfaceModelDir = os.path.join(modelDir, 'openface') 39 | 40 | parser = argparse.ArgumentParser() 41 | 42 | parser.add_argument('imgs', type=str, nargs='+', help="Input images.") 43 | parser.add_argument('--dlibFacePredictor', type=str, help="Path to dlib's face predictor.", 44 | default=os.path.join(dlibModelDir, "shape_predictor_68_face_landmarks.dat")) 45 | parser.add_argument('--networkModel', type=str, help="Path to Torch network model.", 46 | default=os.path.join(openfaceModelDir, 'nn4.small2.v1.t7')) 47 | parser.add_argument('--imgDim', type=int, 48 | help="Default image dimension.", default=96) 49 | parser.add_argument('--verbose', action='store_true') 50 | 51 | args = parser.parse_args() 52 | 53 | if args.verbose: 54 | print("Argument parsing and loading libraries took {} seconds.".format( 55 | time.time() - start)) 56 | 57 | start = time.time() 58 | align = openface.AlignDlib(args.dlibFacePredictor) 59 | net = openface.TorchNeuralNet(args.networkModel, args.imgDim) 60 | if args.verbose: 61 | print("Loading the dlib and OpenFace models took {} seconds.".format( 62 | time.time() - start)) 63 | 64 | 65 | def getRep(imgPath): 66 | if args.verbose: 67 | print("Processing {}.".format(imgPath)) 68 | bgrImg = cv2.imread(imgPath) 69 | if bgrImg is None: 70 | raise Exception("Unable to load image: {}".format(imgPath)) 71 | rgbImg = cv2.cvtColor(bgrImg, cv2.COLOR_BGR2RGB) 72 | 73 | if args.verbose: 74 | print(" + Original size: {}".format(rgbImg.shape)) 75 | 76 | start = time.time() 77 | bb = align.getLargestFaceBoundingBox(rgbImg) 78 | if bb is None: 79 | raise Exception("Unable to find a face: {}".format(imgPath)) 80 | if args.verbose: 81 | print(" + Face detection took {} seconds.".format(time.time() - start)) 82 | 83 | start = time.time() 84 | alignedFace = align.align(args.imgDim, rgbImg, bb, 85 | landmarkIndices=openface.AlignDlib.OUTER_EYES_AND_NOSE) 86 | if alignedFace is None: 87 | raise Exception("Unable to align image: {}".format(imgPath)) 88 | if args.verbose: 89 | print(" + Face alignment took {} seconds.".format(time.time() - start)) 90 | 91 | start = time.time() 92 | rep = net.forward(alignedFace) 93 | if args.verbose: 94 | print(" + OpenFace forward pass took {} seconds.".format(time.time() - start)) 95 | print("Representation:") 96 | print(rep) 97 | print("-----\n") 98 | return rep 99 | 100 | for (img1, img2) in itertools.combinations(args.imgs, 2): 101 | d = getRep(img1) - getRep(img2) 102 | print("Comparing {} with {}.".format(img1, img2)) 103 | print( 104 | " + Squared l2 distance between representations: {:0.3f}".format(np.dot(d, d))) 105 | -------------------------------------------------------------------------------- /demos/vis-outputs.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env th 2 | -- 3 | -- Copyright 2015-2016 Carnegie Mellon University 4 | -- 5 | -- Licensed under the Apache License, Version 2.0 (the "License"); 6 | -- you may not use this file except in compliance with the License. 7 | -- You may obtain a copy of the License at 8 | -- 9 | -- http://www.apache.org/licenses/LICENSE-2.0 10 | -- 11 | -- Unless required by applicable law or agreed to in writing, software 12 | -- distributed under the License is distributed on an "AS IS" BASIS, 13 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | -- See the License for the specific language governing permissions and 15 | -- limitations under the License. 16 | 17 | require 'torch' 18 | require 'nn' 19 | require 'dpnn' 20 | require 'image' 21 | require 'paths' 22 | 23 | torch.setdefaulttensortype('torch.FloatTensor') 24 | 25 | local cmd = torch.CmdLine() 26 | cmd:text() 27 | cmd:text('Visualize OpenFace outputs.') 28 | cmd:text() 29 | cmd:text('Options:') 30 | 31 | cmd:option('-imgPath', 'images/examples-aligned/lennon-1.png', 32 | 'Path to aligned image.') 33 | cmd:option('-filterOutput', 34 | 'images/examples-aligned/lennon-1', 35 | 'Output directory.') 36 | cmd:option('-model', './models/openface/nn4.small2.v1.t7', 'Path to model.') 37 | cmd:option('-imgDim', 96, 'Image dimension. nn1=224, nn4=96') 38 | cmd:option('-numPreview', 39, 'Number of images to preview') 39 | cmd:text() 40 | 41 | opt = cmd:parse(arg or {}) 42 | -- print(opt) 43 | 44 | os.execute('mkdir -p ' .. opt.filterOutput) 45 | 46 | if not paths.filep(opt.imgPath) then 47 | print("Unable to find: " .. opt.imgPath) 48 | os.exit(-1) 49 | end 50 | 51 | net = torch.load(opt.model) 52 | net:evaluate() 53 | print(net) 54 | 55 | local img = torch.Tensor(1, 3, opt.imgDim, opt.imgDim) 56 | local img_orig = image.load(opt.imgPath, 3) 57 | img[1] = image.scale(img_orig, opt.imgDim, opt.imgDim) 58 | net:forward(img) 59 | 60 | local fName = opt.filterOutput .. '/preview.html' 61 | print("Outputting filter preview to '" .. fName .. "'") 62 | f, err = io.open(fName, 'w') 63 | if err then 64 | print("Error: Unable to open preview.html"); 65 | os.exit(-1) 66 | end 67 | 68 | torch.IntTensor({3, 7, 10, 11, 12, 13, 14, 15, 16, 69 | 17, 18, 19, 20, 21}):apply(function (i) 70 | os.execute(string.format('mkdir -p %s/%s', 71 | opt.filterOutput, i)) 72 | out = net.modules[i].output[1] 73 | f:write(string.format("

Layer %s

\n", i)) 74 | for j = 1,out:size(1) do 75 | imgName = string.format('%s/%d/%d.png', 76 | opt.filterOutput, i, j) 77 | image.save(imgName, out[j]) 78 | if j <= opt.numPreview then 79 | f:write(string.format("\n", 80 | i, j)) 81 | end 82 | end 83 | end) 84 | -------------------------------------------------------------------------------- /demos/web/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "openface-web-demo", 3 | "version": "0.0.0", 4 | "homepage": "https://github.com/cmusatyalab/openface", 5 | "authors": [ 6 | "Brandon Amos " 7 | ], 8 | "license": "Apache", 9 | "ignore": [ 10 | "**/.*", 11 | "bower_components" 12 | ], 13 | "dependencies": { 14 | "bootstrap": "3.3.5", 15 | "bootstrap-toggle": "2.2.0", 16 | "font-awesome": "~4.3.0", 17 | "handlebars": "~3.0.0", 18 | "bootstrap3-dialog": "1.35.*", 19 | "underscore": "1.8.3" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /demos/web/create-cert.sh: -------------------------------------------------------------------------------- 1 | # generate self-signed certs with no password for the web and socket servers 2 | # this script requires that openssl is installed: e.g. sudo apt-get install openssl 3 | mkdir tls 4 | openssl genrsa -des3 -out tls/server.key 1024 5 | openssl req -new -key tls/server.key -out tls/server.csr 6 | cp tls/server.key tls/server.key.org 7 | openssl rsa -in tls/server.key.org -out tls/server.key 8 | openssl x509 -req -days 3650 -in tls/server.csr -signkey tls/server.key -out tls/server.crt 9 | echo 'converting to pem' 10 | cat tls/server.crt tls/server.key > tls/server.pem 11 | echo 'cert complete' 12 | -------------------------------------------------------------------------------- /demos/web/create-unknown-vectors.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # 3 | # Copyright 2015-2016 Carnegie Mellon University 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import sys 18 | sys.path.append(".") 19 | 20 | import argparse 21 | import numpy as np 22 | import os 23 | import random 24 | 25 | import cv2 26 | 27 | import openface 28 | from openface.data import iterImgs 29 | 30 | fileDir = os.path.dirname(os.path.realpath(__file__)) 31 | modelDir = os.path.join(fileDir, '..', 'models') 32 | dlibModelDir = os.path.join(modelDir, 'dlib') 33 | openfaceModelDir = os.path.join(modelDir, 'openface') 34 | 35 | parser = argparse.ArgumentParser() 36 | parser.add_argument('imgDir', type=str, help="Input image directory.") 37 | parser.add_argument('--numImages', type=int, default=1000) 38 | parser.add_argument('--model', type=str, help="TODO", 39 | default=os.path.join(openfaceModelDir, 'nn4.small2.v1.t7')) 40 | parser.add_argument('--dlibFacePredictor', type=str, help="Path to dlib's face predictor.", 41 | default=os.path.join(dlibModelDir, "shape_predictor_68_face_landmarks.dat")) 42 | parser.add_argument('--outputFile', type=str, 43 | help="Output file, stored in numpy serialized format.", 44 | default="./unknown.npy") 45 | parser.add_argument('--imgDim', type=int, help="Default image size.", 46 | default=96) 47 | args = parser.parse_args() 48 | 49 | align = openface.AlignDlib(args.dlibFacePredictor) 50 | net = openface.TorchNeuralNet(args.model, imgDim=args.imgDim, cuda=False) 51 | 52 | 53 | def getRep(imgPath): 54 | bgrImg = cv2.imread(imgPath) 55 | if bgrImg is None: 56 | return None 57 | rgbImg = cv2.cvtColor(bgrImg, cv2.COLOR_BGR2RGB) 58 | 59 | bb = align.getLargestFaceBoundingBox(rgbImg) 60 | if bb is None: 61 | return None 62 | 63 | alignedFace = align.align(args.imgDim, rgbImg, bb) 64 | if alignedFace is None: 65 | return None 66 | 67 | rep = net.forward(alignedFace) 68 | return rep 69 | 70 | if __name__ == '__main__': 71 | allImgs = list(iterImgs(args.imgDir)) 72 | imgObjs = random.sample(allImgs, args.numImages) 73 | 74 | reps = [] 75 | for imgObj in imgObjs: 76 | rep = getRep(imgObj.path) 77 | 78 | if rep is not None: 79 | reps.append(rep) 80 | 81 | np.save(args.outputFile, np.row_stack(reps)) 82 | -------------------------------------------------------------------------------- /demos/web/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 10px; 3 | height: 100%; 4 | font-family: Georgia, "Times New Roman", Times, serif; 5 | color: #555; 6 | } 7 | 8 | #videoel { 9 | -o-transform : scaleX(-1); 10 | -webkit-transform : scaleX(-1); 11 | transform : scaleX(-1); 12 | -ms-filter : fliph; /*IE*/ 13 | filter : fliph; /*IE*/ 14 | } 15 | 16 | h1, .h1, h2, .h2, h3, .h3, { 17 | margin-top: 0; 18 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 19 | font-weight: normal; 20 | color: #333; 21 | } 22 | 23 | @media (min-width: 1200px) { 24 | .container { 25 | width: 970px; 26 | } 27 | } 28 | 29 | .addPersonDiv{ 30 | max-width: 330px; 31 | } 32 | 33 | img { 34 | padding: 0; 35 | margin: 0; 36 | } 37 | 38 | .container .header { 39 | text-align: center; 40 | top: 0; 41 | bottom: 330px; 42 | position: absolute; 43 | right: 0; 44 | left: 0; 45 | margin-left: auto; 46 | margin-right: auto; 47 | margin-bottom: 10px; 48 | width: 80%; 49 | height: 310px; 50 | /* overflow-y: scroll; */ 51 | } 52 | 53 | .container .content { 54 | top: 350px; 55 | bottom: 0; 56 | position: absolute; 57 | right: 0; 58 | left: 0; 59 | margin: auto; 60 | width: 80%; 61 | height: auto; 62 | overflow-y: scroll; 63 | } 64 | 65 | a.remove { 66 | color: red; 67 | font-size: 2em; 68 | } 69 | 70 | ul.tabs{ 71 | margin: 0px; 72 | padding: 0px; 73 | list-style: none; 74 | } 75 | ul.tabs li{ 76 | background: none; 77 | display: inline-block; 78 | padding: 10px 15px; 79 | cursor: pointer; 80 | } 81 | 82 | ul.tabs li.current{ 83 | background: #cceeff; 84 | color: #222; 85 | } 86 | 87 | .tab-content{ 88 | display: none; 89 | /* background: #ededed; */ 90 | /* padding: 15px; */ 91 | } 92 | 93 | .tab-content.current{ 94 | display: inherit; 95 | } -------------------------------------------------------------------------------- /demos/web/examples.md: -------------------------------------------------------------------------------- 1 | + https://github.com/auduno/clmtrackr 2 | + http://inspirit.github.io/jsfeat/sample_bbf_face.html 3 | -------------------------------------------------------------------------------- /demos/web/favicon.ico: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /demos/web/images/FacerecWebDemo.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmusatyalab/openface/051475225b5ae335918621077313085bbb7ab5a0/demos/web/images/FacerecWebDemo.ai -------------------------------------------------------------------------------- /demos/web/install-deps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x -e 4 | 5 | sudo apt-get update 6 | sudo apt-get install -y libprotobuf-dev libleveldb-dev libsnappy-dev \ 7 | libopencv-dev libhdf5-serial-dev libboost-all-dev libgflags-dev \ 8 | libgoogle-glog-dev liblmdb-dev protobuf-compiler libboost-all-dev \ 9 | libatlas-dev libatlas-base-dev liblapack-dev libblas-dev \ 10 | libssl-dev libffi-dev python-pip python-numpy python-imaging \ 11 | python-openssl python-opencv \ 12 | git wget cmake gfortran 13 | 14 | mkdir -p ~/src 15 | cd ~/src 16 | git clone https://github.com/bvlc/caffe.git 17 | wget https://github.com/davisking/dlib/releases/download/v18.16/dlib-18.16.tar.bz2 18 | -------------------------------------------------------------------------------- /demos/web/js/utils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Provides requestAnimationFrame in a cross browser way. 3 | */ 4 | window.requestAnimFrame = (function() { 5 | return window.requestAnimationFrame || 6 | window.webkitRequestAnimationFrame || 7 | window.mozRequestAnimationFrame || 8 | window.oRequestAnimationFrame || 9 | window.msRequestAnimationFrame || 10 | function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) { 11 | return window.setTimeout(callback, 1000/60); 12 | }; 13 | })(); 14 | -------------------------------------------------------------------------------- /demos/web/requirements.txt: -------------------------------------------------------------------------------- 1 | autobahn == 0.10.4 2 | imagehash == 1.0 3 | twisted == 15.2.1 4 | scipy >= 0.13, < 0.17 5 | scikit-learn >= 0.17, < 0.18 6 | protobuf >= 2.5, < 2.7 7 | appdirs >= 1.4.3 8 | pyOpenSSL >= 17.0.0 9 | cryptography >= 1.8.1 10 | service-identity >= 16.0.0 11 | -------------------------------------------------------------------------------- /demos/web/simpleSSLServer.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import BaseHTTPServer 3 | import SimpleHTTPServer 4 | import ssl 5 | import sys 6 | 7 | 8 | '''Adopted from https://www.piware.de/2011/01/creating-an-https-server-in-python/''' 9 | 10 | 11 | def main(port): 12 | httpd = BaseHTTPServer.HTTPServer(('0.0.0.0', port), SimpleHTTPServer.SimpleHTTPRequestHandler) 13 | httpd.socket = ssl.wrap_socket(httpd.socket, certfile='tls/server.pem', server_side=True) 14 | print('now serving tls http on port:', port) 15 | httpd.serve_forever() 16 | 17 | if __name__ == '__main__': 18 | main(int(sys.argv[1])) 19 | -------------------------------------------------------------------------------- /demos/web/start-servers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e -u 4 | 5 | function die { echo $1; exit 42; } 6 | 7 | HTTP_PORT=8000 8 | WEBSOCKET_PORT=9000 9 | 10 | case $# in 11 | 0) ;; 12 | 1) HTTP_PORT=$1 13 | ;; 14 | 2) WEBSOCKET_PORT=$2 15 | ;; 16 | *) die "Usage: $0 " 17 | ;; 18 | esac 19 | 20 | cd $(dirname $0) 21 | trap 'kill $(jobs -p)' EXIT 22 | 23 | cat <:$HTTP_PORT. 32 | If you're running on a remote computer, find the IP address 33 | and use https://:$HTTP_PORT. 34 | 35 | WARNING: Chromium will warn on self-signed certificates. Please accept the certificate 36 | and reload the app. 37 | 38 | EOF 39 | 40 | WEBSOCKET_LOG='/tmp/openface.websocket.log' 41 | printf "WebSocket Server: Logging to '%s'\n\n" $WEBSOCKET_LOG 42 | 43 | python2 simpleSSLServer.py $HTTP_PORT &> /dev/null & 44 | 45 | cd ../../ # Root OpenFace directory. 46 | ./demos/web/websocket-server.py --port $WEBSOCKET_PORT 2>&1 | tee $WEBSOCKET_LOG & 47 | 48 | wait 49 | -------------------------------------------------------------------------------- /demos/web/tls/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICATCCAWoCCQC0Yl1TUb3gjzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB 3 | VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 4 | cyBQdHkgTHRkMB4XDTE3MDQzMDE2MDIxNFoXDTI3MDQyODE2MDIxNFowRTELMAkG 5 | A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 6 | IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEApnSL 7 | fpgnKHKCNypUxedbBMik02B40zlK5jQUqAt8ityNYM4DxZV2pOwS4RLfgDrWfLKV 8 | kOiBL+2iJmNWtc8fcU/4MnhAUCgYXvl+o3yFu8EVOLU+FXhlqJRAJOpqESMVa+II 9 | haXDSuLLnSA0e/UrxhDmWEiTGAkteWPLyEP7G6kCAwEAATANBgkqhkiG9w0BAQsF 10 | AAOBgQAwYgs2CrrCoknDs2p2bS/sEBc/cAWxlB3VA0yQXTAxh+6rLOYLwoF+z92w 11 | IbUhUkZss1r0k7zZDBZ32ZEB6Hc0+q4r599UVV3gF/2Ongc6rvtzJtRAv5EZza0d 12 | l3aaZ0aPu09XuDqv9cb/g+i/L7RgQgoEiEpK60WoTm9FeJ4Fpw== 13 | -----END CERTIFICATE----- 14 | -------------------------------------------------------------------------------- /demos/web/tls/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICWwIBAAKBgQCmdIt+mCcocoI3KlTF51sEyKTTYHjTOUrmNBSoC3yK3I1gzgPF 3 | lXak7BLhEt+AOtZ8spWQ6IEv7aImY1a1zx9xT/gyeEBQKBhe+X6jfIW7wRU4tT4V 4 | eGWolEAk6moRIxVr4giFpcNK4sudIDR79SvGEOZYSJMYCS15Y8vIQ/sbqQIDAQAB 5 | AoGAAM7D9oNKfVnA4/+ilas/t9A5bIUlUPEQOfm6t+4GVq4nSXb2cbj98GLs3Ia4 6 | 6uheLhC3xRI7vj3K8aC9xPgSUPpvdqEfef+SlfC7/lcHdtIfz1Fm2qtGdUERw2TC 7 | Iy1ttU58sDLK5dy1Igx9SeIPGMHCWemDw4CA0HVaplCIrPkCQQDRWl0HouUquzNd 8 | 7i6kk2uNKvj0Hdft5tGNdSk9diJU2d5kLravwXKxq9cFkoZ5g8bgxjGrdnguNO4y 9 | bcv/fN0LAkEAy4tED+0Etg0PLIXuYpHUjy5SGYpykaNx+Rfktv2lF5Uf2aDnh6Pv 10 | DObQEYF1NAZVcT8BsLGKta9RGFL7UJOSmwJAS3fgu2T8abgMH1tCUy+VgNEx54Zu 11 | laM0fWLz1+UjISVc5w5z6s24k9XXcHnOojVf1x17QE03q6iHCYTNGi+f2wJAXgfk 12 | VYclmgTGcccdraO5ErxPaUUwUF+1k2GaY38h+ZcGs79Ftr/g+5DVpoCr6HDUoBB/ 13 | c2VRs0VerWIIf9zs6QJAI0M7qCsyLw9z3wfMt8uZjGLokeSet9+LarJyRFkDVFow 14 | PBHMPvgU1+no5L+4A61cB9azn9zkIvchI2bSG0Ubgg== 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /demos/web/tls/server.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICATCCAWoCCQC0Yl1TUb3gjzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB 3 | VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 4 | cyBQdHkgTHRkMB4XDTE3MDQzMDE2MDIxNFoXDTI3MDQyODE2MDIxNFowRTELMAkG 5 | A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 6 | IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEApnSL 7 | fpgnKHKCNypUxedbBMik02B40zlK5jQUqAt8ityNYM4DxZV2pOwS4RLfgDrWfLKV 8 | kOiBL+2iJmNWtc8fcU/4MnhAUCgYXvl+o3yFu8EVOLU+FXhlqJRAJOpqESMVa+II 9 | haXDSuLLnSA0e/UrxhDmWEiTGAkteWPLyEP7G6kCAwEAATANBgkqhkiG9w0BAQsF 10 | AAOBgQAwYgs2CrrCoknDs2p2bS/sEBc/cAWxlB3VA0yQXTAxh+6rLOYLwoF+z92w 11 | IbUhUkZss1r0k7zZDBZ32ZEB6Hc0+q4r599UVV3gF/2Ongc6rvtzJtRAv5EZza0d 12 | l3aaZ0aPu09XuDqv9cb/g+i/L7RgQgoEiEpK60WoTm9FeJ4Fpw== 13 | -----END CERTIFICATE----- 14 | -----BEGIN RSA PRIVATE KEY----- 15 | MIICWwIBAAKBgQCmdIt+mCcocoI3KlTF51sEyKTTYHjTOUrmNBSoC3yK3I1gzgPF 16 | lXak7BLhEt+AOtZ8spWQ6IEv7aImY1a1zx9xT/gyeEBQKBhe+X6jfIW7wRU4tT4V 17 | eGWolEAk6moRIxVr4giFpcNK4sudIDR79SvGEOZYSJMYCS15Y8vIQ/sbqQIDAQAB 18 | AoGAAM7D9oNKfVnA4/+ilas/t9A5bIUlUPEQOfm6t+4GVq4nSXb2cbj98GLs3Ia4 19 | 6uheLhC3xRI7vj3K8aC9xPgSUPpvdqEfef+SlfC7/lcHdtIfz1Fm2qtGdUERw2TC 20 | Iy1ttU58sDLK5dy1Igx9SeIPGMHCWemDw4CA0HVaplCIrPkCQQDRWl0HouUquzNd 21 | 7i6kk2uNKvj0Hdft5tGNdSk9diJU2d5kLravwXKxq9cFkoZ5g8bgxjGrdnguNO4y 22 | bcv/fN0LAkEAy4tED+0Etg0PLIXuYpHUjy5SGYpykaNx+Rfktv2lF5Uf2aDnh6Pv 23 | DObQEYF1NAZVcT8BsLGKta9RGFL7UJOSmwJAS3fgu2T8abgMH1tCUy+VgNEx54Zu 24 | laM0fWLz1+UjISVc5w5z6s24k9XXcHnOojVf1x17QE03q6iHCYTNGi+f2wJAXgfk 25 | VYclmgTGcccdraO5ErxPaUUwUF+1k2GaY38h+ZcGs79Ftr/g+5DVpoCr6HDUoBB/ 26 | c2VRs0VerWIIf9zs6QJAI0M7qCsyLw9z3wfMt8uZjGLokeSet9+LarJyRFkDVFow 27 | PBHMPvgU1+no5L+4A61cB9azn9zkIvchI2bSG0Ubgg== 28 | -----END RSA PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /demos/web/update-vendor-deps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x -e 4 | 5 | bower install 6 | 7 | rm -rf vendor 8 | mkdir -p vendor/{css,fonts,js} 9 | 10 | cp -r bower_components/bootstrap/dist/* vendor 11 | cp -r bower_components/bootstrap-toggle/css/*.min.css* vendor/css 12 | cp -r bower_components/bootstrap-toggle/js/*.min.js* vendor/js 13 | cp -r bower_components/bootstrap3-dialog/dist/* vendor 14 | cp -r bower_components/font-awesome/* vendor 15 | 16 | cp bower_components/jquery/dist/* vendor/js 17 | cp bower_components/handlebars/handlebars.min.js vendor/js 18 | cp bower_components/underscore/underscore-min.js vendor/js 19 | 20 | wget https://raw.githubusercontent.com/jstat/jstat/1.3.0/dist/jstat.min.js -P vendor/js 21 | -------------------------------------------------------------------------------- /demos/web/vendor/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "font-awesome", 3 | "description": "Font Awesome", 4 | "version": "4.3.0", 5 | "keywords": [], 6 | "homepage": "http://fontawesome.io", 7 | "dependencies": {}, 8 | "devDependencies": {}, 9 | "license": ["OFL-1.1", "MIT", "CC-BY-3.0"], 10 | "main": [ 11 | "./css/font-awesome.css", 12 | "./fonts/*" 13 | ], 14 | "ignore": [ 15 | "*/.*", 16 | "*.json", 17 | "src", 18 | "*.yml", 19 | "Gemfile", 20 | "Gemfile.lock", 21 | "*.md" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /demos/web/vendor/css/bootstrap-dialog.css: -------------------------------------------------------------------------------- 1 | .bootstrap-dialog { 2 | /* dialog types */ 3 | /** 4 | * Icon animation 5 | * Copied from font-awesome: http://fontawesome.io/ 6 | **/ 7 | /** End of icon animation **/ 8 | } 9 | .bootstrap-dialog .modal-header { 10 | border-top-left-radius: 4px; 11 | border-top-right-radius: 4px; 12 | } 13 | .bootstrap-dialog .bootstrap-dialog-title { 14 | color: #fff; 15 | display: inline-block; 16 | font-size: 16px; 17 | } 18 | .bootstrap-dialog .bootstrap-dialog-message { 19 | font-size: 14px; 20 | } 21 | .bootstrap-dialog .bootstrap-dialog-button-icon { 22 | margin-right: 3px; 23 | } 24 | .bootstrap-dialog .bootstrap-dialog-close-button { 25 | font-size: 20px; 26 | float: right; 27 | filter: alpha(opacity=90); 28 | -moz-opacity: 0.9; 29 | -khtml-opacity: 0.9; 30 | opacity: 0.9; 31 | } 32 | .bootstrap-dialog .bootstrap-dialog-close-button:hover { 33 | cursor: pointer; 34 | filter: alpha(opacity=100); 35 | -moz-opacity: 1; 36 | -khtml-opacity: 1; 37 | opacity: 1; 38 | } 39 | .bootstrap-dialog.type-default .modal-header { 40 | background-color: #fff; 41 | } 42 | .bootstrap-dialog.type-default .bootstrap-dialog-title { 43 | color: #333; 44 | } 45 | .bootstrap-dialog.type-info .modal-header { 46 | background-color: #5bc0de; 47 | } 48 | .bootstrap-dialog.type-primary .modal-header { 49 | background-color: #428bca; 50 | } 51 | .bootstrap-dialog.type-success .modal-header { 52 | background-color: #5cb85c; 53 | } 54 | .bootstrap-dialog.type-warning .modal-header { 55 | background-color: #f0ad4e; 56 | } 57 | .bootstrap-dialog.type-danger .modal-header { 58 | background-color: #d9534f; 59 | } 60 | .bootstrap-dialog.size-large .bootstrap-dialog-title { 61 | font-size: 24px; 62 | } 63 | .bootstrap-dialog.size-large .bootstrap-dialog-close-button { 64 | font-size: 30px; 65 | } 66 | .bootstrap-dialog.size-large .bootstrap-dialog-message { 67 | font-size: 18px; 68 | } 69 | .bootstrap-dialog .icon-spin { 70 | display: inline-block; 71 | -moz-animation: spin 2s infinite linear; 72 | -o-animation: spin 2s infinite linear; 73 | -webkit-animation: spin 2s infinite linear; 74 | animation: spin 2s infinite linear; 75 | } 76 | @-moz-keyframes spin { 77 | 0% { 78 | -moz-transform: rotate(0deg); 79 | } 80 | 100% { 81 | -moz-transform: rotate(359deg); 82 | } 83 | } 84 | @-webkit-keyframes spin { 85 | 0% { 86 | -webkit-transform: rotate(0deg); 87 | } 88 | 100% { 89 | -webkit-transform: rotate(359deg); 90 | } 91 | } 92 | @-o-keyframes spin { 93 | 0% { 94 | -o-transform: rotate(0deg); 95 | } 96 | 100% { 97 | -o-transform: rotate(359deg); 98 | } 99 | } 100 | @-ms-keyframes spin { 101 | 0% { 102 | -ms-transform: rotate(0deg); 103 | } 104 | 100% { 105 | -ms-transform: rotate(359deg); 106 | } 107 | } 108 | @keyframes spin { 109 | 0% { 110 | transform: rotate(0deg); 111 | } 112 | 100% { 113 | transform: rotate(359deg); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /demos/web/vendor/css/bootstrap-dialog.min.css: -------------------------------------------------------------------------------- 1 | .bootstrap-dialog .modal-header{border-top-left-radius:4px;border-top-right-radius:4px}.bootstrap-dialog .bootstrap-dialog-title{color:#fff;display:inline-block;font-size:16px}.bootstrap-dialog .bootstrap-dialog-message{font-size:14px}.bootstrap-dialog .bootstrap-dialog-button-icon{margin-right:3px}.bootstrap-dialog .bootstrap-dialog-close-button{font-size:20px;float:right;filter:alpha(opacity=90);-moz-opacity:.9;-khtml-opacity:.9;opacity:.9}.bootstrap-dialog .bootstrap-dialog-close-button:hover{cursor:pointer;filter:alpha(opacity=100);-moz-opacity:1;-khtml-opacity:1;opacity:1}.bootstrap-dialog.type-default .modal-header{background-color:#fff}.bootstrap-dialog.type-default .bootstrap-dialog-title{color:#333}.bootstrap-dialog.type-info .modal-header{background-color:#5bc0de}.bootstrap-dialog.type-primary .modal-header{background-color:#428bca}.bootstrap-dialog.type-success .modal-header{background-color:#5cb85c}.bootstrap-dialog.type-warning .modal-header{background-color:#f0ad4e}.bootstrap-dialog.type-danger .modal-header{background-color:#d9534f}.bootstrap-dialog.size-large .bootstrap-dialog-title{font-size:24px}.bootstrap-dialog.size-large .bootstrap-dialog-close-button{font-size:30px}.bootstrap-dialog.size-large .bootstrap-dialog-message{font-size:18px}.bootstrap-dialog .icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)}100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}} -------------------------------------------------------------------------------- /demos/web/vendor/css/bootstrap-toggle.min.css: -------------------------------------------------------------------------------- 1 | /*! ======================================================================== 2 | * Bootstrap Toggle: bootstrap-toggle.css v2.2.0 3 | * http://www.bootstraptoggle.com 4 | * ======================================================================== 5 | * Copyright 2014 Min Hur, The New York Times Company 6 | * Licensed under MIT 7 | * ======================================================================== */ 8 | .checkbox label .toggle,.checkbox-inline .toggle{margin-left:-20px;margin-right:5px} 9 | .toggle{position:relative;overflow:hidden} 10 | .toggle input[type=checkbox]{display:none} 11 | .toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;-moz-user-select:none;-webkit-user-select:none} 12 | .toggle.off .toggle-group{left:-100%} 13 | .toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0} 14 | .toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0} 15 | .toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px} 16 | .toggle.btn{min-width:59px;min-height:34px} 17 | .toggle-on.btn{padding-right:24px} 18 | .toggle-off.btn{padding-left:24px} 19 | .toggle.btn-lg{min-width:79px;min-height:45px} 20 | .toggle-on.btn-lg{padding-right:31px} 21 | .toggle-off.btn-lg{padding-left:31px} 22 | .toggle-handle.btn-lg{width:40px} 23 | .toggle.btn-sm{min-width:50px;min-height:30px} 24 | .toggle-on.btn-sm{padding-right:20px} 25 | .toggle-off.btn-sm{padding-left:20px} 26 | .toggle.btn-xs{min-width:35px;min-height:22px} 27 | .toggle-on.btn-xs{padding-right:12px} 28 | .toggle-off.btn-xs{padding-left:12px} -------------------------------------------------------------------------------- /demos/web/vendor/css/bootstrap2-toggle.min.css: -------------------------------------------------------------------------------- 1 | /*! ======================================================================== 2 | * Bootstrap Toggle: bootstrap2-toggle.css v2.2.0 3 | * http://www.bootstraptoggle.com 4 | * ======================================================================== 5 | * Copyright 2014 Min Hur, The New York Times Company 6 | * Licensed under MIT 7 | * ======================================================================== */ 8 | label.checkbox .toggle,label.checkbox.inline .toggle{margin-left:-20px;margin-right:5px} 9 | .toggle{min-width:40px;height:20px;position:relative;overflow:hidden} 10 | .toggle input[type=checkbox]{display:none} 11 | .toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;-moz-user-select:none;-webkit-user-select:none} 12 | .toggle.off .toggle-group{left:-100%} 13 | .toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0} 14 | .toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0} 15 | .toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px} 16 | .toggle-handle.btn-mini{top:-1px} 17 | .toggle.btn{min-width:30px} 18 | .toggle-on.btn{padding-right:24px} 19 | .toggle-off.btn{padding-left:24px} 20 | .toggle.btn-large{min-width:40px} 21 | .toggle-on.btn-large{padding-right:35px} 22 | .toggle-off.btn-large{padding-left:35px} 23 | .toggle.btn-small{min-width:25px} 24 | .toggle-on.btn-small{padding-right:20px} 25 | .toggle-off.btn-small{padding-left:20px} 26 | .toggle.btn-mini{min-width:20px} 27 | .toggle-on.btn-mini{padding-right:12px} 28 | .toggle-off.btn-mini{padding-left:12px} -------------------------------------------------------------------------------- /demos/web/vendor/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmusatyalab/openface/051475225b5ae335918621077313085bbb7ab5a0/demos/web/vendor/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /demos/web/vendor/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmusatyalab/openface/051475225b5ae335918621077313085bbb7ab5a0/demos/web/vendor/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /demos/web/vendor/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmusatyalab/openface/051475225b5ae335918621077313085bbb7ab5a0/demos/web/vendor/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /demos/web/vendor/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmusatyalab/openface/051475225b5ae335918621077313085bbb7ab5a0/demos/web/vendor/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /demos/web/vendor/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmusatyalab/openface/051475225b5ae335918621077313085bbb7ab5a0/demos/web/vendor/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /demos/web/vendor/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmusatyalab/openface/051475225b5ae335918621077313085bbb7ab5a0/demos/web/vendor/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /demos/web/vendor/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmusatyalab/openface/051475225b5ae335918621077313085bbb7ab5a0/demos/web/vendor/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /demos/web/vendor/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmusatyalab/openface/051475225b5ae335918621077313085bbb7ab5a0/demos/web/vendor/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /demos/web/vendor/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmusatyalab/openface/051475225b5ae335918621077313085bbb7ab5a0/demos/web/vendor/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /demos/web/vendor/js/bootstrap-toggle.min.js: -------------------------------------------------------------------------------- 1 | /*! ======================================================================== 2 | * Bootstrap Toggle: bootstrap-toggle.js v2.2.0 3 | * http://www.bootstraptoggle.com 4 | * ======================================================================== 5 | * Copyright 2014 Min Hur, The New York Times Company 6 | * Licensed under MIT 7 | * ======================================================================== */ 8 | +function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.toggle"),f="object"==typeof b&&b;e||d.data("bs.toggle",e=new c(this,f)),"string"==typeof b&&e[b]&&e[b]()})}var c=function(b,c){this.$element=a(b),this.options=a.extend({},this.defaults(),c),this.render()};c.VERSION="2.2.0",c.DEFAULTS={on:"On",off:"Off",onstyle:"primary",offstyle:"default",size:"normal",style:"",width:null,height:null},c.prototype.defaults=function(){return{on:this.$element.attr("data-on")||c.DEFAULTS.on,off:this.$element.attr("data-off")||c.DEFAULTS.off,onstyle:this.$element.attr("data-onstyle")||c.DEFAULTS.onstyle,offstyle:this.$element.attr("data-offstyle")||c.DEFAULTS.offstyle,size:this.$element.attr("data-size")||c.DEFAULTS.size,style:this.$element.attr("data-style")||c.DEFAULTS.style,width:this.$element.attr("data-width")||c.DEFAULTS.width,height:this.$element.attr("data-height")||c.DEFAULTS.height}},c.prototype.render=function(){this._onstyle="btn-"+this.options.onstyle,this._offstyle="btn-"+this.options.offstyle;var b="large"===this.options.size?"btn-lg":"small"===this.options.size?"btn-sm":"mini"===this.options.size?"btn-xs":"",c=a('