diff --git "a/201601450132 16\347\247\221\344\270\200 \345\217\266\345\277\227\346\203\240.docx" "b/201601450132 16\347\247\221\344\270\200 \345\217\266\345\277\227\346\203\240.docx" new file mode 100644 index 0000000000000000000000000000000000000000..83908abb391d9883eb8634b8d7296589a5c5fb74 Binary files /dev/null and "b/201601450132 16\347\247\221\344\270\200 \345\217\266\345\277\227\346\203\240.docx" differ diff --git "a/201601450133 \345\206\267\351\262\201\344\270\275\350\256\241\347\256\227\346\234\272\347\247\221\345\255\246\344\270\216\346\212\200\346\234\257\344\270\200\347\217\255.docx" "b/201601450133 \345\206\267\351\262\201\344\270\275\350\256\241\347\256\227\346\234\272\347\247\221\345\255\246\344\270\216\346\212\200\346\234\257\344\270\200\347\217\255.docx" new file mode 100644 index 0000000000000000000000000000000000000000..53d9eb69436e9dfab47c134ec5d82bf7b9a1e789 Binary files /dev/null and "b/201601450133 \345\206\267\351\262\201\344\270\275\350\256\241\347\256\227\346\234\272\347\247\221\345\255\246\344\270\216\346\212\200\346\234\257\344\270\200\347\217\255.docx" differ diff --git a/GroupList.md b/GroupList.md index 0564ac07c71c0d8123fdc6b2cf368fa7be3ee58e..72b768e5cbb01a491a965de42b83a186713786ba 100644 --- a/GroupList.md +++ b/GroupList.md @@ -1,17 +1,19 @@ # 下面是计科期末考试分组情况 ------------------------- -* 组长 王* (题目:利用openCV进行人脸识别签到) +* 组长 王政霖 (题目:face_recognition人脸识别) * 组员及各自分工: -1. 刘**,负责调试程序,用例图 -2. 李**,负责类图 -3. 于**,负责协作图 -4. 陈*,负责配置图 - +1. 王政霖,创建仓库,推送了新的分支master并邀请成员加入,用GIT GUI进行源代码上传同时对程序进行调试,负责顺序图 +2. 冷鲁丽,对程序运行环境进行配置环境并阅读代码,负责协作图 +3. 李晓梅,将源代码导入到python,观察运行状态对出现的错误报告进行解读,结合断点操做进行相应处理,负责构件图 +4. 乔岩岩,运行程序观察并检测程序结果是否正确如果有差异则对程序进行调整,负责用例图 +6. 王冬雨,阅读程序同时对组内有疑惑的代码进行学习后进行讲解对运行时的错误进行排除解决,负责状态图 +6. 叶志惠,下载并安装dlib库并学习如何使用,阅读代码,负责活动图 +7. 张文丹,阅读代码,整理全组不理解的代码,进行学习解答,负责部署图、组件图 * 进度计划 -1. 10月份:搜集资料,了解opencv视觉库以及Java语言的用法 +1. 10月份:搜集资料,了解python语言的用法 2. 11月份:配置程序开发环境,共同调试程序代码 3. 12月份:调试程序,上传程序代码 4. 1月份:画出UML图 * 项目地址 - \ No newline at end of file +https://gitee.com/w719027299/uml_library \ No newline at end of file diff --git "a/UML\346\264\273\345\212\250\345\233\276.jpg" "b/UML\346\264\273\345\212\250\345\233\276.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..af55148116dd109b2ea5b1a64be1ee38d0c24dcf Binary files /dev/null and "b/UML\346\264\273\345\212\250\345\233\276.jpg" differ diff --git "a/UML\347\224\250\344\276\213\345\233\276.jpg" "b/UML\347\224\250\344\276\213\345\233\276.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..d2efe34ed4c5e663cad1763f43856d5df4e10def Binary files /dev/null and "b/UML\347\224\250\344\276\213\345\233\276.jpg" differ diff --git a/face_recognition-master/.editorconfig b/face_recognition-master/.editorconfig new file mode 100644 index 0000000000000000000000000000000000000000..d4a2c4405ec2e962c521a13af91bf5f7098a62a8 --- /dev/null +++ b/face_recognition-master/.editorconfig @@ -0,0 +1,21 @@ +# http://editorconfig.org + +root = true + +[*] +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true +insert_final_newline = true +charset = utf-8 +end_of_line = lf + +[*.bat] +indent_style = tab +end_of_line = crlf + +[LICENSE] +insert_final_newline = false + +[Makefile] +indent_style = tab diff --git a/face_recognition-master/.github/ISSUE_TEMPLATE.md b/face_recognition-master/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000000000000000000000000000000000..0aabe506d951127badcac1a7ebdd8b3c347e39b0 --- /dev/null +++ b/face_recognition-master/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,16 @@ +* face_recognition version: +* Python version: +* Operating System: + +### Description + +Describe what you were trying to get done. +Tell us what happened, what went wrong, and what you expected to happen. +IMPORTANT: If your issue is related to a specific picture, include it so others can reproduce the issue. + +### What I Did + +``` +Paste the command(s) you ran and the output. +If there was a crash, please include the traceback here. +``` diff --git a/face_recognition-master/.gitignore b/face_recognition-master/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..72408e29d2911d4e124ce538adc9cf2426033096 --- /dev/null +++ b/face_recognition-master/.gitignore @@ -0,0 +1,65 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# 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/ + +# Translations +*.mo +*.pot +.DS_Store + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# pyenv python configuration file +.python-version + +.idea/ diff --git a/face_recognition-master/.travis.yml b/face_recognition-master/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..6bb102ab79428053e932dce69b6cd85302e8e30f --- /dev/null +++ b/face_recognition-master/.travis.yml @@ -0,0 +1,26 @@ +dist: trusty +sudo: required +language: python +python: + - "2.7" + - "3.4" + - "3.5" + - "3.6" + +before_install: +- sudo apt-get -qq update +- sudo apt-get install -qq cmake python-numpy python-scipy libboost-python-dev +- pip install git+https://github.com/ageitgey/face_recognition_models + +install: + - pip install -r requirements.txt + - pip install tox-travis + +script: tox + +# Temporary for Python 3.7 +matrix: + include: + - python: 3.7 + dist: xenial + sudo: true diff --git a/face_recognition-master/AUTHORS.rst b/face_recognition-master/AUTHORS.rst new file mode 100644 index 0000000000000000000000000000000000000000..3aebe86ce487dac09859562c652f3950533cd54a --- /dev/null +++ b/face_recognition-master/AUTHORS.rst @@ -0,0 +1,16 @@ +======= +Authors +======= + +* Adam Geitgey + +Thanks +------ + +* Many, many thanks to Davis King (@nulhom) + for creating dlib and for providing the trained facial feature detection and face encoding models + used in this library. +* Thanks to everyone who works on all the awesome Python data science libraries like numpy, scipy, scikit-image, + pillow, etc, etc that makes this kind of stuff so easy and fun in Python. +* Thanks to Cookiecutter and the audreyr/cookiecutter-pypackage project template + for making Python project packaging way more tolerable. diff --git a/face_recognition-master/CONTRIBUTING.rst b/face_recognition-master/CONTRIBUTING.rst new file mode 100644 index 0000000000000000000000000000000000000000..8498ebdd12a402923751b16123d5eced52c873d3 --- /dev/null +++ b/face_recognition-master/CONTRIBUTING.rst @@ -0,0 +1,95 @@ +.. highlight:: shell + +============ +Contributing +============ + +Contributions are welcome, and they are greatly appreciated! Every +little bit helps, and credit will always be given. + +You can contribute in many ways: + +Types of Contributions +---------------------- + +Report Bugs +~~~~~~~~~~~ + +Report bugs at https://github.com/ageitgey/face_recognition/issues. + +If you are reporting a bug, please include: + +* Your operating system name and version. +* Any details about your local setup that might be helpful in troubleshooting. +* Detailed steps to reproduce the bug. + +Submit Feedback +~~~~~~~~~~~~~~~ + +The best way to send feedback is to file an issue at https://github.com/ageitgey/face_recognition/issues. + +If you are proposing a feature: + +* Explain in detail how it would work. +* Keep the scope as narrow as possible, to make it easier to implement. +* Remember that this is a volunteer-driven project, and that contributions + are welcome :) + +Get Started! +------------ + +Ready to contribute? Here's how to set up `face_recognition` for local development. + +1. Fork the `face_recognition` repo on GitHub. +2. Clone your fork locally:: + + $ git clone git@github.com:your_name_here/face_recognition.git + +3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:: + + $ mkvirtualenv face_recognition + $ cd face_recognition/ + $ python setup.py develop + +4. Create a branch for local development:: + + $ git checkout -b name-of-your-bugfix-or-feature + + Now you can make your changes locally. + +5. When you're done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox:: + + $ flake8 face_recognition tests + $ python setup.py test or py.test + $ tox + + To get flake8 and tox, just pip install them into your virtualenv. + +6. Commit your changes and push your branch to GitHub:: + + $ git add . + $ git commit -m "Your detailed description of your changes." + $ git push origin name-of-your-bugfix-or-feature + +7. Submit a pull request through the GitHub website. + +Pull Request Guidelines +----------------------- + +Before you submit a pull request, check that it meets these guidelines: + +1. The pull request should include tests. +2. If the pull request adds functionality, the docs should be updated. Put + your new functionality into a function with a docstring, and add the + feature to the list in README.rst. +3. The pull request should work for Python 2.6, 2.7, 3.3, 3.4 and 3.5, and for PyPy. Check + https://travis-ci.org/ageitgey/face_recognition/pull_requests + and make sure that the tests pass for all supported Python versions. + +Tips +---- + +To run a subset of tests:: + + + $ python -m unittest tests.test_face_recognition diff --git a/face_recognition-master/Dockerfile b/face_recognition-master/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..0ffc7e6fa36d54724a9836900e87ae181a8c164f --- /dev/null +++ b/face_recognition-master/Dockerfile @@ -0,0 +1,50 @@ +# This is a sample Dockerfile you can modify to deploy your own app based on face_recognition + +FROM python:3.6-slim-stretch + +RUN apt-get -y update +RUN apt-get install -y --fix-missing \ + build-essential \ + cmake \ + gfortran \ + git \ + wget \ + curl \ + graphicsmagick \ + libgraphicsmagick1-dev \ + libatlas-dev \ + libavcodec-dev \ + libavformat-dev \ + libgtk2.0-dev \ + libjpeg-dev \ + liblapack-dev \ + libswscale-dev \ + pkg-config \ + python3-dev \ + python3-numpy \ + software-properties-common \ + zip \ + && apt-get clean && rm -rf /tmp/* /var/tmp/* + +RUN cd ~ && \ + mkdir -p dlib && \ + git clone -b 'v19.9' --single-branch https://github.com/davisking/dlib.git dlib/ && \ + cd dlib/ && \ + python3 setup.py install --yes USE_AVX_INSTRUCTIONS + + +# The rest of this file just runs an example script. + +# If you wanted to use this Dockerfile to run your own app instead, maybe you would do this: +# COPY . /root/your_app_or_whatever +# RUN cd /root/your_app_or_whatever && \ +# pip3 install -r requirements.txt +# RUN whatever_command_you_run_to_start_your_app + +COPY . /root/face_recognition +RUN cd /root/face_recognition && \ + pip3 install -r requirements.txt && \ + python3 setup.py install + +CMD cd /root/face_recognition/examples && \ + python3 recognize_faces_in_pictures.py diff --git a/face_recognition-master/HISTORY.rst b/face_recognition-master/HISTORY.rst new file mode 100644 index 0000000000000000000000000000000000000000..9e9cb843d1483f47e1c4dd06a0e8e7fc4c092829 --- /dev/null +++ b/face_recognition-master/HISTORY.rst @@ -0,0 +1,125 @@ +History +======= + +1.2.3 (2018-08-21) +------------------ + +* You can now pass model="small" to face_landmarks() to use the 5-point face model instead of the 68-point model. +* Now officially supporting Python 3.7 +* New example of using this library in a Jupyter Notebook + +1.2.2 (2018-04-02) +------------------ + +* Added the face_detection CLI command +* Removed dependencies on scipy to make installation easier +* Cleaned up KNN example and fixed a bug with drawing fonts to label detected faces in the demo + + +1.2.1 (2018-02-01) +------------------ + +* Fixed version numbering inside of module code. + + +1.2.0 (2018-02-01) +------------------ + +* Fixed a bug where batch size parameter didn't work correctly when doing batch face detections on GPU. +* Updated OpenCV examples to do proper BGR -> RGB conversion +* Updated webcam examples to avoid common mistakes and reduce support questions +* Added a KNN classification example +* Added an example of automatically blurring faces in images or videos +* Updated Dockerfile example to use dlib v19.9 which removes the boost dependency. + + +1.1.0 (2017-09-23) +------------------ + +* Will use dlib's 5-point face pose estimator when possible for speed (instead of 68-point face pose esimator) +* dlib v19.7 is now the minimum required version +* face_recognition_models v0.3.0 is now the minimum required version + + +1.0.0 (2017-08-29) +------------------ + +* Added support for dlib's CNN face detection model via model="cnn" parameter on face detecion call +* Added support for GPU batched face detections using dlib's CNN face detector model +* Added find_faces_in_picture_cnn.py to examples +* Added find_faces_in_batches.py to examples +* Added face_rec_from_video_file.py to examples +* dlib v19.5 is now the minimum required version +* face_recognition_models v0.2.0 is now the minimum required version + + +0.2.2 (2017-07-07) +------------------ + +* Added --show-distance to cli +* Fixed a bug where --tolerance was ignored in cli if testing a single image +* Added benchmark.py to examples + + +0.2.1 (2017-07-03) +------------------ + +* Added --tolerance to cli + + +0.2.0 (2017-06-03) +------------------ + +* The CLI can now take advantage of multiple CPUs. Just pass in the -cpus X parameter where X is the number of CPUs to use. +* Added face_distance.py example +* Improved CLI tests to actually test the CLI functionality +* Updated facerec_on_raspberry_pi.py to capture in rgb (not bgr) format. + + +0.1.14 (2017-04-22) +------------------- + +* Fixed a ValueError crash when using the CLI on Python 2.7 + + +0.1.13 (2017-04-20) +------------------- + +* Raspberry Pi support. + + +0.1.12 (2017-04-13) +------------------- + +* Fixed: Face landmarks wasn't returning all chin points. + + +0.1.11 (2017-03-30) +------------------- + +* Fixed a minor bug in the command-line interface. + + +0.1.10 (2017-03-21) +------------------- + +* Minor pref improvements with face comparisons. +* Test updates. + + +0.1.9 (2017-03-16) +------------------ + +* Fix minimum scipy version required. + + +0.1.8 (2017-03-16) +------------------ + +* Fix missing Pillow dependency. + + +0.1.7 (2017-03-13) +------------------ + +* First working release. diff --git a/face_recognition-master/LICENSE b/face_recognition-master/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..696d0ce724be62971544c1f754433a37eb43d775 --- /dev/null +++ b/face_recognition-master/LICENSE @@ -0,0 +1,11 @@ + +MIT License + +Copyright (c) 2017, Adam Geitgey + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/face_recognition-master/MANIFEST.in b/face_recognition-master/MANIFEST.in new file mode 100644 index 0000000000000000000000000000000000000000..63895e797c2fd94cc0c2f5e3180b2d80a0cef285 --- /dev/null +++ b/face_recognition-master/MANIFEST.in @@ -0,0 +1,13 @@ + +include AUTHORS.rst + +include CONTRIBUTING.rst +include HISTORY.rst +include LICENSE +include README.rst + +recursive-include tests * +recursive-exclude * __pycache__ +recursive-exclude * *.py[co] + +recursive-include docs *.rst conf.py Makefile make.bat *.jpg *.png *.gif diff --git a/face_recognition-master/Makefile b/face_recognition-master/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..5af87c9f6d7df4cf6ebdccafcb40eb6a05f2b1d0 --- /dev/null +++ b/face_recognition-master/Makefile @@ -0,0 +1,87 @@ +.PHONY: clean clean-test clean-pyc clean-build docs help +.DEFAULT_GOAL := help +define BROWSER_PYSCRIPT +import os, webbrowser, sys +try: + from urllib import pathname2url +except: + from urllib.request import pathname2url + +webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1]))) +endef +export BROWSER_PYSCRIPT + +define PRINT_HELP_PYSCRIPT +import re, sys + +for line in sys.stdin: + match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line) + if match: + target, help = match.groups() + print("%-20s %s" % (target, help)) +endef +export PRINT_HELP_PYSCRIPT +BROWSER := python3 -c "$$BROWSER_PYSCRIPT" + +help: + @python3 -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST) + +clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts + + +clean-build: ## remove build artifacts + rm -fr build/ + rm -fr dist/ + rm -fr .eggs/ + find . -name '*.egg-info' -exec rm -fr {} + + find . -name '*.egg' -exec rm -f {} + + +clean-pyc: ## remove Python file artifacts + find . -name '*.pyc' -exec rm -f {} + + find . -name '*.pyo' -exec rm -f {} + + find . -name '*~' -exec rm -f {} + + find . -name '__pycache__' -exec rm -fr {} + + +clean-test: ## remove test and coverage artifacts + rm -fr .tox/ + rm -f .coverage + rm -fr htmlcov/ + +lint: ## check style with flake8 + flake8 face_recognition tests + +test: ## run tests quickly with the default Python + + python3 setup.py test + +test-all: ## run tests on every Python version with tox + tox + +coverage: ## check code coverage quickly with the default Python + + coverage run --source face_recognition setup.py test + + coverage report -m + coverage html + $(BROWSER) htmlcov/index.html + +docs: ## generate Sphinx HTML documentation, including API docs + sphinx-apidoc -o docs/ face_recognition + $(MAKE) -C docs clean + $(MAKE) -C docs html + $(BROWSER) docs/_build/html/index.html + +servedocs: docs ## compile the docs watching for changes + watchmedo shell-command -p '*.rst' -c '$(MAKE) -C docs html' -R -D . + +release: clean ## package and upload a release + python3 setup.py sdist upload + python3 setup.py bdist_wheel upload + +dist: clean ## builds source and wheel package + python3 setup.py sdist + python3 setup.py bdist_wheel + ls -l dist + +install: clean ## install the package to the active Python's site-packages + python3 setup.py install diff --git a/face_recognition-master/README.md b/face_recognition-master/README.md new file mode 100644 index 0000000000000000000000000000000000000000..142b10b3138e74177b39e2790cdb0860b50fb1df --- /dev/null +++ b/face_recognition-master/README.md @@ -0,0 +1,384 @@ +# Face Recognition + +_You can also read a translated version of this file [in Chinese 简体中文版](https://github.com/ageitgey/face_recognition/blob/master/README_Simplified_Chinese.md)._ + +Recognize and manipulate faces from Python or from the command line with +the world's simplest face recognition library. + +Built using [dlib](http://dlib.net/)'s state-of-the-art face recognition +built with deep learning. The model has an accuracy of 99.38% on the +[Labeled Faces in the Wild](http://vis-www.cs.umass.edu/lfw/) benchmark. + +This also provides a simple `face_recognition` command line tool that lets +you do face recognition on a folder of images from the command line! + + +[![PyPI](https://img.shields.io/pypi/v/face_recognition.svg)](https://pypi.python.org/pypi/face_recognition) +[![Build Status](https://travis-ci.org/ageitgey/face_recognition.svg?branch=master)](https://travis-ci.org/ageitgey/face_recognition) +[![Documentation Status](https://readthedocs.org/projects/face-recognition/badge/?version=latest)](http://face-recognition.readthedocs.io/en/latest/?badge=latest) + +## Features + +#### Find faces in pictures + +Find all the faces that appear in a picture: + +![](https://cloud.githubusercontent.com/assets/896692/23625227/42c65360-025d-11e7-94ea-b12f28cb34b4.png) + +```python +import face_recognition +image = face_recognition.load_image_file("your_file.jpg") +face_locations = face_recognition.face_locations(image) +``` + +#### Find and manipulate facial features in pictures + +Get the locations and outlines of each person's eyes, nose, mouth and chin. + +![](https://cloud.githubusercontent.com/assets/896692/23625282/7f2d79dc-025d-11e7-8728-d8924596f8fa.png) + +```python +import face_recognition +image = face_recognition.load_image_file("your_file.jpg") +face_landmarks_list = face_recognition.face_landmarks(image) +``` + +Finding facial features is super useful for lots of important stuff. But you can also use it for really stupid stuff +like applying [digital make-up](https://github.com/ageitgey/face_recognition/blob/master/examples/digital_makeup.py) (think 'Meitu'): + +![](https://cloud.githubusercontent.com/assets/896692/23625283/80638760-025d-11e7-80a2-1d2779f7ccab.png) + +#### Identify faces in pictures + +Recognize who appears in each photo. + +![](https://cloud.githubusercontent.com/assets/896692/23625229/45e049b6-025d-11e7-89cc-8a71cf89e713.png) + +```python +import face_recognition +known_image = face_recognition.load_image_file("biden.jpg") +unknown_image = face_recognition.load_image_file("unknown.jpg") + +biden_encoding = face_recognition.face_encodings(known_image)[0] +unknown_encoding = face_recognition.face_encodings(unknown_image)[0] + +results = face_recognition.compare_faces([biden_encoding], unknown_encoding) +``` + +You can even use this library with other Python libraries to do real-time face recognition: + +![](https://cloud.githubusercontent.com/assets/896692/24430398/36f0e3f0-13cb-11e7-8258-4d0c9ce1e419.gif) + +See [this example](https://github.com/ageitgey/face_recognition/blob/master/examples/facerec_from_webcam_faster.py) for the code. + +## Installation + +### Requirements + + * Python 3.3+ or Python 2.7 + * macOS or Linux (Windows not officially supported, but might work) + +### Installation Options: + +#### Installing on Mac or Linux + +First, make sure you have dlib already installed with Python bindings: + + * [How to install dlib from source on macOS or Ubuntu](https://gist.github.com/ageitgey/629d75c1baac34dfa5ca2a1928a7aeaf) + +Then, install this module from pypi using `pip3` (or `pip2` for Python 2): + +```bash +pip3 install face_recognition +``` + +If you are having trouble with installation, you can also try out a +[pre-configured VM](https://medium.com/@ageitgey/try-deep-learning-in-python-now-with-a-fully-pre-configured-vm-1d97d4c3e9b). + +#### Installing on Raspberry Pi 2+ + + * [Raspberry Pi 2+ installation instructions](https://gist.github.com/ageitgey/1ac8dbe8572f3f533df6269dab35df65) + +#### Installing on Windows + +While Windows isn't officially supported, helpful users have posted instructions on how to install this library: + + * [@masoudr's Windows 10 installation guide (dlib + face_recognition)](https://github.com/ageitgey/face_recognition/issues/175#issue-257710508) + +#### Installing a pre-configured Virtual Machine image + + * [Download the pre-configured VM image](https://medium.com/@ageitgey/try-deep-learning-in-python-now-with-a-fully-pre-configured-vm-1d97d4c3e9b) (for VMware Player or VirtualBox). + +## Usage + +### Command-Line Interface + +When you install `face_recognition`, you get two simple command-line +programs: + +* `face_recognition` - Recognize faces in a photograph or folder full for + photographs. +* `face_detection` - Find faces in a photograph or folder full for photographs. + +#### `face_recognition` command line tool + +The `face_recognition` command lets you recognize faces in a photograph or +folder full for photographs. + +First, you need to provide a folder with one picture of each person you +already know. There should be one image file for each person with the +files named according to who is in the picture: + +![known](https://cloud.githubusercontent.com/assets/896692/23582466/8324810e-00df-11e7-82cf-41515eba704d.png) + +Next, you need a second folder with the files you want to identify: + +![unknown](https://cloud.githubusercontent.com/assets/896692/23582465/81f422f8-00df-11e7-8b0d-75364f641f58.png) + +Then in you simply run the command `face_recognition`, passing in +the folder of known people and the folder (or single image) with unknown +people and it tells you who is in each image: + +```bash +$ face_recognition ./pictures_of_people_i_know/ ./unknown_pictures/ + +/unknown_pictures/unknown.jpg,Barack Obama +/face_recognition_test/unknown_pictures/unknown.jpg,unknown_person +``` + +There's one line in the output for each face. The data is comma-separated +with the filename and the name of the person found. + +An `unknown_person` is a face in the image that didn't match anyone in +your folder of known people. + +#### `face_detection` command line tool + +The `face_detection` command lets you find the location (pixel coordinatates) +of any faces in an image. + +Just run the command `face_detection`, passing in a folder of images +to check (or a single image): + +```bash +$ face_detection ./folder_with_pictures/ + +examples/image1.jpg,65,215,169,112 +examples/image2.jpg,62,394,211,244 +examples/image2.jpg,95,941,244,792 +``` + +It prints one line for each face that was detected. The coordinates +reported are the top, right, bottom and left coordinates of the face (in pixels). + +##### Adjusting Tolerance / Sensitivity + +If you are getting multiple matches for the same person, it might be that +the people in your photos look very similar and a lower tolerance value +is needed to make face comparisons more strict. + +You can do that with the `--tolerance` parameter. The default tolerance +value is 0.6 and lower numbers make face comparisons more strict: + +```bash +$ face_recognition --tolerance 0.54 ./pictures_of_people_i_know/ ./unknown_pictures/ + +/unknown_pictures/unknown.jpg,Barack Obama +/face_recognition_test/unknown_pictures/unknown.jpg,unknown_person +``` + +If you want to see the face distance calculated for each match in order +to adjust the tolerance setting, you can use `--show-distance true`: + +```bash +$ face_recognition --show-distance true ./pictures_of_people_i_know/ ./unknown_pictures/ + +/unknown_pictures/unknown.jpg,Barack Obama,0.378542298956785 +/face_recognition_test/unknown_pictures/unknown.jpg,unknown_person,None +``` + +##### More Examples + +If you simply want to know the names of the people in each photograph but don't +care about file names, you could do this: + +```bash +$ face_recognition ./pictures_of_people_i_know/ ./unknown_pictures/ | cut -d ',' -f2 + +Barack Obama +unknown_person +``` + +##### Speeding up Face Recognition + +Face recognition can be done in parallel if you have a computer with +multiple CPU cores. For example, if your system has 4 CPU cores, you can +process about 4 times as many images in the same amount of time by using +all your CPU cores in parallel. + +If you are using Python 3.4 or newer, pass in a `--cpus ` parameter: + +```bash +$ face_recognition --cpus 4 ./pictures_of_people_i_know/ ./unknown_pictures/ +``` + +You can also pass in `--cpus -1` to use all CPU cores in your system. + +#### Python Module + +You can import the `face_recognition` module and then easily manipulate +faces with just a couple of lines of code. It's super easy! + +API Docs: [https://face-recognition.readthedocs.io](https://face-recognition.readthedocs.io/en/latest/face_recognition.html). + +##### Automatically find all the faces in an image + +```python +import face_recognition + +image = face_recognition.load_image_file("my_picture.jpg") +face_locations = face_recognition.face_locations(image) + +# face_locations is now an array listing the co-ordinates of each face! +``` + +See [this example](https://github.com/ageitgey/face_recognition/blob/master/examples/find_faces_in_picture.py) + to try it out. + +You can also opt-in to a somewhat more accurate deep-learning-based face detection model. + +Note: GPU acceleration (via NVidia's CUDA library) is required for good +performance with this model. You'll also want to enable CUDA support +when compliling `dlib`. + +```python +import face_recognition + +image = face_recognition.load_image_file("my_picture.jpg") +face_locations = face_recognition.face_locations(image, model="cnn") + +# face_locations is now an array listing the co-ordinates of each face! +``` + +See [this example](https://github.com/ageitgey/face_recognition/blob/master/examples/find_faces_in_picture_cnn.py) + to try it out. + +If you have a lot of images and a GPU, you can also +[find faces in batches](https://github.com/ageitgey/face_recognition/blob/master/examples/find_faces_in_batches.py). + +##### Automatically locate the facial features of a person in an image + +```python +import face_recognition + +image = face_recognition.load_image_file("my_picture.jpg") +face_landmarks_list = face_recognition.face_landmarks(image) + +# face_landmarks_list is now an array with the locations of each facial feature in each face. +# face_landmarks_list[0]['left_eye'] would be the location and outline of the first person's left eye. +``` + +See [this example](https://github.com/ageitgey/face_recognition/blob/master/examples/find_facial_features_in_picture.py) + to try it out. + +##### Recognize faces in images and identify who they are + +```python +import face_recognition + +picture_of_me = face_recognition.load_image_file("me.jpg") +my_face_encoding = face_recognition.face_encodings(picture_of_me)[0] + +# my_face_encoding now contains a universal 'encoding' of my facial features that can be compared to any other picture of a face! + +unknown_picture = face_recognition.load_image_file("unknown.jpg") +unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0] + +# Now we can see the two face encodings are of the same person with `compare_faces`! + +results = face_recognition.compare_faces([my_face_encoding], unknown_face_encoding) + +if results[0] == True: + print("It's a picture of me!") +else: + print("It's not a picture of me!") +``` + +See [this example](https://github.com/ageitgey/face_recognition/blob/master/examples/recognize_faces_in_pictures.py) + to try it out. + +## Python Code Examples + +All the examples are available [here](https://github.com/ageitgey/face_recognition/tree/master/examples). + + +#### Face Detection + +* [Find faces in a photograph](https://github.com/ageitgey/face_recognition/blob/master/examples/find_faces_in_picture.py) +* [Find faces in a photograph (using deep learning)](https://github.com/ageitgey/face_recognition/blob/master/examples/find_faces_in_picture_cnn.py) +* [Find faces in batches of images w/ GPU (using deep learning)](https://github.com/ageitgey/face_recognition/blob/master/examples/find_faces_in_batches.py) +* [Blur all the faces in a live video using your webcam (Requires OpenCV to be installed)](https://github.com/ageitgey/face_recognition/blob/master/examples/blur_faces_on_webcam.py) + +#### Facial Features + +* [Identify specific facial features in a photograph](https://github.com/ageitgey/face_recognition/blob/master/examples/find_facial_features_in_picture.py) +* [Apply (horribly ugly) digital make-up](https://github.com/ageitgey/face_recognition/blob/master/examples/digital_makeup.py) + +#### Facial Recognition + +* [Find and recognize unknown faces in a photograph based on photographs of known people](https://github.com/ageitgey/face_recognition/blob/master/examples/recognize_faces_in_pictures.py) +* [Identify and draw boxes around each person in a photo](https://github.com/ageitgey/face_recognition/blob/master/examples/identify_and_draw_boxes_on_faces.py) +* [Compare faces by numeric face distance instead of only True/False matches](https://github.com/ageitgey/face_recognition/blob/master/examples/face_distance.py) +* [Recognize faces in live video using your webcam - Simple / Slower Version (Requires OpenCV to be installed)](https://github.com/ageitgey/face_recognition/blob/master/examples/facerec_from_webcam.py) +* [Recognize faces in live video using your webcam - Faster Version (Requires OpenCV to be installed)](https://github.com/ageitgey/face_recognition/blob/master/examples/facerec_from_webcam_faster.py) +* [Recognize faces in a video file and write out new video file (Requires OpenCV to be installed)](https://github.com/ageitgey/face_recognition/blob/master/examples/facerec_from_video_file.py) +* [Recognize faces on a Raspberry Pi w/ camera](https://github.com/ageitgey/face_recognition/blob/master/examples/facerec_on_raspberry_pi.py) +* [Run a web service to recognize faces via HTTP (Requires Flask to be installed)](https://github.com/ageitgey/face_recognition/blob/master/examples/web_service_example.py) +* [Recognize faces with a K-nearest neighbors classifier](https://github.com/ageitgey/face_recognition/blob/master/examples/face_recognition_knn.py) + +## Articles and Guides that cover `face_recognition` + +- My article on how Face Recognition works: [Modern Face Recognition with Deep Learning](https://medium.com/@ageitgey/machine-learning-is-fun-part-4-modern-face-recognition-with-deep-learning-c3cffc121d78) + - Covers the algorithms and how they generally work +- [Face recognition with OpenCV, Python, and deep learning](https://www.pyimagesearch.com/2018/06/18/face-recognition-with-opencv-python-and-deep-learning/) by Adrian Rosebrock + - Covers how to use face recognition in practice +- [Raspberry Pi Face Recognition](https://www.pyimagesearch.com/2018/06/25/raspberry-pi-face-recognition/) by Adrian Rosebrock + - Covers how to use this on a Raspberry Pi +- [Face clustering with Python](https://www.pyimagesearch.com/2018/07/09/face-clustering-with-python/) by Adrian Rosebrock + - Covers how to automatically cluster photos based on who appears in each photo using unsupervised learning + +## How Face Recognition Works + +If you want to learn how face location and recognition work instead of +depending on a black box library, [read my article](https://medium.com/@ageitgey/machine-learning-is-fun-part-4-modern-face-recognition-with-deep-learning-c3cffc121d78). + +## Caveats + +* The face recognition model is trained on adults and does not work very well on children. It tends to mix + up children quite easy using the default comparison threshold of 0.6. +* Accuracy may vary between ethnic groups. Please see [this wiki page](https://github.com/ageitgey/face_recognition/wiki/Face-Recognition-Accuracy-Problems#question-face-recognition-works-well-with-european-individuals-but-overall-accuracy-is-lower-with-asian-individuals) for more details. + +## Deployment to Cloud Hosts (Heroku, AWS, etc) + +Since `face_recognition` depends on `dlib` which is written in C++, it can be tricky to deploy an app +using it to a cloud hosting provider like Heroku or AWS. + +To make things easier, there's an example Dockerfile in this repo that shows how to run an app built with +`face_recognition` in a [Docker](https://www.docker.com/) container. With that, you should be able to deploy +to any service that supports Docker images. + +## Having problems? + +If you run into problems, please read the [Common Errors](https://github.com/ageitgey/face_recognition/wiki/Common-Errors) section of the wiki before filing a github issue. + +## Thanks + +* Many, many thanks to [Davis King](https://github.com/davisking) ([@nulhom](https://twitter.com/nulhom)) + for creating dlib and for providing the trained facial feature detection and face encoding models + used in this library. For more information on the ResNet that powers the face encodings, check out + his [blog post](http://blog.dlib.net/2017/02/high-quality-face-recognition-with-deep.html). +* Thanks to everyone who works on all the awesome Python data science libraries like numpy, scipy, scikit-image, + pillow, etc, etc that makes this kind of stuff so easy and fun in Python. +* Thanks to [Cookiecutter](https://github.com/audreyr/cookiecutter) and the + [audreyr/cookiecutter-pypackage](https://github.com/audreyr/cookiecutter-pypackage) project template + for making Python project packaging way more tolerable. diff --git a/face_recognition-master/README.rst b/face_recognition-master/README.rst new file mode 100644 index 0000000000000000000000000000000000000000..16edc6c13aa10168220fc411c22f3ac77fc3a38d --- /dev/null +++ b/face_recognition-master/README.rst @@ -0,0 +1,492 @@ +Face Recognition +================ + +| Recognize and manipulate faces from Python or from the command line + with +| the world's simplest face recognition library. + +| Built using `dlib `__'s state-of-the-art face + recognition +| built with deep learning. The model has an accuracy of 99.38% on the +| `Labeled Faces in the Wild `__ + benchmark. + +| This also provides a simple ``face_recognition`` command line tool + that lets +| you do face recognition on a folder of images from the command line! + +| |PyPI| +| |Build Status| +| |Documentation Status| + +Features +-------- + +Find faces in pictures +^^^^^^^^^^^^^^^^^^^^^^ + +Find all the faces that appear in a picture: + +|image3| + +.. code:: python + + import face_recognition + image = face_recognition.load_image_file("your_file.jpg") + face_locations = face_recognition.face_locations(image) + +Find and manipulate facial features in pictures +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Get the locations and outlines of each person's eyes, nose, mouth and +chin. + +|image4| + +.. code:: python + + import face_recognition + image = face_recognition.load_image_file("your_file.jpg") + face_landmarks_list = face_recognition.face_landmarks(image) + +| Finding facial features is super useful for lots of important stuff. + But you can also use for really stupid stuff +| like applying `digital + make-up `__ + (think 'Meitu'): + +|image5| + +Identify faces in pictures +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Recognize who appears in each photo. + +|image6| + +.. code:: python + + import face_recognition + known_image = face_recognition.load_image_file("biden.jpg") + unknown_image = face_recognition.load_image_file("unknown.jpg") + + biden_encoding = face_recognition.face_encodings(known_image)[0] + unknown_encoding = face_recognition.face_encodings(unknown_image)[0] + + results = face_recognition.compare_faces([biden_encoding], unknown_encoding) + +You can even use this library with other Python libraries to do +real-time face recognition: + +|image7| + +See `this +example `__ +for the code. + +Installation +------------ + +Requirements +^^^^^^^^^^^^ + +- Python 3.3+ or Python 2.7 +- macOS or Linux (Windows not officially supported, but might work) + +Installing on Mac or Linux +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +First, make sure you have dlib already installed with Python bindings: + +- `How to install dlib from source on macOS or + Ubuntu `__ + +Then, install this module from pypi using ``pip3`` (or ``pip2`` for +Python 2): + +.. code:: bash + + pip3 install face_recognition + +| If you are having trouble with installation, you can also try out a +| `pre-configured + VM `__. + +Installing on Raspberry Pi 2+ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- `Raspberry Pi 2+ installation + instructions `__ + +Installing on Windows +^^^^^^^^^^^^^^^^^^^^^ + +While Windows isn't officially supported, helpful users have posted +instructions on how to install this library: + +- `@masoudr's Windows 10 installation guide (dlib + + face\_recognition) `__ + +Installing a pre-configured Virtual Machine image +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- `Download the pre-configured VM + image `__ + (for VMware Player or VirtualBox). + +Usage +----- + +Command-Line Interface +^^^^^^^^^^^^^^^^^^^^^^ + +| When you install ``face_recognition``, you get a simple command-line + program +| called ``face_recognition`` that you can use to recognize faces in a +| photograph or folder full for photographs. + +| First, you need to provide a folder with one picture of each person + you +| already know. There should be one image file for each person with the +| files named according to who is in the picture: + +|known| + +Next, you need a second folder with the files you want to identify: + +|unknown| + +| Then in you simply run the command ``face_recognition``, passing in +| the folder of known people and the folder (or single image) with + unknown +| people and it tells you who is in each image: + +.. code:: bash + + $ face_recognition ./pictures_of_people_i_know/ ./unknown_pictures/ + + /unknown_pictures/unknown.jpg,Barack Obama + /face_recognition_test/unknown_pictures/unknown.jpg,unknown_person + +| There's one line in the output for each face. The data is + comma-separated +| with the filename and the name of the person found. + +| An ``unknown_person`` is a face in the image that didn't match anyone + in +| your folder of known people. + +Adjusting Tolerance / Sensitivity +''''''''''''''''''''''''''''''''' + +| If you are getting multiple matches for the same person, it might be + that +| the people in your photos look very similar and a lower tolerance + value +| is needed to make face comparisons more strict. + +| You can do that with the ``--tolerance`` parameter. The default + tolerance +| value is 0.6 and lower numbers make face comparisons more strict: + +.. code:: bash + + $ face_recognition --tolerance 0.54 ./pictures_of_people_i_know/ ./unknown_pictures/ + + /unknown_pictures/unknown.jpg,Barack Obama + /face_recognition_test/unknown_pictures/unknown.jpg,unknown_person + +| If you want to see the face distance calculated for each match in + order +| to adjust the tolerance setting, you can use ``--show-distance true``: + +.. code:: bash + + $ face_recognition --show-distance true ./pictures_of_people_i_know/ ./unknown_pictures/ + + /unknown_pictures/unknown.jpg,Barack Obama,0.378542298956785 + /face_recognition_test/unknown_pictures/unknown.jpg,unknown_person,None + +More Examples +''''''''''''' + +| If you simply want to know the names of the people in each photograph + but don't +| care about file names, you could do this: + +.. code:: bash + + $ face_recognition ./pictures_of_people_i_know/ ./unknown_pictures/ | cut -d ',' -f2 + + Barack Obama + unknown_person + +Speeding up Face Recognition +'''''''''''''''''''''''''''' + +| Face recognition can be done in parallel if you have a computer with +| multiple CPU cores. For example if your system has 4 CPU cores, you + can +| process about 4 times as many images in the same amount of time by + using +| all your CPU cores in parallel. + +If you are using Python 3.4 or newer, pass in a +``--cpus `` parameter: + +.. code:: bash + + $ face_recognition --cpus 4 ./pictures_of_people_i_know/ ./unknown_pictures/ + +You can also pass in ``--cpus -1`` to use all CPU cores in your system. + +Python Module +^^^^^^^^^^^^^ + +| You can import the ``face_recognition`` module and then easily + manipulate +| faces with just a couple of lines of code. It's super easy! + +API Docs: +`https://face-recognition.readthedocs.io `__. + +Automatically find all the faces in an image +'''''''''''''''''''''''''''''''''''''''''''' + +.. code:: python + + import face_recognition + + image = face_recognition.load_image_file("my_picture.jpg") + face_locations = face_recognition.face_locations(image) + + # face_locations is now an array listing the co-ordinates of each face! + +| See `this + example `__ +| to try it out. + +You can also opt-in to a somewhat more accurate deep-learning-based face +detection model. + +| Note: GPU acceleration (via nvidia's CUDA library) is required for + good +| performance with this model. You'll also want to enable CUDA support +| when compliling ``dlib``. + +.. code:: python + + import face_recognition + + image = face_recognition.load_image_file("my_picture.jpg") + face_locations = face_recognition.face_locations(image, model="cnn") + + # face_locations is now an array listing the co-ordinates of each face! + +| See `this + example `__ +| to try it out. + +| If you have a lot of images and a GPU, you can also +| `find faces in + batches `__. + +Automatically locate the facial features of a person in an image +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +.. code:: python + + import face_recognition + + image = face_recognition.load_image_file("my_picture.jpg") + face_landmarks_list = face_recognition.face_landmarks(image) + + # face_landmarks_list is now an array with the locations of each facial feature in each face. + # face_landmarks_list[0]['left_eye'] would be the location and outline of the first person's left eye. + +| See `this + example `__ +| to try it out. + +Recognize faces in images and identify who they are +''''''''''''''''''''''''''''''''''''''''''''''''''' + +.. code:: python + + import face_recognition + + picture_of_me = face_recognition.load_image_file("me.jpg") + my_face_encoding = face_recognition.face_encodings(picture_of_me)[0] + + # my_face_encoding now contains a universal 'encoding' of my facial features that can be compared to any other picture of a face! + + unknown_picture = face_recognition.load_image_file("unknown.jpg") + unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0] + + # Now we can see the two face encodings are of the same person with `compare_faces`! + + results = face_recognition.compare_faces([my_face_encoding], unknown_face_encoding) + + if results[0] == True: + print("It's a picture of me!") + else: + print("It's not a picture of me!") + +| See `this + example `__ +| to try it out. + +Python Code Examples +-------------------- + +All the examples are available +`here `__. + +Face Detection +^^^^^^^^^^^^^^ + +- `Find faces in a + photograph `__ +- `Find faces in a photograph (using deep + learning) `__ +- `Find faces in batches of images w/ GPU (using deep + learning) `__ + +Facial Features +^^^^^^^^^^^^^^^ + +- `Identify specific facial features in a + photograph `__ +- `Apply (horribly ugly) digital + make-up `__ + +Facial Recognition +^^^^^^^^^^^^^^^^^^ + +- `Find and recognize unknown faces in a photograph based on + photographs of known + people `__ +- `Compare faces by numeric face distance instead of only True/False + matches `__ +- `Recognize faces in live video using your webcam - Simple / Slower + Version (Requires OpenCV to be + installed) `__ +- `Recognize faces in live video using your webcam - Faster Version + (Requires OpenCV to be + installed) `__ +- `Recognize faces in a video file and write out new video file + (Requires OpenCV to be + installed) `__ +- `Recognize faces on a Raspberry Pi w/ + camera `__ +- `Run a web service to recognize faces via HTTP (Requires Flask to be + installed) `__ +- `Recognize faces with a K-nearest neighbors + classifier `__ + + .. rubric:: How Face Recognition Works + :name: how-face-recognition-works + +| If you want to learn how face location and recognition work instead of +| depending on a black box library, `read my + article `__. + +Caveats +------- + +- The face recognition model is trained on adults and does not work + very well on children. It tends to mix + up children quite easy using the default comparison threshold of 0.6. + +Deployment to Cloud Hosts (Heroku, AWS, etc) +-------------------------------------------- + +| Since ``face_recognition`` depends on ``dlib`` which is written in + C++, it can be tricky to deploy an app +| using it to a cloud hosting provider like Heroku or AWS. + +| To make things easier, there's an example Dockerfile in this repo that + shows how to run an app built with +| ``face_recognition`` in a `Docker `__ + container. With that, you should be able to deploy +| to any service that supports Docker images. + +Common Issues +------------- + +Issue: ``Illegal instruction (core dumped)`` when using +face\_recognition or running examples. + +| Solution: ``dlib`` is compiled with SSE4 or AVX support, but your CPU + is too old and doesn't support that. +| You'll need to recompile ``dlib`` after `making the code change + outlined + here `__. + +Issue: +``RuntimeError: Unsupported image type, must be 8bit gray or RGB image.`` +when running the webcam examples. + +Solution: Your webcam probably isn't set up correctly with OpenCV. `Look +here for +more `__. + +Issue: ``MemoryError`` when running ``pip2 install face_recognition`` + +| Solution: The face\_recognition\_models file is too big for your + available pip cache memory. Instead, +| try ``pip2 --no-cache-dir install face_recognition`` to avoid the + issue. + +Issue: +``AttributeError: 'module' object has no attribute 'face_recognition_model_v1'`` + +Solution: The version of ``dlib`` you have installed is too old. You +need version 19.7 or newer. Upgrade ``dlib``. + +Issue: +``Attribute Error: 'Module' object has no attribute 'cnn_face_detection_model_v1'`` + +Solution: The version of ``dlib`` you have installed is too old. You +need version 19.7 or newer. Upgrade ``dlib``. + +Issue: ``TypeError: imread() got an unexpected keyword argument 'mode'`` + +Solution: The version of ``scipy`` you have installed is too old. You +need version 0.17 or newer. Upgrade ``scipy``. + +Thanks +------ + +- Many, many thanks to `Davis King `__ + (`@nulhom `__) + for creating dlib and for providing the trained facial feature + detection and face encoding models + used in this library. For more information on the ResNet that powers + the face encodings, check out + his `blog + post `__. +- Thanks to everyone who works on all the awesome Python data science + libraries like numpy, scipy, scikit-image, + pillow, etc, etc that makes this kind of stuff so easy and fun in + Python. +- Thanks to `Cookiecutter `__ + and the + `audreyr/cookiecutter-pypackage `__ + project template + for making Python project packaging way more tolerable. + +.. |PyPI| image:: https://img.shields.io/pypi/v/face_recognition.svg + :target: https://pypi.python.org/pypi/face_recognition +.. |Build Status| image:: https://travis-ci.org/ageitgey/face_recognition.svg?branch=master + :target: https://travis-ci.org/ageitgey/face_recognition +.. |Documentation Status| image:: https://readthedocs.org/projects/face-recognition/badge/?version=latest + :target: http://face-recognition.readthedocs.io/en/latest/?badge=latest +.. |image3| image:: https://cloud.githubusercontent.com/assets/896692/23625227/42c65360-025d-11e7-94ea-b12f28cb34b4.png +.. |image4| image:: https://cloud.githubusercontent.com/assets/896692/23625282/7f2d79dc-025d-11e7-8728-d8924596f8fa.png +.. |image5| image:: https://cloud.githubusercontent.com/assets/896692/23625283/80638760-025d-11e7-80a2-1d2779f7ccab.png +.. |image6| image:: https://cloud.githubusercontent.com/assets/896692/23625229/45e049b6-025d-11e7-89cc-8a71cf89e713.png +.. |image7| image:: https://cloud.githubusercontent.com/assets/896692/24430398/36f0e3f0-13cb-11e7-8258-4d0c9ce1e419.gif +.. |known| image:: https://cloud.githubusercontent.com/assets/896692/23582466/8324810e-00df-11e7-82cf-41515eba704d.png +.. |unknown| image:: https://cloud.githubusercontent.com/assets/896692/23582465/81f422f8-00df-11e7-8b0d-75364f641f58.png + diff --git a/face_recognition-master/README_Simplified_Chinese.md b/face_recognition-master/README_Simplified_Chinese.md new file mode 100644 index 0000000000000000000000000000000000000000..bb1e2b019e8d9b9e60c6be0ba9c11702fcf439a8 --- /dev/null +++ b/face_recognition-master/README_Simplified_Chinese.md @@ -0,0 +1,368 @@ +# Face Recognition 人脸识别 + +> 译者注: +> +> 本项目[face_recognition](https://github.com/ageitgey/face_recognition)是一个强大、简单、易上手的人脸识别开源项目,并且配备了完整的开发文档和应用案例,特别是兼容树莓派系统。 +> +> 为了便于中国开发者研究学习人脸识别、贡献代码,我将本项目README文件翻译成中文。 +> +> 向本项目的所有贡献者致敬。 +> +> 英译汉:同济大学开源软件协会 [子豪兄Tommy](https://github.com/TommyZihao) +> +> Translator's note: +> +> [face_recognition](https://github.com/ageitgey/face_recognition) is a powerful, simple and easy-to-use face recognition open source project with complete development documents and application cases, especially it is compatible with Raspberry Pi. +> +> In order to facilitate Chinese software developers to learn, make progress in face recognition development and source code contributions, I translated README file into simplified Chinese. +> +> Salute to all contributors to this project. +> +> Translator: Tommy in Tongji Univerisity Opensource Association [子豪兄Tommy](https://github.com/TommyZihao) + + + +本项目是世界上最简洁的人脸识别库,你可以使用Python和命令行工具提取、识别、操作人脸。 + +本项目的人脸识别是基于业内领先的C++开源库 [dlib](http://dlib.net/)中的深度学习模型,用[Labeled Faces in the Wild](http://vis-www.cs.umass.edu/lfw/)人脸数据集进行测试,有高达99.38%的准确率。但对小孩和亚洲人脸的识别准确率尚待提升。 + +> [Labeled Faces in the Wild](http://vis-www.cs.umass.edu/lfw/)是美国麻省大学安姆斯特分校(University of Massachusetts Amherst)制作的人脸数据集,该数据集包含了从网络收集的13,000多张面部图像。 + +本项目提供了简易的`face_recognition`命令行工具,你可以用它处理整个文件夹里的图片。 + +[![PyPI](https://img.shields.io/pypi/v/face_recognition.svg)](https://pypi.python.org/pypi/face_recognition) +[![Build Status](https://travis-ci.org/ageitgey/face_recognition.svg?branch=master)](https://travis-ci.org/ageitgey/face_recognition) +[![Documentation Status](https://readthedocs.org/projects/face-recognition/badge/?version=latest)](http://face-recognition.readthedocs.io/en/latest/?badge=latest) + +## 特性 + +#### 从图片里找到人脸 + +定位图片中的所有人脸: + +![](https://cloud.githubusercontent.com/assets/896692/23625227/42c65360-025d-11e7-94ea-b12f28cb34b4.png) + +```python +import face_recognition +image = face_recognition.load_image_file("your_file.jpg") +face_locations = face_recognition.face_locations(image) +``` + +#### 识别人脸关键点 + +识别人脸关键点,包括眼睛、鼻子、嘴和下巴。 + +![](https://cloud.githubusercontent.com/assets/896692/23625282/7f2d79dc-025d-11e7-8728-d8924596f8fa.png) + +```python +import face_recognition +image = face_recognition.load_image_file("your_file.jpg") +face_landmarks_list = face_recognition.face_landmarks(image) +``` + +识别人脸关键点在很多领域都有用处,但同样你也可以把这个功能玩坏,比如本项目的 [digital make-up](https://github.com/ageitgey/face_recognition/blob/master/examples/digital_makeup.py)自动化妆案例(就像美图秀秀一样)。 + +![](https://cloud.githubusercontent.com/assets/896692/23625283/80638760-025d-11e7-80a2-1d2779f7ccab.png) + +#### 识别图片中的人是谁 + +![](https://cloud.githubusercontent.com/assets/896692/23625229/45e049b6-025d-11e7-89cc-8a71cf89e713.png) + +```python +import face_recognition +known_image = face_recognition.load_image_file("biden.jpg") +unknown_image = face_recognition.load_image_file("unknown.jpg") + +biden_encoding = face_recognition.face_encodings(known_image)[0] +unknown_encoding = face_recognition.face_encodings(unknown_image)[0] + +results = face_recognition.compare_faces([biden_encoding], unknown_encoding) +``` + +你也可以配合其它的Python库(比如opencv)实现实时人脸检测: + +![](https://cloud.githubusercontent.com/assets/896692/24430398/36f0e3f0-13cb-11e7-8258-4d0c9ce1e419.gif) + +看这个案例 [实时人脸检测](https://github.com/ageitgey/face_recognition/blob/master/examples/facerec_from_webcam_faster.py) 。 + +## 安装 + +### 环境配置 + +- Python 3.3+ or Python 2.7 +- macOS or Linux +- Windows并不是我们官方支持的,但也许也能用 + +### 不同操作系统的安装方法 + +#### 在 Mac 或者 Linux上安装本项目 + +First, make sure you have dlib already installed with Python bindings: + +第一步,安装dlib和相关Python依赖: + +- [如何在macOS或者Ubuntu上安装dlib](https://gist.github.com/ageitgey/629d75c1baac34dfa5ca2a1928a7aeaf) + +Then, install this module from pypi using `pip3` (or `pip2` for Python 2): + +```bash +pip3 install face_recognition +``` + +如果你遇到了幺蛾子,可以用Ubuntu虚拟机安装本项目,看下面这个教程。 +[如何使用Adam Geitgey大神提供的Ubuntu虚拟机镜像文件安装配置虚拟机,本项目已经包含在镜像中](https://medium.com/@ageitgey/try-deep-learning-in-python-now-with-a-fully-pre-configured-vm-1d97d4c3e9b). + +#### 在树莓派上安装 + +- [树莓派安装指南](https://gist.github.com/ageitgey/1ac8dbe8572f3f533df6269dab35df65) + +#### 在Windows上安装 + +虽然本项目官方并不支持Windows,但一些大神们摸索出了在Windows上运行本项目的方法: + +- [@masoudr写的教程:如何在Win10系统上安装 dlib库和 face_recognition项目](https://github.com/ageitgey/face_recognition/issues/175#issue-257710508) + +#### 使用Ubuntu虚拟机镜像文件安装配置虚拟机,本项目已经包含在这个镜像中 + +- [如何使用Adam Geitgey大神提供的Ubuntu虚拟机镜像文件安装配置虚拟机,本项目已经包含在镜像中](https://medium.com/@ageitgey/try-deep-learning-in-python-now-with-a-fully-pre-configured-vm-1d97d4c3e9b)(需要电脑中安装VMWare Player 或者 VirtualBox) + +## 使用方法 + +### 命令行界面 + +当你安装好了本项目,你可以使用两种命令行工具: + +- `face_recognition` - 在单张图片或一个图片文件夹中认出是谁的脸。 +- `face_detection` - 在单张图片或一个图片文件夹中定位人脸位置。 + +#### `face_recognition` 命令行工具 + +`face_recognition`命令行工具可以在单张图片或一个图片文件夹中认出是谁的脸。 + +首先,你得有一个你已经知道名字的人脸图片文件夹,一个人一张图,图片的文件名即为对应的人的名字: + +![known](https://cloud.githubusercontent.com/assets/896692/23582466/8324810e-00df-11e7-82cf-41515eba704d.png) + +然后,你需要第二个图片文件夹,文件夹里面是你希望识别的图片: + +![unknown](https://cloud.githubusercontent.com/assets/896692/23582465/81f422f8-00df-11e7-8b0d-75364f641f58.png) + +然后,你在命令行中切换到这两个文件夹所在路径,然后使用`face_recognition`命令行,传入这两个图片文件夹,然后就会输出未知图片中人的名字: + +```bash +$ face_recognition ./pictures_of_people_i_know/ ./unknown_pictures/ + +/unknown_pictures/unknown.jpg,Barack Obama +/face_recognition_test/unknown_pictures/unknown.jpg,unknown_person +``` + +输出结果的每一行对应着图片中的一张脸,图片名字和对应人脸识别结果用逗号分开。 + +如果结果输出了`unknown_person`,那么代表这张脸没有对应上已知人脸图片文件夹中的任何一个人。 + +#### `face_detection` 命令行工具 + +`face_detection`命令行工具可以在单张图片或一个图片文件夹中定位人脸位置(输出像素点坐标)。 + +在命令行中使用`face_detection`,传入一个图片文件夹或单张图片文件来进行人脸位置检测: + +```bash +$ face_detection ./folder_with_pictures/ + +examples/image1.jpg,65,215,169,112 +examples/image2.jpg,62,394,211,244 +examples/image2.jpg,95,941,244,792 +``` + +输出结果的每一行都对应图片中的一张脸,输出坐标代表着这张脸的上、右、下、左像素点坐标。 + +##### 调整人脸识别的容错率和敏感度 + +如果一张脸识别出不止一个结果,那么这意味着他和其他人长的太像了(本项目对于小孩和亚洲人的人脸识别准确率有待提升)。你可以把容错率调低一些,使识别结果更加严格。 + +通过传入参数 `--tolerance` 来实现这个功能,默认的容错率是0.6,容错率越低,识别越严格准确。 + +```bash +$ face_recognition --tolerance 0.54 ./pictures_of_people_i_know/ ./unknown_pictures/ + +/unknown_pictures/unknown.jpg,Barack Obama +/face_recognition_test/unknown_pictures/unknown.jpg,unknown_person +``` + +如果你想看人脸匹配的具体数值,可以传入参数 `--show-distance true`: + +```bash +$ face_recognition --show-distance true ./pictures_of_people_i_know/ ./unknown_pictures/ + +/unknown_pictures/unknown.jpg,Barack Obama,0.378542298956785 +/face_recognition_test/unknown_pictures/unknown.jpg,unknown_person,None +``` + +##### 更多的例子 + +如果你并不在乎图片的文件名,只想知道文件夹中的图片里有谁,可以用这个管道命令: + +```bash +$ face_recognition ./pictures_of_people_i_know/ ./unknown_pictures/ | cut -d ',' -f2 + +Barack Obama +unknown_person +``` + +##### 加速人脸识别运算 + +如果你的CPU是多核的,你可以通过并行运算加速人脸识别。例如,如果你的CPU有四个核心,那么你可以通过并行运算提升大概四倍的运算速度。 + +如果你使用Python3.4或更新的版本,可以传入 `--cpus ` 参数: + +```bash +$ face_recognition --cpus 4 ./pictures_of_people_i_know/ ./unknown_pictures/ +``` + +你可以传入 `--cpus -1`参数来调用cpu的所有核心。 + +> 子豪兄批注:树莓派3B有4个CPU核心,传入多核参数可以显著提升图片识别的速度(亲测)。 + +#### Python 模块:`face_recognition` + +在Python中,你可以导入`face_recognition`模块,调用我们提供的丰富的API接口,用几行代码就可以轻松玩转各种人脸识别功能! + +API 接口文档: [https://face-recognition.readthedocs.io](https://face-recognition.readthedocs.io/en/latest/face_recognition.html) + +##### 在图片中定位人脸的位置 + +```python +import face_recognition + +image = face_recognition.load_image_file("my_picture.jpg") +face_locations = face_recognition.face_locations(image) + +# face_locations is now an array listing the co-ordinates of each face! +``` + +看 [案例:定位拜登的脸](https://github.com/ageitgey/face_recognition/blob/master/examples/find_faces_in_picture.py) + +![案例:定位拜登的脸](https://upload-images.jianshu.io/upload_images/13714448-b4ce08c6ba699c5e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) + +你也可以使用深度学习模型达到更加精准的人脸定位。 + +注意:这种方法需要GPU加速(通过英伟达显卡的CUDA库驱动),你在编译安装`dlib`的时候也需要开启CUDA支持。 + +```python +import face_recognition + +image = face_recognition.load_image_file("my_picture.jpg") +face_locations = face_recognition.face_locations(image, model="cnn") + +# face_locations is now an array listing the co-ordinates of each face! +``` + +看 [案例:使用卷积神经网络深度学习模型定位拜登的脸](https://github.com/ageitgey/face_recognition/blob/master/examples/find_faces_in_picture_cnn.py) + +如果你有很多图片需要识别,同时又有GPU,那么你可以参考这个例子:[案例:使用卷积神经网络深度学习模型批量识别图片中的人脸](https://github.com/ageitgey/face_recognition/blob/master/examples/find_faces_in_batches.py). + +##### 识别单张图片中人脸的关键点 + +```python +import face_recognition + +image = face_recognition.load_image_file("my_picture.jpg") +face_landmarks_list = face_recognition.face_landmarks(image) + +# face_landmarks_list is now an array with the locations of each facial feature in each face. +# face_landmarks_list[0]['left_eye'] would be the location and outline of the first person's left eye. +``` + +看这个案例 [案例:提取奥巴马和拜登的面部关键点](https://github.com/ageitgey/face_recognition/blob/master/examples/find_facial_features_in_picture.py) +![案例:提取奥巴马和拜登的面部关键点](https://upload-images.jianshu.io/upload_images/13714448-734e8b4f5592ed4a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) + +##### 识别图片中的人是谁 + +```python +import face_recognition + +picture_of_me = face_recognition.load_image_file("me.jpg") +my_face_encoding = face_recognition.face_encodings(picture_of_me)[0] + +# my_face_encoding now contains a universal 'encoding' of my facial features that can be compared to any other picture of a face! + +unknown_picture = face_recognition.load_image_file("unknown.jpg") +unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0] + +# Now we can see the two face encodings are of the same person with `compare_faces`! + +results = face_recognition.compare_faces([my_face_encoding], unknown_face_encoding) + +if results[0] == True: + print("It's a picture of me!") +else: + print("It's not a picture of me!") +``` + +看这个案例 [案例:是奥巴马还是拜登?](https://github.com/ageitgey/face_recognition/blob/master/examples/recognize_faces_in_pictures.py) + +## Python 案例 + +所有案例都在这个链接中 [也就是examples文件夹](https://github.com/ageitgey/face_recognition/tree/master/examples). + +#### 人脸定位 + +- [案例:定位拜登的脸](https://github.com/ageitgey/face_recognition/blob/master/examples/find_faces_in_picture.py) +- [案例:使用卷积神经网络深度学习模型定位拜登的脸](https://github.com/ageitgey/face_recognition/blob/master/examples/find_faces_in_picture_cnn.py) +- [案例:使用卷积神经网络深度学习模型批量识别图片中的人脸](https://github.com/ageitgey/face_recognition/blob/master/examples/find_faces_in_batches.py) +- [案例:把来自网络摄像头视频里的人脸高斯模糊(需要安装OpenCV)](https://github.com/ageitgey/face_recognition/blob/master/examples/blur_faces_on_webcam.py) + +#### 人脸关键点识别 + +- [案例:提取奥巴马和拜登的面部关键点](https://github.com/ageitgey/face_recognition/blob/master/examples/find_facial_features_in_picture.py) +- [案例:给美国副总统拜登涂美妆](https://github.com/ageitgey/face_recognition/blob/master/examples/digital_makeup.py) + +#### 人脸识别 + +- [案例:是奥巴马还是拜登?](https://github.com/ageitgey/face_recognition/blob/master/examples/recognize_faces_in_pictures.py) +- [案例:人脸识别之后在原图上画框框并标注姓名](https://github.com/ageitgey/face_recognition/blob/master/examples/identify_and_draw_boxes_on_faces.py) +- [案例:在不同精度上比较两个人脸是否属于一个人](https://github.com/ageitgey/face_recognition/blob/master/examples/face_distance.py) +- [案例:从摄像头获取视频进行人脸识别-较慢版(需要安装OpenCV)](https://github.com/ageitgey/face_recognition/blob/master/examples/facerec_from_webcam.py) +- [案例:从摄像头获取视频进行人脸识别-较快版(需要安装OpenCV)](https://github.com/ageitgey/face_recognition/blob/master/examples/facerec_from_webcam_faster.py) +- [案例:从视频文件中识别人脸并把识别结果输出为新的视频文件(需要安装OpenCV)](https://github.com/ageitgey/face_recognition/blob/master/examples/facerec_from_video_file.py) +- [案例:通过树莓派摄像头进行人脸个数统计及人脸身份识别](https://github.com/ageitgey/face_recognition/blob/master/examples/facerec_on_raspberry_pi.py) +- [案例:通过浏览器HTTP访问网络服务器进行人脸识别(需要安装Flask后端开发框架))](https://github.com/ageitgey/face_recognition/blob/master/examples/web_service_example.py) +- [案例:基于K最近邻KNN分类算法进行人脸识别](https://github.com/ageitgey/face_recognition/blob/master/examples/face_recognition_knn.py) + +## 关于 `face_recognition`的文章和教程 + +- 本项目作者写的一篇文章 [Modern Face Recognition with Deep Learning](https://medium.com/@ageitgey/machine-learning-is-fun-part-4-modern-face-recognition-with-deep-learning-c3cffc121d78) + - 主要内容:基本算法和原理 +- [Face recognition with OpenCV, Python, and deep learning](https://www.pyimagesearch.com/2018/06/18/face-recognition-with-opencv-python-and-deep-learning/) by Adrian Rosebrock + - 主要内容:如何实际使用本项目 +- [Raspberry Pi Face Recognition](https://www.pyimagesearch.com/2018/06/25/raspberry-pi-face-recognition/) by Adrian Rosebrock + - 主要内容:如何在树莓派上使用本项目 +- [Face clustering with Python](https://www.pyimagesearch.com/2018/07/09/face-clustering-with-python/) by Adrian Rosebrock + - 主要内容:使用非监督学习算法实现把图片中的人脸高斯模糊 + +## 人脸识别的原理 + +如果你想更深入了解人脸识别这个黑箱的原理 [读这篇文章](https://medium.com/@ageitgey/machine-learning-is-fun-part-4-modern-face-recognition-with-deep-learning-c3cffc121d78)。 + +> 子豪兄批注:一定要看这篇文章,讲的既有趣又有料。 + +## 警告说明 + +- 本项目的人脸识别模型是基于成年人的,在孩子身上效果可能一般。如果图片中有孩子的话,建议把临界值设为0.6. +- 不同人种的识别结果可能不同, [看wiki百科页面](https://github.com/ageitgey/face_recognition/wiki/Face-Recognition-Accuracy-Problems#question-face-recognition-works-well-with-european-individuals-but-overall-accuracy-is-lower-with-asian-individuals) 查看更多细节。 + +## 把本项目部署在云服务器上 (Heroku, AWS等) + +本项目是基于C++库`dlib`的,所以把本项目部署在Heroku或者AWS的云端服务器上是很明智的。 + +为了简化这个过程,有一个Dockerfile案例,教你怎么把`face_recognition`开发的app封装成[Docker](https://www.docker.com/) 容器文件,你可以把它部署在所以支持Docker镜像文件的云服务上。 + +## 出了幺蛾子? + +如果出了问题,请在Github提交Issue之前查看 [常见错误](https://github.com/ageitgey/face_recognition/wiki/Common-Errors) 。 + +## 鸣谢 + +- 非常感谢 [Davis King](https://github.com/davisking) ([@nulhom](https://twitter.com/nulhom))创建了`dlib`库,提供了响应的人脸关键点检测和人脸编码相关的模型,你可以查看 [blog post](http://blog.dlib.net/2017/02/high-quality-face-recognition-with-deep.html)这个网页获取更多有关ResNet的信息。 +- 感谢每一个相关Python模块(包括numpy,scipy,scikit-image,pillow等)的贡献者。 +- 感谢 [Cookiecutter](https://github.com/audreyr/cookiecutter) 和[audreyr/cookiecutter-pypackage](https://github.com/audreyr/cookiecutter-pypackage) 项目模板,使得Python的打包方式更容易接受。 diff --git a/face_recognition-master/docs/Makefile b/face_recognition-master/docs/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..6ad57265fa899587b531e41776aa0d50f9ba7ff4 --- /dev/null +++ b/face_recognition-master/docs/Makefile @@ -0,0 +1,177 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/face_recognition.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/face_recognition.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/face_recognition" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/face_recognition" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/face_recognition-master/docs/authors.rst b/face_recognition-master/docs/authors.rst new file mode 100644 index 0000000000000000000000000000000000000000..e122f914a87b277e565fc9567af1a7545ec9872b --- /dev/null +++ b/face_recognition-master/docs/authors.rst @@ -0,0 +1 @@ +.. include:: ../AUTHORS.rst diff --git a/face_recognition-master/docs/conf.py b/face_recognition-master/docs/conf.py new file mode 100644 index 0000000000000000000000000000000000000000..24bcf65fd755408fc6684f890c7b1915044cf569 --- /dev/null +++ b/face_recognition-master/docs/conf.py @@ -0,0 +1,284 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# face_recognition documentation build configuration file, created by +# sphinx-quickstart on Tue Jul 9 22:26:36 2013. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os +from unittest.mock import MagicMock + +class Mock(MagicMock): + @classmethod + def __getattr__(cls, name): + return MagicMock() + +MOCK_MODULES = ['face_recognition_models', 'Click', 'dlib', 'numpy', 'PIL'] +sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES) + +# If extensions (or modules to document with autodoc) are in another +# directory, add these directories to sys.path here. If the directory is +# relative to the documentation root, use os.path.abspath to make it +# absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# Get the project root dir, which is the parent dir of this +cwd = os.getcwd() +project_root = os.path.dirname(cwd) + +# Insert the project root dir as the first element in the PYTHONPATH. +# This lets us ensure that the source package is imported, and that its +# version is used. +sys.path.insert(0, project_root) + +import face_recognition + +# -- General configuration --------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Face Recognition' +copyright = u"2017, Adam Geitgey" + +# The version info for the project you're documenting, acts as replacement +# for |version| and |release|, also used in various other places throughout +# the built documents. +# +# The short X.Y version. +version = face_recognition.__version__ +# The full version, including alpha/beta/rc tags. +release = face_recognition.__version__ + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to +# some non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built +# documents. +#keep_warnings = False + + +# -- Options for HTML output ------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a +# theme further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as +# html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the +# top of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon +# of the docs. This file should be a Windows icon file (.ico) being +# 16x16 or 32x32 pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) +# here, relative to this directory. They are copied after the builtin +# static files, so a file named "default.css" will overwrite the builtin +# "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page +# bottom, using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names +# to template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. +# Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. +# Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages +# will contain a tag referring to it. The value of this option +# must be the base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'face_recognitiondoc' + + +# -- Options for LaTeX output ------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + #'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass +# [howto/manual]). +latex_documents = [ + ('index', 'face_recognition.tex', + u'Face Recognition Documentation', + u'Adam Geitgey', 'manual'), +] + +# The name of an image file (relative to this directory) to place at +# the top of the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings +# are parts, not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output ------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'face_recognition', + u'Face Recognition Documentation', + [u'Adam Geitgey'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ---------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'face_recognition', + u'Face Recognition Documentation', + u'Adam Geitgey', + 'face_recognition', + 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False diff --git a/face_recognition-master/docs/contributing.rst b/face_recognition-master/docs/contributing.rst new file mode 100644 index 0000000000000000000000000000000000000000..e582053ea018c369be05aae96cf730744f1dc616 --- /dev/null +++ b/face_recognition-master/docs/contributing.rst @@ -0,0 +1 @@ +.. include:: ../CONTRIBUTING.rst diff --git a/face_recognition-master/docs/face_recognition.rst b/face_recognition-master/docs/face_recognition.rst new file mode 100644 index 0000000000000000000000000000000000000000..444153d4589570255e4ec2242b708274a8467420 --- /dev/null +++ b/face_recognition-master/docs/face_recognition.rst @@ -0,0 +1,10 @@ +face_recognition package +======================== + +Module contents +--------------- + +.. automodule:: face_recognition.api + :members: + :undoc-members: + :show-inheritance: diff --git a/face_recognition-master/docs/history.rst b/face_recognition-master/docs/history.rst new file mode 100644 index 0000000000000000000000000000000000000000..250649964bbc36f4bec2942f69238aa6f7c02c1a --- /dev/null +++ b/face_recognition-master/docs/history.rst @@ -0,0 +1 @@ +.. include:: ../HISTORY.rst diff --git a/face_recognition-master/docs/index.rst b/face_recognition-master/docs/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..52f847b419742c874c4f9a8ff32b71161ccb85a4 --- /dev/null +++ b/face_recognition-master/docs/index.rst @@ -0,0 +1,22 @@ +Welcome to Face Recognition's documentation! +====================================== + +Contents: + +.. toctree:: + :maxdepth: 2 + + readme + installation + usage + modules + contributing + authors + history + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/face_recognition-master/docs/installation.rst b/face_recognition-master/docs/installation.rst new file mode 100644 index 0000000000000000000000000000000000000000..1d35ca565119b58e420002a9f32a42c271c42b94 --- /dev/null +++ b/face_recognition-master/docs/installation.rst @@ -0,0 +1,51 @@ +.. highlight:: shell + +============ +Installation +============ + + +Stable release +-------------- + +To install Face Recognition, run this command in your terminal: + +.. code-block:: console + + $ pip3 install face_recognition + +This is the preferred method to install Face Recognition, as it will always install the most recent stable release. + +If you don't have `pip`_ installed, this `Python installation guide`_ can guide +you through the process. + +.. _pip: https://pip.pypa.io +.. _Python installation guide: http://docs.python-guide.org/en/latest/starting/installation/ + + +From sources +------------ + +The sources for Face Recognition can be downloaded from the `Github repo`_. + +You can either clone the public repository: + +.. code-block:: console + + $ git clone git://github.com/ageitgey/face_recognition + +Or download the `tarball`_: + +.. code-block:: console + + $ curl -OL https://github.com/ageitgey/face_recognition/tarball/master + +Once you have a copy of the source, you can install it with: + +.. code-block:: console + + $ python setup.py install + + +.. _Github repo: https://github.com/ageitgey/face_recognition +.. _tarball: https://github.com/ageitgey/face_recognition/tarball/master diff --git a/face_recognition-master/docs/make.bat b/face_recognition-master/docs/make.bat new file mode 100644 index 0000000000000000000000000000000000000000..a2872b726fd66ac02c6aa77af6151304746fcef4 --- /dev/null +++ b/face_recognition-master/docs/make.bat @@ -0,0 +1,242 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. xml to make Docutils-native XML files + echo. pseudoxml to make pseudoxml-XML files for display purposes + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + + +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\face_recognition.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\face_recognition.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf + cd %BUILDDIR%/.. + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdfja" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf-ja + cd %BUILDDIR%/.. + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +if "%1" == "xml" ( + %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The XML files are in %BUILDDIR%/xml. + goto end +) + +if "%1" == "pseudoxml" ( + %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. + goto end +) + +:end diff --git a/face_recognition-master/docs/modules.rst b/face_recognition-master/docs/modules.rst new file mode 100644 index 0000000000000000000000000000000000000000..301725748961e91a82ff30e1ec531c058efbe82f --- /dev/null +++ b/face_recognition-master/docs/modules.rst @@ -0,0 +1,7 @@ +face_recognition +================ + +.. toctree:: + :maxdepth: 4 + + face_recognition diff --git a/face_recognition-master/docs/readme.rst b/face_recognition-master/docs/readme.rst new file mode 100644 index 0000000000000000000000000000000000000000..72a33558153fb57def85612b021ec596ef2a51b9 --- /dev/null +++ b/face_recognition-master/docs/readme.rst @@ -0,0 +1 @@ +.. include:: ../README.rst diff --git a/face_recognition-master/docs/usage.rst b/face_recognition-master/docs/usage.rst new file mode 100644 index 0000000000000000000000000000000000000000..f1dc1ef096e9b241bcad7750fc27249001b39953 --- /dev/null +++ b/face_recognition-master/docs/usage.rst @@ -0,0 +1,41 @@ +===== +Usage +===== + +To use Face Recognition in a project:: + + import face_recognition + +See the examples in the /examples folder on github for how to use each function. + +You can also check the API docs for the 'face_recognition' module to see the possible parameters for each function. + +The basic idea is that first you load an image:: + + import face_recognition + + image = face_recognition.load_image_file("your_file.jpg") + +That loads the image into a numpy array. If you already have an image in a numpy array, you can skip this step. + +Then you can perform operations on the image, like finding faces, identifying facial features or finding face encodings:: + + # Find all the faces in the image + face_locations = face_recognition.face_locations(image) + + # Or maybe find the facial features in the image + face_landmarks_list = face_recognition.face_landmarks(image) + + # Or you could get face encodings for each face in the image: + list_of_face_encodings = face_recognition.face_encodings(image) + +Face encodings can be compared against each other to see if the faces are a match. Note: Finding the encoding for a face +is a bit slow, so you might want to save the results for each image in a database or cache if you need to refer back to +it later. + +But once you have the encodings for faces, you can compare them like this:: + + # results is an array of True/False telling if the unknown face matched anyone in the known_faces array + results = face_recognition.compare_faces(known_face_encodings, a_single_unknown_face_encoding) + +It's that simple! Check out the examples for more details. diff --git a/face_recognition-master/examples/alex-lacamoire.png b/face_recognition-master/examples/alex-lacamoire.png new file mode 100644 index 0000000000000000000000000000000000000000..57a49de800202b59e4e4a945265e3bfc9e54eea5 Binary files /dev/null and b/face_recognition-master/examples/alex-lacamoire.png differ diff --git a/face_recognition-master/examples/benchmark.py b/face_recognition-master/examples/benchmark.py new file mode 100644 index 0000000000000000000000000000000000000000..4904437428ab6aadbd49f430f32985a0b644a056 --- /dev/null +++ b/face_recognition-master/examples/benchmark.py @@ -0,0 +1,77 @@ +import timeit + +# Note: This example is only tested with Python 3 (not Python 2) + +# This is a very simple benchmark to give you an idea of how fast each step of face recognition will run on your system. +# Notice that face detection gets very slow at large image sizes. So you might consider running face detection on a +# scaled down version of your image and then running face encodings on the the full size image. + +TEST_IMAGES = [ + "obama-240p.jpg", + "obama-480p.jpg", + "obama-720p.jpg", + "obama-1080p.jpg" +] + + +def run_test(setup, test, iterations_per_test=5, tests_to_run=10): + fastest_execution = min(timeit.Timer(test, setup=setup).repeat(tests_to_run, iterations_per_test)) + execution_time = fastest_execution / iterations_per_test + fps = 1.0 / execution_time + return execution_time, fps + + +setup_locate_faces = """ +import face_recognition + +image = face_recognition.load_image_file("{}") +""" + +test_locate_faces = """ +face_locations = face_recognition.face_locations(image) +""" + +setup_face_landmarks = """ +import face_recognition + +image = face_recognition.load_image_file("{}") +face_locations = face_recognition.face_locations(image) +""" + +test_face_landmarks = """ +landmarks = face_recognition.face_landmarks(image, face_locations=face_locations)[0] +""" + +setup_encode_face = """ +import face_recognition + +image = face_recognition.load_image_file("{}") +face_locations = face_recognition.face_locations(image) +""" + +test_encode_face = """ +encoding = face_recognition.face_encodings(image, known_face_locations=face_locations)[0] +""" + +setup_end_to_end = """ +import face_recognition + +image = face_recognition.load_image_file("{}") +""" + +test_end_to_end = """ +encoding = face_recognition.face_encodings(image)[0] +""" + +print("Benchmarks (Note: All benchmarks are only using a single CPU core)") +print() + +for image in TEST_IMAGES: + size = image.split("-")[1].split(".")[0] + print("Timings at {}:".format(size)) + + print(" - Face locations: {:.4f}s ({:.2f} fps)".format(*run_test(setup_locate_faces.format(image), test_locate_faces))) + print(" - Face landmarks: {:.4f}s ({:.2f} fps)".format(*run_test(setup_face_landmarks.format(image), test_face_landmarks))) + print(" - Encode face (inc. landmarks): {:.4f}s ({:.2f} fps)".format(*run_test(setup_encode_face.format(image), test_encode_face))) + print(" - End-to-end: {:.4f}s ({:.2f} fps)".format(*run_test(setup_end_to_end.format(image), test_end_to_end))) + print() diff --git a/face_recognition-master/examples/biden.jpg b/face_recognition-master/examples/biden.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3a0bdc974e9067b1595a6a623a3d898265b0a7a2 Binary files /dev/null and b/face_recognition-master/examples/biden.jpg differ diff --git a/face_recognition-master/examples/blur_faces_on_webcam.py b/face_recognition-master/examples/blur_faces_on_webcam.py new file mode 100644 index 0000000000000000000000000000000000000000..41c0b940fd981d72ad90cd5a92af6b18e1c17858 --- /dev/null +++ b/face_recognition-master/examples/blur_faces_on_webcam.py @@ -0,0 +1,52 @@ +import face_recognition +import cv2 + +# This is a demo of blurring faces in video. + +# PLEASE NOTE: This example requires OpenCV (the `cv2` library) to be installed only to read from your webcam. +# OpenCV is *not* required to use the face_recognition library. It's only required if you want to run this +# specific demo. If you have trouble installing it, try any of the other demos that don't require it instead. + +# Get a reference to webcam #0 (the default one) +video_capture = cv2.VideoCapture(0) + +# Initialize some variables +face_locations = [] + +while True: + # Grab a single frame of video + ret, frame = video_capture.read() + + # Resize frame of video to 1/4 size for faster face detection processing + small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25) + + # Find all the faces and face encodings in the current frame of video + face_locations = face_recognition.face_locations(small_frame, model="cnn") + + # Display the results + for top, right, bottom, left in face_locations: + # Scale back up face locations since the frame we detected in was scaled to 1/4 size + top *= 4 + right *= 4 + bottom *= 4 + left *= 4 + + # Extract the region of the image that contains the face + face_image = frame[top:bottom, left:right] + + # Blur the face image + face_image = cv2.GaussianBlur(face_image, (99, 99), 30) + + # Put the blurred face region back into the frame image + frame[top:bottom, left:right] = face_image + + # Display the resulting image + cv2.imshow('Video', frame) + + # Hit 'q' on the keyboard to quit! + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +# Release handle to the webcam +video_capture.release() +cv2.destroyAllWindows() diff --git a/face_recognition-master/examples/digital_makeup.py b/face_recognition-master/examples/digital_makeup.py new file mode 100644 index 0000000000000000000000000000000000000000..776cda48c51ee911f7588a1dd35d2ec496bc16c9 --- /dev/null +++ b/face_recognition-master/examples/digital_makeup.py @@ -0,0 +1,34 @@ +from PIL import Image, ImageDraw +import face_recognition + +# Load the jpg file into a numpy array +image = face_recognition.load_image_file("biden.jpg") + +# Find all facial features in all the faces in the image +face_landmarks_list = face_recognition.face_landmarks(image) + +for face_landmarks in face_landmarks_list: + pil_image = Image.fromarray(image) + d = ImageDraw.Draw(pil_image, 'RGBA') + + # Make the eyebrows into a nightmare + d.polygon(face_landmarks['left_eyebrow'], fill=(68, 54, 39, 128)) + d.polygon(face_landmarks['right_eyebrow'], fill=(68, 54, 39, 128)) + d.line(face_landmarks['left_eyebrow'], fill=(68, 54, 39, 150), width=5) + d.line(face_landmarks['right_eyebrow'], fill=(68, 54, 39, 150), width=5) + + # Gloss the lips + d.polygon(face_landmarks['top_lip'], fill=(150, 0, 0, 128)) + d.polygon(face_landmarks['bottom_lip'], fill=(150, 0, 0, 128)) + d.line(face_landmarks['top_lip'], fill=(150, 0, 0, 64), width=8) + d.line(face_landmarks['bottom_lip'], fill=(150, 0, 0, 64), width=8) + + # Sparkle the eyes + d.polygon(face_landmarks['left_eye'], fill=(255, 255, 255, 30)) + d.polygon(face_landmarks['right_eye'], fill=(255, 255, 255, 30)) + + # Apply some eyeliner + d.line(face_landmarks['left_eye'] + [face_landmarks['left_eye'][0]], fill=(0, 0, 0, 110), width=6) + d.line(face_landmarks['right_eye'] + [face_landmarks['right_eye'][0]], fill=(0, 0, 0, 110), width=6) + + pil_image.show() diff --git a/face_recognition-master/examples/face_distance.py b/face_recognition-master/examples/face_distance.py new file mode 100644 index 0000000000000000000000000000000000000000..af3bd6253a46cefa6b5657bf33d677d65fb469bb --- /dev/null +++ b/face_recognition-master/examples/face_distance.py @@ -0,0 +1,37 @@ +import face_recognition + +# Often instead of just checking if two faces match or not (True or False), it's helpful to see how similar they are. +# You can do that by using the face_distance function. + +# The model was trained in a way that faces with a distance of 0.6 or less should be a match. But if you want to +# be more strict, you can look for a smaller face distance. For example, using a 0.55 cutoff would reduce false +# positive matches at the risk of more false negatives. + +# Note: This isn't exactly the same as a "percent match". The scale isn't linear. But you can assume that images with a +# smaller distance are more similar to each other than ones with a larger distance. + +# Load some images to compare against +known_obama_image = face_recognition.load_image_file("obama.jpg") +known_biden_image = face_recognition.load_image_file("biden.jpg") + +# Get the face encodings for the known images +obama_face_encoding = face_recognition.face_encodings(known_obama_image)[0] +biden_face_encoding = face_recognition.face_encodings(known_biden_image)[0] + +known_encodings = [ + obama_face_encoding, + biden_face_encoding +] + +# Load a test image and get encondings for it +image_to_test = face_recognition.load_image_file("obama2.jpg") +image_to_test_encoding = face_recognition.face_encodings(image_to_test)[0] + +# See how far apart the test image is from the known faces +face_distances = face_recognition.face_distance(known_encodings, image_to_test_encoding) + +for i, face_distance in enumerate(face_distances): + print("The test image has a distance of {:.2} from known image #{}".format(face_distance, i)) + print("- With a normal cutoff of 0.6, would the test image match the known image? {}".format(face_distance < 0.6)) + print("- With a very strict cutoff of 0.5, would the test image match the known image? {}".format(face_distance < 0.5)) + print() diff --git a/face_recognition-master/examples/face_recognition_knn.py b/face_recognition-master/examples/face_recognition_knn.py new file mode 100644 index 0000000000000000000000000000000000000000..d99b760b55acc673eb1b6baa9a6b6c55dfeb2cdc --- /dev/null +++ b/face_recognition-master/examples/face_recognition_knn.py @@ -0,0 +1,206 @@ +""" +This is an example of using the k-nearest-neighbors (KNN) algorithm for face recognition. + +When should I use this example? +This example is useful when you wish to recognize a large set of known people, +and make a prediction for an unknown person in a feasible computation time. + +Algorithm Description: +The knn classifier is first trained on a set of labeled (known) faces and can then predict the person +in an unknown image by finding the k most similar faces (images with closet face-features under eucledian distance) +in its training set, and performing a majority vote (possibly weighted) on their label. + +For example, if k=3, and the three closest face images to the given image in the training set are one image of Biden +and two images of Obama, The result would be 'Obama'. + +* This implementation uses a weighted vote, such that the votes of closer-neighbors are weighted more heavily. + +Usage: + +1. Prepare a set of images of the known people you want to recognize. Organize the images in a single directory + with a sub-directory for each known person. + +2. Then, call the 'train' function with the appropriate parameters. Make sure to pass in the 'model_save_path' if you + want to save the model to disk so you can re-use the model without having to re-train it. + +3. Call 'predict' and pass in your trained model to recognize the people in an unknown image. + +NOTE: This example requires scikit-learn to be installed! You can install it with pip: + +$ pip3 install scikit-learn + +""" + +import math +from sklearn import neighbors +import os +import os.path +import pickle +from PIL import Image, ImageDraw +import face_recognition +from face_recognition.face_recognition_cli import image_files_in_folder + +ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'} + + +def train(train_dir, model_save_path=None, n_neighbors=None, knn_algo='ball_tree', verbose=False): + """ + Trains a k-nearest neighbors classifier for face recognition. + + :param train_dir: directory that contains a sub-directory for each known person, with its name. + + (View in source code to see train_dir example tree structure) + + Structure: + / + ├── / + │ ├── .jpeg + │ ├── .jpeg + │ ├── ... + ├── / + │ ├── .jpeg + │ └── .jpeg + └── ... + + :param model_save_path: (optional) path to save model on disk + :param n_neighbors: (optional) number of neighbors to weigh in classification. Chosen automatically if not specified + :param knn_algo: (optional) underlying data structure to support knn.default is ball_tree + :param verbose: verbosity of training + :return: returns knn classifier that was trained on the given data. + """ + X = [] + y = [] + + # Loop through each person in the training set + for class_dir in os.listdir(train_dir): + if not os.path.isdir(os.path.join(train_dir, class_dir)): + continue + + # Loop through each training image for the current person + for img_path in image_files_in_folder(os.path.join(train_dir, class_dir)): + image = face_recognition.load_image_file(img_path) + face_bounding_boxes = face_recognition.face_locations(image) + + if len(face_bounding_boxes) != 1: + # If there are no people (or too many people) in a training image, skip the image. + if verbose: + print("Image {} not suitable for training: {}".format(img_path, "Didn't find a face" if len(face_bounding_boxes) < 1 else "Found more than one face")) + else: + # Add face encoding for current image to the training set + X.append(face_recognition.face_encodings(image, known_face_locations=face_bounding_boxes)[0]) + y.append(class_dir) + + # Determine how many neighbors to use for weighting in the KNN classifier + if n_neighbors is None: + n_neighbors = int(round(math.sqrt(len(X)))) + if verbose: + print("Chose n_neighbors automatically:", n_neighbors) + + # Create and train the KNN classifier + knn_clf = neighbors.KNeighborsClassifier(n_neighbors=n_neighbors, algorithm=knn_algo, weights='distance') + knn_clf.fit(X, y) + + # Save the trained KNN classifier + if model_save_path is not None: + with open(model_save_path, 'wb') as f: + pickle.dump(knn_clf, f) + + return knn_clf + + +def predict(X_img_path, knn_clf=None, model_path=None, distance_threshold=0.6): + """ + Recognizes faces in given image using a trained KNN classifier + + :param X_img_path: path to image to be recognized + :param knn_clf: (optional) a knn classifier object. if not specified, model_save_path must be specified. + :param model_path: (optional) path to a pickled knn classifier. if not specified, model_save_path must be knn_clf. + :param distance_threshold: (optional) distance threshold for face classification. the larger it is, the more chance + of mis-classifying an unknown person as a known one. + :return: a list of names and face locations for the recognized faces in the image: [(name, bounding box), ...]. + For faces of unrecognized persons, the name 'unknown' will be returned. + """ + if not os.path.isfile(X_img_path) or os.path.splitext(X_img_path)[1][1:] not in ALLOWED_EXTENSIONS: + raise Exception("Invalid image path: {}".format(X_img_path)) + + if knn_clf is None and model_path is None: + raise Exception("Must supply knn classifier either thourgh knn_clf or model_path") + + # Load a trained KNN model (if one was passed in) + if knn_clf is None: + with open(model_path, 'rb') as f: + knn_clf = pickle.load(f) + + # Load image file and find face locations + X_img = face_recognition.load_image_file(X_img_path) + X_face_locations = face_recognition.face_locations(X_img) + + # If no faces are found in the image, return an empty result. + if len(X_face_locations) == 0: + return [] + + # Find encodings for faces in the test iamge + faces_encodings = face_recognition.face_encodings(X_img, known_face_locations=X_face_locations) + + # Use the KNN model to find the best matches for the test face + closest_distances = knn_clf.kneighbors(faces_encodings, n_neighbors=1) + are_matches = [closest_distances[0][i][0] <= distance_threshold for i in range(len(X_face_locations))] + + # Predict classes and remove classifications that aren't within the threshold + return [(pred, loc) if rec else ("unknown", loc) for pred, loc, rec in zip(knn_clf.predict(faces_encodings), X_face_locations, are_matches)] + + +def show_prediction_labels_on_image(img_path, predictions): + """ + Shows the face recognition results visually. + + :param img_path: path to image to be recognized + :param predictions: results of the predict function + :return: + """ + pil_image = Image.open(img_path).convert("RGB") + draw = ImageDraw.Draw(pil_image) + + for name, (top, right, bottom, left) in predictions: + # Draw a box around the face using the Pillow module + draw.rectangle(((left, top), (right, bottom)), outline=(0, 0, 255)) + + # There's a bug in Pillow where it blows up with non-UTF-8 text + # when using the default bitmap font + name = name.encode("UTF-8") + + # Draw a label with a name below the face + text_width, text_height = draw.textsize(name) + draw.rectangle(((left, bottom - text_height - 10), (right, bottom)), fill=(0, 0, 255), outline=(0, 0, 255)) + draw.text((left + 6, bottom - text_height - 5), name, fill=(255, 255, 255, 255)) + + # Remove the drawing library from memory as per the Pillow docs + del draw + + # Display the resulting image + pil_image.show() + + +if __name__ == "__main__": + # STEP 1: Train the KNN classifier and save it to disk + # Once the model is trained and saved, you can skip this step next time. + print("Training KNN classifier...") + classifier = train("knn_examples/train", model_save_path="trained_knn_model.clf", n_neighbors=2) + print("Training complete!") + + # STEP 2: Using the trained classifier, make predictions for unknown images + for image_file in os.listdir("knn_examples/test"): + full_file_path = os.path.join("knn_examples/test", image_file) + + print("Looking for faces in {}".format(image_file)) + + # Find all people in the image using a trained classifier model + # Note: You can pass in either a classifier file name or a classifier model instance + predictions = predict(full_file_path, model_path="trained_knn_model.clf") + + # Print results on the console + for name, (top, right, bottom, left) in predictions: + print("- Found {} at ({}, {})".format(name, left, top)) + + # Display results overlaid on an image + show_prediction_labels_on_image(os.path.join("knn_examples/test", image_file), predictions) diff --git a/face_recognition-master/examples/facerec_from_video_file.py b/face_recognition-master/examples/facerec_from_video_file.py new file mode 100644 index 0000000000000000000000000000000000000000..4c1f4ee93559080dfa587ae520c9a9892e3de13a --- /dev/null +++ b/face_recognition-master/examples/facerec_from_video_file.py @@ -0,0 +1,86 @@ +import face_recognition +import cv2 + +# This is a demo of running face recognition on a video file and saving the results to a new video file. +# +# PLEASE NOTE: This example requires OpenCV (the `cv2` library) to be installed only to read from your webcam. +# OpenCV is *not* required to use the face_recognition library. It's only required if you want to run this +# specific demo. If you have trouble installing it, try any of the other demos that don't require it instead. + +# Open the input movie file +input_movie = cv2.VideoCapture("hamilton_clip.mp4") +length = int(input_movie.get(cv2.CAP_PROP_FRAME_COUNT)) + +# Create an output movie file (make sure resolution/frame rate matches input video!) +fourcc = cv2.VideoWriter_fourcc(*'XVID') +output_movie = cv2.VideoWriter('output.avi', fourcc, 29.97, (640, 360)) + +# Load some sample pictures and learn how to recognize them. +lmm_image = face_recognition.load_image_file("lin-manuel-miranda.png") +lmm_face_encoding = face_recognition.face_encodings(lmm_image)[0] + +al_image = face_recognition.load_image_file("alex-lacamoire.png") +al_face_encoding = face_recognition.face_encodings(al_image)[0] + +known_faces = [ + lmm_face_encoding, + al_face_encoding +] + +# Initialize some variables +face_locations = [] +face_encodings = [] +face_names = [] +frame_number = 0 + +while True: + # Grab a single frame of video + ret, frame = input_movie.read() + frame_number += 1 + + # Quit when the input video file ends + if not ret: + break + + # Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses) + rgb_frame = frame[:, :, ::-1] + + # Find all the faces and face encodings in the current frame of video + face_locations = face_recognition.face_locations(rgb_frame) + face_encodings = face_recognition.face_encodings(rgb_frame, face_locations) + + face_names = [] + for face_encoding in face_encodings: + # See if the face is a match for the known face(s) + match = face_recognition.compare_faces(known_faces, face_encoding, tolerance=0.50) + + # If you had more than 2 faces, you could make this logic a lot prettier + # but I kept it simple for the demo + name = None + if match[0]: + name = "Lin-Manuel Miranda" + elif match[1]: + name = "Alex Lacamoire" + + face_names.append(name) + + # Label the results + for (top, right, bottom, left), name in zip(face_locations, face_names): + if not name: + continue + + # Draw a box around the face + cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2) + + # Draw a label with a name below the face + cv2.rectangle(frame, (left, bottom - 25), (right, bottom), (0, 0, 255), cv2.FILLED) + font = cv2.FONT_HERSHEY_DUPLEX + cv2.putText(frame, name, (left + 6, bottom - 6), font, 0.5, (255, 255, 255), 1) + + # Write the resulting image to the output video file + print("Writing frame {} / {}".format(frame_number, length)) + output_movie.write(frame) + +# All done! +input_movie.release() +cv2.destroyAllWindows() diff --git a/face_recognition-master/examples/facerec_from_webcam.py b/face_recognition-master/examples/facerec_from_webcam.py new file mode 100644 index 0000000000000000000000000000000000000000..fea3887d30895069f5eeb1e7474f762aa4485e37 --- /dev/null +++ b/face_recognition-master/examples/facerec_from_webcam.py @@ -0,0 +1,72 @@ +import face_recognition +import cv2 + +# This is a super simple (but slow) example of running face recognition on live video from your webcam. +# There's a second example that's a little more complicated but runs faster. + +# PLEASE NOTE: This example requires OpenCV (the `cv2` library) to be installed only to read from your webcam. +# OpenCV is *not* required to use the face_recognition library. It's only required if you want to run this +# specific demo. If you have trouble installing it, try any of the other demos that don't require it instead. + +# Get a reference to webcam #0 (the default one) +video_capture = cv2.VideoCapture(0) + +# Load a sample picture and learn how to recognize it. +obama_image = face_recognition.load_image_file("obama.jpg") +obama_face_encoding = face_recognition.face_encodings(obama_image)[0] + +# Load a second sample picture and learn how to recognize it. +biden_image = face_recognition.load_image_file("biden.jpg") +biden_face_encoding = face_recognition.face_encodings(biden_image)[0] + +# Create arrays of known face encodings and their names +known_face_encodings = [ + obama_face_encoding, + biden_face_encoding +] +known_face_names = [ + "Barack Obama", + "Joe Biden" +] + +while True: + # Grab a single frame of video + ret, frame = video_capture.read() + + # Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses) + rgb_frame = frame[:, :, ::-1] + + # Find all the faces and face enqcodings in the frame of video + face_locations = face_recognition.face_locations(rgb_frame) + face_encodings = face_recognition.face_encodings(rgb_frame, face_locations) + + # Loop through each face in this frame of video + for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings): + # See if the face is a match for the known face(s) + matches = face_recognition.compare_faces(known_face_encodings, face_encoding) + + name = "Unknown" + + # If a match was found in known_face_encodings, just use the first one. + if True in matches: + first_match_index = matches.index(True) + name = known_face_names[first_match_index] + + # Draw a box around the face + cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2) + + # Draw a label with a name below the face + cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED) + font = cv2.FONT_HERSHEY_DUPLEX + cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1) + + # Display the resulting image + cv2.imshow('Video', frame) + + # Hit 'q' on the keyboard to quit! + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +# Release handle to the webcam +video_capture.release() +cv2.destroyAllWindows() diff --git a/face_recognition-master/examples/facerec_from_webcam_faster.py b/face_recognition-master/examples/facerec_from_webcam_faster.py new file mode 100644 index 0000000000000000000000000000000000000000..1807ac5d8c4f44be13fb02975b5c0f7ddf7d2bab --- /dev/null +++ b/face_recognition-master/examples/facerec_from_webcam_faster.py @@ -0,0 +1,97 @@ +import face_recognition +import cv2 + +# This is a demo of running face recognition on live video from your webcam. It's a little more complicated than the +# other example, but it includes some basic performance tweaks to make things run a lot faster: +# 1. Process each video frame at 1/4 resolution (though still display it at full resolution) +# 2. Only detect faces in every other frame of video. + +# PLEASE NOTE: This example requires OpenCV (the `cv2` library) to be installed only to read from your webcam. +# OpenCV is *not* required to use the face_recognition library. It's only required if you want to run this +# specific demo. If you have trouble installing it, try any of the other demos that don't require it instead. + +# Get a reference to webcam #0 (the default one) +video_capture = cv2.VideoCapture(0) + +# Load a sample picture and learn how to recognize it. +obama_image = face_recognition.load_image_file("obama.jpg") +obama_face_encoding = face_recognition.face_encodings(obama_image)[0] + +# Load a second sample picture and learn how to recognize it. +biden_image = face_recognition.load_image_file("biden.jpg") +biden_face_encoding = face_recognition.face_encodings(biden_image)[0] + +# Create arrays of known face encodings and their names +known_face_encodings = [ + obama_face_encoding, + biden_face_encoding +] +known_face_names = [ + "Barack Obama", + "Joe Biden" +] + +# Initialize some variables +face_locations = [] +face_encodings = [] +face_names = [] +process_this_frame = True + +while True: + # Grab a single frame of video + ret, frame = video_capture.read() + + # Resize frame of video to 1/4 size for faster face recognition processing + small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25) + + # Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses) + rgb_small_frame = small_frame[:, :, ::-1] + + # Only process every other frame of video to save time + if process_this_frame: + # Find all the faces and face encodings in the current frame of video + face_locations = face_recognition.face_locations(rgb_small_frame) + face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations) + + face_names = [] + for face_encoding in face_encodings: + # See if the face is a match for the known face(s) + matches = face_recognition.compare_faces(known_face_encodings, face_encoding) + name = "Unknown" + + # If a match was found in known_face_encodings, just use the first one. + if True in matches: + first_match_index = matches.index(True) + name = known_face_names[first_match_index] + + face_names.append(name) + + process_this_frame = not process_this_frame + + + # Display the results + for (top, right, bottom, left), name in zip(face_locations, face_names): + # Scale back up face locations since the frame we detected in was scaled to 1/4 size + top *= 4 + right *= 4 + bottom *= 4 + left *= 4 + + # Draw a box around the face + cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2) + + # Draw a label with a name below the face + cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED) + font = cv2.FONT_HERSHEY_DUPLEX + cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1) + + # Display the resulting image + cv2.imshow('Video', frame) + + # Hit 'q' on the keyboard to quit! + if cv2.waitKey(1) & 0xFF == ord('q'): + break + +# Release handle to the webcam +video_capture.release() +cv2.destroyAllWindows() diff --git a/face_recognition-master/examples/facerec_on_raspberry_pi.py b/face_recognition-master/examples/facerec_on_raspberry_pi.py new file mode 100644 index 0000000000000000000000000000000000000000..4e874d93f0e9b854bcb6e329393f7f355c1f8d43 --- /dev/null +++ b/face_recognition-master/examples/facerec_on_raspberry_pi.py @@ -0,0 +1,48 @@ +# This is a demo of running face recognition on a Raspberry Pi. +# This program will print out the names of anyone it recognizes to the console. + +# To run this, you need a Raspberry Pi 2 (or greater) with face_recognition and +# the picamera[array] module installed. +# You can follow this installation instructions to get your RPi set up: +# https://gist.github.com/ageitgey/1ac8dbe8572f3f533df6269dab35df65 + +import face_recognition +import picamera +import numpy as np + +# Get a reference to the Raspberry Pi camera. +# If this fails, make sure you have a camera connected to the RPi and that you +# enabled your camera in raspi-config and rebooted first. +camera = picamera.PiCamera() +camera.resolution = (320, 240) +output = np.empty((240, 320, 3), dtype=np.uint8) + +# Load a sample picture and learn how to recognize it. +print("Loading known face image(s)") +obama_image = face_recognition.load_image_file("obama_small.jpg") +obama_face_encoding = face_recognition.face_encodings(obama_image)[0] + +# Initialize some variables +face_locations = [] +face_encodings = [] + +while True: + print("Capturing image.") + # Grab a single frame of video from the RPi camera as a numpy array + camera.capture(output, format="rgb") + + # Find all the faces and face encodings in the current frame of video + face_locations = face_recognition.face_locations(output) + print("Found {} faces in image.".format(len(face_locations))) + face_encodings = face_recognition.face_encodings(output, face_locations) + + # Loop over each face found in the frame to see if it's someone we know. + for face_encoding in face_encodings: + # See if the face is a match for the known face(s) + match = face_recognition.compare_faces([obama_face_encoding], face_encoding) + name = "" + + if match[0]: + name = "Barack Obama" + + print("I see someone named {}!".format(name)) diff --git a/face_recognition-master/examples/facerec_on_raspberry_pi_Simplified_Chinese.py b/face_recognition-master/examples/facerec_on_raspberry_pi_Simplified_Chinese.py new file mode 100644 index 0000000000000000000000000000000000000000..c9287daddacafdd4e4b91154817b326c174143dc --- /dev/null +++ b/face_recognition-master/examples/facerec_on_raspberry_pi_Simplified_Chinese.py @@ -0,0 +1,46 @@ +# 这是一个在树莓派上运行人脸识别的案例 +# 本案例会在命令行控制面板上输出识别出的人脸数量和身份结果。 + +# 你需要一个2代以上的树莓派,并在树莓派上安装face_recognition,并连接上picamera摄像头 +# 并确保picamera这个模块已经安装(树莓派一般会内置安装) +# 你可以参考这个教程配制你的树莓派: +# https://gist.github.com/ageitgey/1ac8dbe8572f3f533df6269dab35df65 + +import face_recognition +import picamera +import numpy as np + +# 你需要在sudo raspi-config中把camera功能打开 +camera = picamera.PiCamera() +camera.resolution = (320, 240) +output = np.empty((240, 320, 3), dtype=np.uint8) + +# 载入样本图片(奥巴马和拜登) +print("Loading known face image(s)") +obama_image = face_recognition.load_image_file("obama_small.jpg") +obama_face_encoding = face_recognition.face_encodings(obama_image)[0] + +# 初始化变量 +face_locations = [] +face_encodings = [] + +while True: + print("Capturing image.") + # 以numpy array的数据结构从picamera摄像头中获取一帧图片 + camera.capture(output, format="rgb") + + # 获得所有人脸的位置以及它们的编码 + face_locations = face_recognition.face_locations(output) + print("Found {} faces in image.".format(len(face_locations))) + face_encodings = face_recognition.face_encodings(output, face_locations) + + # 将每一个人脸与已知样本图片比对 + for face_encoding in face_encodings: + # 看是否属于奥巴马或者拜登 + match = face_recognition.compare_faces([obama_face_encoding], face_encoding) + name = "" + + if match[0]: + name = "Barack Obama" + + print("I see someone named {}!".format(name)) diff --git a/face_recognition-master/examples/find_faces_in_batches.py b/face_recognition-master/examples/find_faces_in_batches.py new file mode 100644 index 0000000000000000000000000000000000000000..dd301498ce9032c30b8b82d545675cfe9732797c --- /dev/null +++ b/face_recognition-master/examples/find_faces_in_batches.py @@ -0,0 +1,55 @@ +import face_recognition +import cv2 + +# This code finds all faces in a list of images using the CNN model. +# +# This demo is for the _special case_ when you need to find faces in LOTS of images very quickly and all the images +# are the exact same size. This is common in video processing applications where you have lots of video frames +# to process. +# +# If you are processing a lot of images and using a GPU with CUDA, batch processing can be ~3x faster then processing +# single images at a time. But if you aren't using a GPU, then batch processing isn't going to be very helpful. +# +# PLEASE NOTE: This example requires OpenCV (the `cv2` library) to be installed only to read the video file. +# OpenCV is *not* required to use the face_recognition library. It's only required if you want to run this +# specific demo. If you have trouble installing it, try any of the other demos that don't require it instead. + +# Open video file +video_capture = cv2.VideoCapture("short_hamilton_clip.mp4") + +frames = [] +frame_count = 0 + +while video_capture.isOpened(): + # Grab a single frame of video + ret, frame = video_capture.read() + + # Bail out when the video file ends + if not ret: + break + + # Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses) + frame = frame[:, :, ::-1] + + # Save each frame of the video to a list + frame_count += 1 + frames.append(frame) + + # Every 128 frames (the default batch size), batch process the list of frames to find faces + if len(frames) == 128: + batch_of_face_locations = face_recognition.batch_face_locations(frames, number_of_times_to_upsample=0) + + # Now let's list all the faces we found in all 128 frames + for frame_number_in_batch, face_locations in enumerate(batch_of_face_locations): + number_of_faces_in_frame = len(face_locations) + + frame_number = frame_count - 128 + frame_number_in_batch + print("I found {} face(s) in frame #{}.".format(number_of_faces_in_frame, frame_number)) + + for face_location in face_locations: + # Print the location of each face in this frame + top, right, bottom, left = face_location + print(" - A face is located at pixel location Top: {}, Left: {}, Bottom: {}, Right: {}".format(top, left, bottom, right)) + + # Clear the frames array to start the next batch + frames = [] diff --git a/face_recognition-master/examples/find_faces_in_picture.py b/face_recognition-master/examples/find_faces_in_picture.py new file mode 100644 index 0000000000000000000000000000000000000000..b136d95bed781bf0aaa06e91dff1c208a0f3388e --- /dev/null +++ b/face_recognition-master/examples/find_faces_in_picture.py @@ -0,0 +1,23 @@ +from PIL import Image +import face_recognition + +# Load the jpg file into a numpy array +image = face_recognition.load_image_file("biden.jpg") + +# Find all the faces in the image using the default HOG-based model. +# This method is fairly accurate, but not as accurate as the CNN model and not GPU accelerated. +# See also: find_faces_in_picture_cnn.py +face_locations = face_recognition.face_locations(image) + +print("I found {} face(s) in this photograph.".format(len(face_locations))) + +for face_location in face_locations: + + # Print the location of each face in this image + top, right, bottom, left = face_location + print("A face is located at pixel location Top: {}, Left: {}, Bottom: {}, Right: {}".format(top, left, bottom, right)) + + # You can access the actual face itself like this: + face_image = image[top:bottom, left:right] + pil_image = Image.fromarray(face_image) + pil_image.show() diff --git a/face_recognition-master/examples/find_faces_in_picture_cnn.py b/face_recognition-master/examples/find_faces_in_picture_cnn.py new file mode 100644 index 0000000000000000000000000000000000000000..9b1904c0dbdade904a0657f7223dce878ed21c60 --- /dev/null +++ b/face_recognition-master/examples/find_faces_in_picture_cnn.py @@ -0,0 +1,25 @@ +from PIL import Image +import face_recognition + +# Load the jpg file into a numpy array +image = face_recognition.load_image_file("biden.jpg") + +# Find all the faces in the image using a pre-trained convolutional neural network. +# This method is more accurate than the default HOG model, but it's slower +# unless you have an nvidia GPU and dlib compiled with CUDA extensions. But if you do, +# this will use GPU acceleration and perform well. +# See also: find_faces_in_picture.py +face_locations = face_recognition.face_locations(image, number_of_times_to_upsample=0, model="cnn") + +print("I found {} face(s) in this photograph.".format(len(face_locations))) + +for face_location in face_locations: + + # Print the location of each face in this image + top, right, bottom, left = face_location + print("A face is located at pixel location Top: {}, Left: {}, Bottom: {}, Right: {}".format(top, left, bottom, right)) + + # You can access the actual face itself like this: + face_image = image[top:bottom, left:right] + pil_image = Image.fromarray(face_image) + pil_image.show() diff --git a/face_recognition-master/examples/find_facial_features_in_picture.py b/face_recognition-master/examples/find_facial_features_in_picture.py new file mode 100644 index 0000000000000000000000000000000000000000..0ff90c62266a0d4d5b5974747a4e9b2c9ad4b505 --- /dev/null +++ b/face_recognition-master/examples/find_facial_features_in_picture.py @@ -0,0 +1,27 @@ +from PIL import Image, ImageDraw +import face_recognition + +# Load the jpg file into a numpy array +image = face_recognition.load_image_file("two_people.jpg") + +# Find all facial features in all the faces in the image +face_landmarks_list = face_recognition.face_landmarks(image) + +print("I found {} face(s) in this photograph.".format(len(face_landmarks_list))) + +# Create a PIL imagedraw object so we can draw on the picture +pil_image = Image.fromarray(image) +d = ImageDraw.Draw(pil_image) + +for face_landmarks in face_landmarks_list: + + # Print the location of each facial feature in this image + for facial_feature in face_landmarks.keys(): + print("The {} in this face has the following points: {}".format(facial_feature, face_landmarks[facial_feature])) + + # Let's trace out each facial feature in the image with a line! + for facial_feature in face_landmarks.keys(): + d.line(face_landmarks[facial_feature], width=5) + +# Show the picture +pil_image.show() diff --git a/face_recognition-master/examples/hamilton_clip.mp4 b/face_recognition-master/examples/hamilton_clip.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..aa6bbc6f73096d5e2828cdf74930780e26dd0b5c Binary files /dev/null and b/face_recognition-master/examples/hamilton_clip.mp4 differ diff --git a/face_recognition-master/examples/identify_and_draw_boxes_on_faces.py b/face_recognition-master/examples/identify_and_draw_boxes_on_faces.py new file mode 100644 index 0000000000000000000000000000000000000000..255d5225868ffeebb722f840351d381d4b38488d --- /dev/null +++ b/face_recognition-master/examples/identify_and_draw_boxes_on_faces.py @@ -0,0 +1,66 @@ +import face_recognition +from PIL import Image, ImageDraw + +# This is an example of running face recognition on a single image +# and drawing a box around each person that was identified. + +# Load a sample picture and learn how to recognize it. +obama_image = face_recognition.load_image_file("obama.jpg") +obama_face_encoding = face_recognition.face_encodings(obama_image)[0] + +# Load a second sample picture and learn how to recognize it. +biden_image = face_recognition.load_image_file("biden.jpg") +biden_face_encoding = face_recognition.face_encodings(biden_image)[0] + +# Create arrays of known face encodings and their names +known_face_encodings = [ + obama_face_encoding, + biden_face_encoding +] +known_face_names = [ + "Barack Obama", + "Joe Biden" +] + +# Load an image with an unknown face +unknown_image = face_recognition.load_image_file("two_people.jpg") + +# Find all the faces and face encodings in the unknown image +face_locations = face_recognition.face_locations(unknown_image) +face_encodings = face_recognition.face_encodings(unknown_image, face_locations) + +# Convert the image to a PIL-format image so that we can draw on top of it with the Pillow library +# See http://pillow.readthedocs.io/ for more about PIL/Pillow +pil_image = Image.fromarray(unknown_image) +# Create a Pillow ImageDraw Draw instance to draw with +draw = ImageDraw.Draw(pil_image) + +# Loop through each face found in the unknown image +for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings): + # See if the face is a match for the known face(s) + matches = face_recognition.compare_faces(known_face_encodings, face_encoding) + + name = "Unknown" + + # If a match was found in known_face_encodings, just use the first one. + if True in matches: + first_match_index = matches.index(True) + name = known_face_names[first_match_index] + + # Draw a box around the face using the Pillow module + draw.rectangle(((left, top), (right, bottom)), outline=(0, 0, 255)) + + # Draw a label with a name below the face + text_width, text_height = draw.textsize(name) + draw.rectangle(((left, bottom - text_height - 10), (right, bottom)), fill=(0, 0, 255), outline=(0, 0, 255)) + draw.text((left + 6, bottom - text_height - 5), name, fill=(255, 255, 255, 255)) + + +# Remove the drawing library from memory as per the Pillow docs +del draw + +# Display the resulting image +pil_image.show() + +# You can also save a copy of the new image to disk if you want by uncommenting this line +# pil_image.save("image_with_boxes.jpg") diff --git a/face_recognition-master/examples/ipynb_examples/track_faces_on_video_realtime.ipynb b/face_recognition-master/examples/ipynb_examples/track_faces_on_video_realtime.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..4baeb510f4f7994c8bf81fbd1c4960de728d1e39 --- /dev/null +++ b/face_recognition-master/examples/ipynb_examples/track_faces_on_video_realtime.ipynb @@ -0,0 +1,123 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### This demo shows how to detect faces from video and displays result in realtime\n", + "\n", + "You need OpenCV installed to run this example. To install it, run ___pip install opencv-python___\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Populating the interactive namespace from numpy and matplotlib\n" + ] + } + ], + "source": [ + "%pylab inline \n", + "import face_recognition\n", + "import cv2\n", + "import matplotlib.patches as patches\n", + "from IPython.display import clear_output\n", + "from matplotlib.pyplot import imshow\n", + "import matplotlib.pylab as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAADrCAYAAABn7V3CAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4wLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvpW3flQAAIABJREFUeJzsvXmwbNt91/f5rbV3d5/53OHd+4b7\nBg2WJes9yzLIkhHCdsWOjSEYipghRQIVCkNSCVTCHzghkDCFKRUIlQRimwKXASPZBOzYjmJsMGBs\nyQ8/C6PJenpPb7zzvWc+p7v3XuuXP35r7b27T59zz7mDdCX6V9Wn+3TvvfYaf+v3+/6GJarKnOY0\npznN6SuX3Je6AnOa05zmNKcHS3NGP6c5zWlOX+E0Z/RzmtOc5vQVTnNGP6c5zWlOX+E0Z/RzmtOc\n5vQVTnNGP6c5zWlOX+E0Z/RzmtOc5vQVTnNGP6eHgkTkFRH51i/Cc/4nEfl7d7jmN4rIL4jIlojc\nFpF/LSLvS7/9ARH5+QddzznN6X5S8aWuwJzm9DCRiKwCPwH8F8BHgB7wIWB0ijK8qoYHU8M5zen0\nNJfo5/TQUZaaReR/EZENEfmCiPzmzu8/JyJ/UUR+KUndPyYiZ9Nv3ywib0yV94qIfKuIfAfw3wO/\nW0R2ReTfznj8OwBU9YdVNajqgar+tKr+qoi8C/hbwDem+zdT+X9XRP6miPyUiOwB3yIi/VT/10Tk\nmoj8LRFZSNefEZGfEJEbqX0/ISKXptr355NWsSsi/4+InBORvy8i2yLyvIg8cz/7fE5f2TRn9HN6\nWOn9wK8B54G/AvxtEZHO7/8Z8J8DjwM18DfuVKCqfhT4n4EPq+qyqr5nxmWfA4KI/KCI/GYROdO5\n/zPAHwF+Md2/3rnvPwH+ArAC/Dzwl7FN4+uAtwNPAH86XeuAvwM8DTwFHAD/+1Q9fg/wn6b73gb8\nYrrnLPAZ4H+8U3vnNKdMc0Y/p4eVXlXV708QyA8CjwEXO7//kKp+UlX3gD8F/C4R8ff6UFXdBn4j\noMD3AzdE5MdF5OLxd/JjqvqvVTViMM8fAv4bVb2tqjvYBvN70jNuqeo/UtX99NtfAL5pqry/o6ov\nqeoW8P8CL6nqz6hqDfwI8N57beuc/v2hOUY/p4eVruYPqrqfhPnlzu+vdz6/CpSY9H/PlCT3PwAg\n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\nAR/ZM0ufICocAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Loading video for face detection\n", + "video_capture = cv2.VideoCapture(\"../hamilton_clip.mp4\")\n", + "\n", + "frame_count = 0\n", + "\n", + "while video_capture.isOpened(): \n", + " # Grab a single frame of video\n", + " ret, frame = video_capture.read()\n", + "\n", + " # Bail out when the video file ends\n", + " if not ret:\n", + " video_capture.release()\n", + " break\n", + " \n", + " # We will search face in every 15 frames to speed up process.\n", + " frame_count += 1\n", + " if frame_count % 15 == 0: \n", + " frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)\n", + " \n", + " # Display video frame\n", + " title(\"Input Stream\")\n", + " plt.imshow(frame) \n", + "\n", + " # Find all the faces and face encodings in the current frame of video\n", + " rgb_frame = frame[:, :, ::-1]\n", + " face_locations = face_recognition.face_locations(rgb_frame)\n", + " \n", + " # If faces were found, we will mark it on frame with blue dots\n", + " for face_location in face_locations: \n", + " plt.plot(face_location[1], face_location[0], 'bo')\n", + " plt.plot(face_location[1], face_location[2], 'bo')\n", + " plt.plot(face_location[3], face_location[2], 'bo')\n", + " plt.plot(face_location[3], face_location[0], 'bo')\n", + "\n", + " # Show frame...\n", + " plt.show() \n", + " # ... and hold it until a new frame appears\n", + " clear_output(wait=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/face_recognition-master/examples/knn_examples/test/alex_lacamoire1.jpg b/face_recognition-master/examples/knn_examples/test/alex_lacamoire1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..787d8e4c832d9556f360d66878ff6f072459b989 Binary files /dev/null and b/face_recognition-master/examples/knn_examples/test/alex_lacamoire1.jpg differ diff --git a/face_recognition-master/examples/knn_examples/test/johnsnow_test1.jpg b/face_recognition-master/examples/knn_examples/test/johnsnow_test1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..291f2ce33a23514689e09e6fd8c2893a0ceb0931 Binary files /dev/null and b/face_recognition-master/examples/knn_examples/test/johnsnow_test1.jpg differ diff --git a/face_recognition-master/examples/knn_examples/test/kit_with_rose.jpg b/face_recognition-master/examples/knn_examples/test/kit_with_rose.jpg new file mode 100644 index 0000000000000000000000000000000000000000..32029c1769929d3353f12d9c81bdcda5f3401b1c Binary files /dev/null and b/face_recognition-master/examples/knn_examples/test/kit_with_rose.jpg differ diff --git a/face_recognition-master/examples/knn_examples/test/obama1.jpg b/face_recognition-master/examples/knn_examples/test/obama1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c379e8a23e9226066f05a6961a7966f3ac4a05e8 Binary files /dev/null and b/face_recognition-master/examples/knn_examples/test/obama1.jpg differ diff --git a/face_recognition-master/examples/knn_examples/test/obama_and_biden.jpg b/face_recognition-master/examples/knn_examples/test/obama_and_biden.jpg new file mode 100644 index 0000000000000000000000000000000000000000..66fd84a8fcaa687648d3c138e972e8ea9bbc84f8 Binary files /dev/null and b/face_recognition-master/examples/knn_examples/test/obama_and_biden.jpg differ diff --git a/face_recognition-master/examples/knn_examples/train/alex_lacamoire/img1.jpg b/face_recognition-master/examples/knn_examples/train/alex_lacamoire/img1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c629d3464e965def54c83a86ea3ce70389f0c9db Binary files /dev/null and b/face_recognition-master/examples/knn_examples/train/alex_lacamoire/img1.jpg differ diff --git a/face_recognition-master/examples/knn_examples/train/biden/biden.jpg b/face_recognition-master/examples/knn_examples/train/biden/biden.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3a0bdc974e9067b1595a6a623a3d898265b0a7a2 Binary files /dev/null and b/face_recognition-master/examples/knn_examples/train/biden/biden.jpg differ diff --git a/face_recognition-master/examples/knn_examples/train/biden/biden2.jpg b/face_recognition-master/examples/knn_examples/train/biden/biden2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9730f97ab80dbf0ff9553676f4659d34e9c9a963 Binary files /dev/null and b/face_recognition-master/examples/knn_examples/train/biden/biden2.jpg differ diff --git a/face_recognition-master/examples/knn_examples/train/kit_harington/john1.jpeg b/face_recognition-master/examples/knn_examples/train/kit_harington/john1.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..8afd6a5be809a5bffba508acd16493812f242136 Binary files /dev/null and b/face_recognition-master/examples/knn_examples/train/kit_harington/john1.jpeg differ diff --git a/face_recognition-master/examples/knn_examples/train/kit_harington/john2.jpeg b/face_recognition-master/examples/knn_examples/train/kit_harington/john2.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..406453587f342954570033d1e5e4e326b22fabc0 Binary files /dev/null and b/face_recognition-master/examples/knn_examples/train/kit_harington/john2.jpeg differ diff --git a/face_recognition-master/examples/knn_examples/train/obama/obama.jpg b/face_recognition-master/examples/knn_examples/train/obama/obama.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1ce4b846f50bea6c0e8348a351413bfdd6ea1f86 Binary files /dev/null and b/face_recognition-master/examples/knn_examples/train/obama/obama.jpg differ diff --git a/face_recognition-master/examples/knn_examples/train/obama/obama2.jpg b/face_recognition-master/examples/knn_examples/train/obama/obama2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b9b60c4680686f27cee2e2b242e115dde62b6443 Binary files /dev/null and b/face_recognition-master/examples/knn_examples/train/obama/obama2.jpg differ diff --git a/face_recognition-master/examples/knn_examples/train/rose_leslie/img1.jpg b/face_recognition-master/examples/knn_examples/train/rose_leslie/img1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8872b8bb2d0deea52a83328dfc6c8bd22cb12dd6 Binary files /dev/null and b/face_recognition-master/examples/knn_examples/train/rose_leslie/img1.jpg differ diff --git a/face_recognition-master/examples/knn_examples/train/rose_leslie/img2.jpg b/face_recognition-master/examples/knn_examples/train/rose_leslie/img2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6a3b5a557f37df9f499f4b42ea9594383786f226 Binary files /dev/null and b/face_recognition-master/examples/knn_examples/train/rose_leslie/img2.jpg differ diff --git a/face_recognition-master/examples/lin-manuel-miranda.png b/face_recognition-master/examples/lin-manuel-miranda.png new file mode 100644 index 0000000000000000000000000000000000000000..0ecf41c90e5ec520aea753ad4063fef498806eae Binary files /dev/null and b/face_recognition-master/examples/lin-manuel-miranda.png differ diff --git a/face_recognition-master/examples/obama-1080p.jpg b/face_recognition-master/examples/obama-1080p.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a244779067c801d8e744b0fc6a83a82a34574b1f Binary files /dev/null and b/face_recognition-master/examples/obama-1080p.jpg differ diff --git a/face_recognition-master/examples/obama-240p.jpg b/face_recognition-master/examples/obama-240p.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c4a947a52a1d81e41c25b84c214604a233e85fb6 Binary files /dev/null and b/face_recognition-master/examples/obama-240p.jpg differ diff --git a/face_recognition-master/examples/obama-480p.jpg b/face_recognition-master/examples/obama-480p.jpg new file mode 100644 index 0000000000000000000000000000000000000000..78837efc451cea599ea009138d69a57292640059 Binary files /dev/null and b/face_recognition-master/examples/obama-480p.jpg differ diff --git a/face_recognition-master/examples/obama-720p.jpg b/face_recognition-master/examples/obama-720p.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d06cec3e257778cd802e355359fcf653daeb7208 Binary files /dev/null and b/face_recognition-master/examples/obama-720p.jpg differ diff --git a/face_recognition-master/examples/obama.jpg b/face_recognition-master/examples/obama.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1ce4b846f50bea6c0e8348a351413bfdd6ea1f86 Binary files /dev/null and b/face_recognition-master/examples/obama.jpg differ diff --git a/face_recognition-master/examples/obama2.jpg b/face_recognition-master/examples/obama2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b9b60c4680686f27cee2e2b242e115dde62b6443 Binary files /dev/null and b/face_recognition-master/examples/obama2.jpg differ diff --git a/face_recognition-master/examples/obama_small.jpg b/face_recognition-master/examples/obama_small.jpg new file mode 100644 index 0000000000000000000000000000000000000000..371691dfc844215a2277541ea831f721e1ad3c6f Binary files /dev/null and b/face_recognition-master/examples/obama_small.jpg differ diff --git a/face_recognition-master/examples/recognize_faces_in_pictures.py b/face_recognition-master/examples/recognize_faces_in_pictures.py new file mode 100644 index 0000000000000000000000000000000000000000..b56df46f5d486214b439a668c2cb97d6c5bb0bde --- /dev/null +++ b/face_recognition-master/examples/recognize_faces_in_pictures.py @@ -0,0 +1,29 @@ +import face_recognition + +# Load the jpg files into numpy arrays +biden_image = face_recognition.load_image_file("biden.jpg") +obama_image = face_recognition.load_image_file("obama.jpg") +unknown_image = face_recognition.load_image_file("obama2.jpg") + +# Get the face encodings for each face in each image file +# Since there could be more than one face in each image, it returns a list of encodings. +# But since I know each image only has one face, I only care about the first encoding in each image, so I grab index 0. +try: + biden_face_encoding = face_recognition.face_encodings(biden_image)[0] + obama_face_encoding = face_recognition.face_encodings(obama_image)[0] + unknown_face_encoding = face_recognition.face_encodings(unknown_image)[0] +except IndexError: + print("I wasn't able to locate any faces in at least one of the images. Check the image files. Aborting...") + quit() + +known_faces = [ + biden_face_encoding, + obama_face_encoding +] + +# results is an array of True/False telling if the unknown face matched anyone in the known_faces array +results = face_recognition.compare_faces(known_faces, unknown_face_encoding) + +print("Is the unknown face a picture of Biden? {}".format(results[0])) +print("Is the unknown face a picture of Obama? {}".format(results[1])) +print("Is the unknown face a new person that we've never seen before? {}".format(not True in results)) diff --git a/face_recognition-master/examples/short_hamilton_clip.mp4 b/face_recognition-master/examples/short_hamilton_clip.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..467f44c939ac350f521ca0084a7927f8e5951d5b Binary files /dev/null and b/face_recognition-master/examples/short_hamilton_clip.mp4 differ diff --git a/face_recognition-master/examples/two_people.jpg b/face_recognition-master/examples/two_people.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e62376298c040d28aea5befc0ac66b9b6b59b410 Binary files /dev/null and b/face_recognition-master/examples/two_people.jpg differ diff --git a/face_recognition-master/examples/web_service_example.py b/face_recognition-master/examples/web_service_example.py new file mode 100644 index 0000000000000000000000000000000000000000..e0860a3207d8d53af086de3832b757dc06430a05 --- /dev/null +++ b/face_recognition-master/examples/web_service_example.py @@ -0,0 +1,113 @@ +# This is a _very simple_ example of a web service that recognizes faces in uploaded images. +# Upload an image file and it will check if the image contains a picture of Barack Obama. +# The result is returned as json. For example: +# +# $ curl -XPOST -F "file=@obama2.jpg" http://127.0.0.1:5001 +# +# Returns: +# +# { +# "face_found_in_image": true, +# "is_picture_of_obama": true +# } +# +# This example is based on the Flask file upload example: http://flask.pocoo.org/docs/0.12/patterns/fileuploads/ + +# NOTE: This example requires flask to be installed! You can install it with pip: +# $ pip3 install flask + +import face_recognition +from flask import Flask, jsonify, request, redirect + +# You can change this to any folder on your system +ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'} + +app = Flask(__name__) + + +def allowed_file(filename): + return '.' in filename and \ + filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS + + +@app.route('/', methods=['GET', 'POST']) +def upload_image(): + # Check if a valid image file was uploaded + if request.method == 'POST': + if 'file' not in request.files: + return redirect(request.url) + + file = request.files['file'] + + if file.filename == '': + return redirect(request.url) + + if file and allowed_file(file.filename): + # The image file seems valid! Detect faces and return the result. + return detect_faces_in_image(file) + + # If no valid image file was uploaded, show the file upload form: + return ''' + + Is this a picture of Obama? +

Upload a picture and see if it's a picture of Obama!

+
+ + +
+ ''' + + +def detect_faces_in_image(file_stream): + # Pre-calculated face encoding of Obama generated with face_recognition.face_encodings(img) + known_face_encoding = [-0.09634063, 0.12095481, -0.00436332, -0.07643753, 0.0080383, + 0.01902981, -0.07184699, -0.09383309, 0.18518871, -0.09588896, + 0.23951106, 0.0986533 , -0.22114635, -0.1363683 , 0.04405268, + 0.11574756, -0.19899382, -0.09597053, -0.11969153, -0.12277931, + 0.03416885, -0.00267565, 0.09203379, 0.04713435, -0.12731361, + -0.35371891, -0.0503444 , -0.17841317, -0.00310897, -0.09844551, + -0.06910533, -0.00503746, -0.18466514, -0.09851682, 0.02903969, + -0.02174894, 0.02261871, 0.0032102 , 0.20312519, 0.02999607, + -0.11646006, 0.09432904, 0.02774341, 0.22102901, 0.26725179, + 0.06896867, -0.00490024, -0.09441824, 0.11115381, -0.22592428, + 0.06230862, 0.16559327, 0.06232892, 0.03458837, 0.09459756, + -0.18777156, 0.00654241, 0.08582542, -0.13578284, 0.0150229 , + 0.00670836, -0.08195844, -0.04346499, 0.03347827, 0.20310158, + 0.09987706, -0.12370517, -0.06683611, 0.12704916, -0.02160804, + 0.00984683, 0.00766284, -0.18980607, -0.19641446, -0.22800779, + 0.09010898, 0.39178532, 0.18818057, -0.20875394, 0.03097027, + -0.21300618, 0.02532415, 0.07938635, 0.01000703, -0.07719778, + -0.12651891, -0.04318593, 0.06219772, 0.09163868, 0.05039065, + -0.04922386, 0.21839413, -0.02394437, 0.06173781, 0.0292527 , + 0.06160797, -0.15553983, -0.02440624, -0.17509389, -0.0630486 , + 0.01428208, -0.03637431, 0.03971229, 0.13983178, -0.23006812, + 0.04999552, 0.0108454 , -0.03970895, 0.02501768, 0.08157793, + -0.03224047, -0.04502571, 0.0556995 , -0.24374914, 0.25514284, + 0.24795187, 0.04060191, 0.17597422, 0.07966681, 0.01920104, + -0.01194376, -0.02300822, -0.17204897, -0.0596558 , 0.05307484, + 0.07417042, 0.07126575, 0.00209804] + + # Load the uploaded image file + img = face_recognition.load_image_file(file_stream) + # Get face encodings for any faces in the uploaded image + unknown_face_encodings = face_recognition.face_encodings(img) + + face_found = False + is_obama = False + + if len(unknown_face_encodings) > 0: + face_found = True + # See if the first face in the uploaded image matches the known face of Obama + match_results = face_recognition.compare_faces([known_face_encoding], unknown_face_encodings[0]) + if match_results[0]: + is_obama = True + + # Return the result as json + result = { + "face_found_in_image": face_found, + "is_picture_of_obama": is_obama + } + return jsonify(result) + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=5001, debug=True) diff --git a/face_recognition-master/examples/web_service_example_Simplified_Chinese.py b/face_recognition-master/examples/web_service_example_Simplified_Chinese.py new file mode 100644 index 0000000000000000000000000000000000000000..92eb0cc1dd01616be78428f18928a691ec0cfc9b --- /dev/null +++ b/face_recognition-master/examples/web_service_example_Simplified_Chinese.py @@ -0,0 +1,110 @@ +# 这是一个非常简单的使用Web服务上传图片运行人脸识别的案例,后端服务器会识别这张图片是不是奥巴马,并把识别结果以json键值对输出 +# 比如:运行以下代码 +# $ curl -XPOST -F "file=@obama2.jpg" http://127.0.0.1:5001 +# 会返回: +# { +# "face_found_in_image": true, +# "is_picture_of_obama": true +# } +# +# 本项目基于Flask框架的案例 http://flask.pocoo.org/docs/0.12/patterns/fileuploads/ + +# 提示:运行本案例需要安装Flask,你可以用下面的代码安装Flask +# $ pip3 install flask + +import face_recognition +from flask import Flask, jsonify, request, redirect + +# You can change this to any folder on your system +ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'} + +app = Flask(__name__) + + +def allowed_file(filename): + return '.' in filename and \ + filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS + + +@app.route('/', methods=['GET', 'POST']) +def upload_image(): + # 检测图片是否上传成功 + if request.method == 'POST': + if 'file' not in request.files: + return redirect(request.url) + + file = request.files['file'] + + if file.filename == '': + return redirect(request.url) + + if file and allowed_file(file.filename): + # 图片上传成功,检测图片中的人脸 + return detect_faces_in_image(file) + + # 图片上传失败,输出以下html代码 + return ''' + + Is this a picture of Obama? +

Upload a picture and see if it's a picture of Obama!

+
+ + +
+ ''' + + +def detect_faces_in_image(file_stream): + # 用face_recognition.face_encodings(img)接口提前把奥巴马人脸的编码录入 + known_face_encoding = [-0.09634063, 0.12095481, -0.00436332, -0.07643753, 0.0080383, + 0.01902981, -0.07184699, -0.09383309, 0.18518871, -0.09588896, + 0.23951106, 0.0986533 , -0.22114635, -0.1363683 , 0.04405268, + 0.11574756, -0.19899382, -0.09597053, -0.11969153, -0.12277931, + 0.03416885, -0.00267565, 0.09203379, 0.04713435, -0.12731361, + -0.35371891, -0.0503444 , -0.17841317, -0.00310897, -0.09844551, + -0.06910533, -0.00503746, -0.18466514, -0.09851682, 0.02903969, + -0.02174894, 0.02261871, 0.0032102 , 0.20312519, 0.02999607, + -0.11646006, 0.09432904, 0.02774341, 0.22102901, 0.26725179, + 0.06896867, -0.00490024, -0.09441824, 0.11115381, -0.22592428, + 0.06230862, 0.16559327, 0.06232892, 0.03458837, 0.09459756, + -0.18777156, 0.00654241, 0.08582542, -0.13578284, 0.0150229 , + 0.00670836, -0.08195844, -0.04346499, 0.03347827, 0.20310158, + 0.09987706, -0.12370517, -0.06683611, 0.12704916, -0.02160804, + 0.00984683, 0.00766284, -0.18980607, -0.19641446, -0.22800779, + 0.09010898, 0.39178532, 0.18818057, -0.20875394, 0.03097027, + -0.21300618, 0.02532415, 0.07938635, 0.01000703, -0.07719778, + -0.12651891, -0.04318593, 0.06219772, 0.09163868, 0.05039065, + -0.04922386, 0.21839413, -0.02394437, 0.06173781, 0.0292527 , + 0.06160797, -0.15553983, -0.02440624, -0.17509389, -0.0630486 , + 0.01428208, -0.03637431, 0.03971229, 0.13983178, -0.23006812, + 0.04999552, 0.0108454 , -0.03970895, 0.02501768, 0.08157793, + -0.03224047, -0.04502571, 0.0556995 , -0.24374914, 0.25514284, + 0.24795187, 0.04060191, 0.17597422, 0.07966681, 0.01920104, + -0.01194376, -0.02300822, -0.17204897, -0.0596558 , 0.05307484, + 0.07417042, 0.07126575, 0.00209804] + + # 载入用户上传的图片 + img = face_recognition.load_image_file(file_stream) + # 为用户上传的图片中的人脸编码 + unknown_face_encodings = face_recognition.face_encodings(img) + + face_found = False + is_obama = False + + if len(unknown_face_encodings) > 0: + face_found = True + # 看看图片中的第一张脸是不是奥巴马 + match_results = face_recognition.compare_faces([known_face_encoding], unknown_face_encodings[0]) + if match_results[0]: + is_obama = True + + # 讲识别结果以json键值对的数据结构输出 + result = { + "face_found_in_image": face_found, + "is_picture_of_obama": is_obama + } + return jsonify(result) + + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=5001, debug=True) diff --git a/face_recognition-master/face_recognition/__init__.py b/face_recognition-master/face_recognition/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5c96187e0a17e3ed9990f864fca5d218f6a2ebb1 --- /dev/null +++ b/face_recognition-master/face_recognition/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- + +__author__ = """Adam Geitgey""" +__email__ = 'ageitgey@gmail.com' +__version__ = '1.2.3' + +from .api import load_image_file, face_locations, batch_face_locations, face_landmarks, face_encodings, compare_faces, face_distance diff --git a/face_recognition-master/face_recognition/api.py b/face_recognition-master/face_recognition/api.py new file mode 100644 index 0000000000000000000000000000000000000000..fd73a4894214e13285a0a51abf941b6b2e138a68 --- /dev/null +++ b/face_recognition-master/face_recognition/api.py @@ -0,0 +1,222 @@ +# -*- coding: utf-8 -*- + +import PIL.Image +import dlib +import numpy as np + +try: + import face_recognition_models +except Exception: + print("Please install `face_recognition_models` with this command before using `face_recognition`:\n") + print("pip install git+https://github.com/ageitgey/face_recognition_models") + quit() + +face_detector = dlib.get_frontal_face_detector() + +predictor_68_point_model = face_recognition_models.pose_predictor_model_location() +pose_predictor_68_point = dlib.shape_predictor(predictor_68_point_model) + +predictor_5_point_model = face_recognition_models.pose_predictor_five_point_model_location() +pose_predictor_5_point = dlib.shape_predictor(predictor_5_point_model) + +cnn_face_detection_model = face_recognition_models.cnn_face_detector_model_location() +cnn_face_detector = dlib.cnn_face_detection_model_v1(cnn_face_detection_model) + +face_recognition_model = face_recognition_models.face_recognition_model_location() +face_encoder = dlib.face_recognition_model_v1(face_recognition_model) + + +def _rect_to_css(rect): + """ + Convert a dlib 'rect' object to a plain tuple in (top, right, bottom, left) order + + :param rect: a dlib 'rect' object + :return: a plain tuple representation of the rect in (top, right, bottom, left) order + """ + return rect.top(), rect.right(), rect.bottom(), rect.left() + + +def _css_to_rect(css): + """ + Convert a tuple in (top, right, bottom, left) order to a dlib `rect` object + + :param css: plain tuple representation of the rect in (top, right, bottom, left) order + :return: a dlib `rect` object + """ + return dlib.rectangle(css[3], css[0], css[1], css[2]) + + +def _trim_css_to_bounds(css, image_shape): + """ + Make sure a tuple in (top, right, bottom, left) order is within the bounds of the image. + + :param css: plain tuple representation of the rect in (top, right, bottom, left) order + :param image_shape: numpy shape of the image array + :return: a trimmed plain tuple representation of the rect in (top, right, bottom, left) order + """ + return max(css[0], 0), min(css[1], image_shape[1]), min(css[2], image_shape[0]), max(css[3], 0) + + +def face_distance(face_encodings, face_to_compare): + """ + Given a list of face encodings, compare them to a known face encoding and get a euclidean distance + for each comparison face. The distance tells you how similar the faces are. + + :param faces: List of face encodings to compare + :param face_to_compare: A face encoding to compare against + :return: A numpy ndarray with the distance for each face in the same order as the 'faces' array + """ + if len(face_encodings) == 0: + return np.empty((0)) + + return np.linalg.norm(face_encodings - face_to_compare, axis=1) + + +def load_image_file(file, mode='RGB'): + """ + Loads an image file (.jpg, .png, etc) into a numpy array + + :param file: image file name or file object to load + :param mode: format to convert the image to. Only 'RGB' (8-bit RGB, 3 channels) and 'L' (black and white) are supported. + :return: image contents as numpy array + """ + im = PIL.Image.open(file) + if mode: + im = im.convert(mode) + return np.array(im) + + +def _raw_face_locations(img, number_of_times_to_upsample=1, model="hog"): + """ + Returns an array of bounding boxes of human faces in a image + + :param img: An image (as a numpy array) + :param number_of_times_to_upsample: How many times to upsample the image looking for faces. Higher numbers find smaller faces. + :param model: Which face detection model to use. "hog" is less accurate but faster on CPUs. "cnn" is a more accurate + deep-learning model which is GPU/CUDA accelerated (if available). The default is "hog". + :return: A list of dlib 'rect' objects of found face locations + """ + if model == "cnn": + return cnn_face_detector(img, number_of_times_to_upsample) + else: + return face_detector(img, number_of_times_to_upsample) + + +def face_locations(img, number_of_times_to_upsample=1, model="hog"): + """ + Returns an array of bounding boxes of human faces in a image + + :param img: An image (as a numpy array) + :param number_of_times_to_upsample: How many times to upsample the image looking for faces. Higher numbers find smaller faces. + :param model: Which face detection model to use. "hog" is less accurate but faster on CPUs. "cnn" is a more accurate + deep-learning model which is GPU/CUDA accelerated (if available). The default is "hog". + :return: A list of tuples of found face locations in css (top, right, bottom, left) order + """ + if model == "cnn": + return [_trim_css_to_bounds(_rect_to_css(face.rect), img.shape) for face in _raw_face_locations(img, number_of_times_to_upsample, "cnn")] + else: + return [_trim_css_to_bounds(_rect_to_css(face), img.shape) for face in _raw_face_locations(img, number_of_times_to_upsample, model)] + + +def _raw_face_locations_batched(images, number_of_times_to_upsample=1, batch_size=128): + """ + Returns an 2d array of dlib rects of human faces in a image using the cnn face detector + + :param img: A list of images (each as a numpy array) + :param number_of_times_to_upsample: How many times to upsample the image looking for faces. Higher numbers find smaller faces. + :return: A list of dlib 'rect' objects of found face locations + """ + return cnn_face_detector(images, number_of_times_to_upsample, batch_size=batch_size) + + +def batch_face_locations(images, number_of_times_to_upsample=1, batch_size=128): + """ + Returns an 2d array of bounding boxes of human faces in a image using the cnn face detector + If you are using a GPU, this can give you much faster results since the GPU + can process batches of images at once. If you aren't using a GPU, you don't need this function. + + :param img: A list of images (each as a numpy array) + :param number_of_times_to_upsample: How many times to upsample the image looking for faces. Higher numbers find smaller faces. + :param batch_size: How many images to include in each GPU processing batch. + :return: A list of tuples of found face locations in css (top, right, bottom, left) order + """ + def convert_cnn_detections_to_css(detections): + return [_trim_css_to_bounds(_rect_to_css(face.rect), images[0].shape) for face in detections] + + raw_detections_batched = _raw_face_locations_batched(images, number_of_times_to_upsample, batch_size) + + return list(map(convert_cnn_detections_to_css, raw_detections_batched)) + + +def _raw_face_landmarks(face_image, face_locations=None, model="large"): + if face_locations is None: + face_locations = _raw_face_locations(face_image) + else: + face_locations = [_css_to_rect(face_location) for face_location in face_locations] + + pose_predictor = pose_predictor_68_point + + if model == "small": + pose_predictor = pose_predictor_5_point + + return [pose_predictor(face_image, face_location) for face_location in face_locations] + + +def face_landmarks(face_image, face_locations=None, model="large"): + """ + Given an image, returns a dict of face feature locations (eyes, nose, etc) for each face in the image + + :param face_image: image to search + :param face_locations: Optionally provide a list of face locations to check. + :param model: Optional - which model to use. "large" (default) or "small" which only returns 5 points but is faster. + :return: A list of dicts of face feature locations (eyes, nose, etc) + """ + landmarks = _raw_face_landmarks(face_image, face_locations, model) + landmarks_as_tuples = [[(p.x, p.y) for p in landmark.parts()] for landmark in landmarks] + + # For a definition of each point index, see https://cdn-images-1.medium.com/max/1600/1*AbEg31EgkbXSQehuNJBlWg.png + if model == 'large': + return [{ + "chin": points[0:17], + "left_eyebrow": points[17:22], + "right_eyebrow": points[22:27], + "nose_bridge": points[27:31], + "nose_tip": points[31:36], + "left_eye": points[36:42], + "right_eye": points[42:48], + "top_lip": points[48:55] + [points[64]] + [points[63]] + [points[62]] + [points[61]] + [points[60]], + "bottom_lip": points[54:60] + [points[48]] + [points[60]] + [points[67]] + [points[66]] + [points[65]] + [points[64]] + } for points in landmarks_as_tuples] + elif model == 'small': + return [{ + "nose_tip": [points[4]], + "left_eye": points[2:4], + "right_eye": points[0:2], + } for points in landmarks_as_tuples] + else: + raise ValueError("Invalid landmarks model type. Supported models are ['small', 'large'].") + + +def face_encodings(face_image, known_face_locations=None, num_jitters=1): + """ + Given an image, return the 128-dimension face encoding for each face in the image. + + :param face_image: The image that contains one or more faces + :param known_face_locations: Optional - the bounding boxes of each face if you already know them. + :param num_jitters: How many times to re-sample the face when calculating encoding. Higher is more accurate, but slower (i.e. 100 is 100x slower) + :return: A list of 128-dimensional face encodings (one for each face in the image) + """ + raw_landmarks = _raw_face_landmarks(face_image, known_face_locations, model="small") + return [np.array(face_encoder.compute_face_descriptor(face_image, raw_landmark_set, num_jitters)) for raw_landmark_set in raw_landmarks] + + +def compare_faces(known_face_encodings, face_encoding_to_check, tolerance=0.6): + """ + Compare a list of face encodings against a candidate encoding to see if they match. + + :param known_face_encodings: A list of known face encodings + :param face_encoding_to_check: A single face encoding to compare against the list + :param tolerance: How much distance between faces to consider it a match. Lower is more strict. 0.6 is typical best performance. + :return: A list of True/False values indicating which known_face_encodings match the face encoding to check + """ + return list(face_distance(known_face_encodings, face_encoding_to_check) <= tolerance) diff --git a/face_recognition-master/face_recognition/face_detection_cli.py b/face_recognition-master/face_recognition/face_detection_cli.py new file mode 100644 index 0000000000000000000000000000000000000000..595636c06672b39cf4262b042df11954a6609b9a --- /dev/null +++ b/face_recognition-master/face_recognition/face_detection_cli.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +from __future__ import print_function +import click +import os +import re +import face_recognition.api as face_recognition +import multiprocessing +import sys +import itertools + + +def print_result(filename, location): + top, right, bottom, left = location + print("{},{},{},{},{}".format(filename, top, right, bottom, left)) + + +def test_image(image_to_check, model): + unknown_image = face_recognition.load_image_file(image_to_check) + face_locations = face_recognition.face_locations(unknown_image, number_of_times_to_upsample=0, model=model) + + for face_location in face_locations: + print_result(image_to_check, face_location) + + +def image_files_in_folder(folder): + return [os.path.join(folder, f) for f in os.listdir(folder) if re.match(r'.*\.(jpg|jpeg|png)', f, flags=re.I)] + + +def process_images_in_process_pool(images_to_check, number_of_cpus, model): + if number_of_cpus == -1: + processes = None + else: + processes = number_of_cpus + + # macOS will crash due to a bug in libdispatch if you don't use 'forkserver' + context = multiprocessing + if "forkserver" in multiprocessing.get_all_start_methods(): + context = multiprocessing.get_context("forkserver") + + pool = context.Pool(processes=processes) + + function_parameters = zip( + images_to_check, + itertools.repeat(model), + ) + + pool.starmap(test_image, function_parameters) + + +@click.command() +@click.argument('image_to_check') +@click.option('--cpus', default=1, help='number of CPU cores to use in parallel. -1 means "use all in system"') +@click.option('--model', default="hog", help='Which face detection model to use. Options are "hog" or "cnn".') +def main(image_to_check, cpus, model): + # Multi-core processing only supported on Python 3.4 or greater + if (sys.version_info < (3, 4)) and cpus != 1: + click.echo("WARNING: Multi-processing support requires Python 3.4 or greater. Falling back to single-threaded processing!") + cpus = 1 + + if os.path.isdir(image_to_check): + if cpus == 1: + [test_image(image_file, model) for image_file in image_files_in_folder(image_to_check)] + else: + process_images_in_process_pool(image_files_in_folder(image_to_check), cpus, model) + else: + test_image(image_to_check, model) + + +if __name__ == "__main__": + main() diff --git a/face_recognition-master/face_recognition/face_recognition_cli.py b/face_recognition-master/face_recognition/face_recognition_cli.py new file mode 100644 index 0000000000000000000000000000000000000000..218a0fb15a4608f75c2aeeb6cf36465dadd78a13 --- /dev/null +++ b/face_recognition-master/face_recognition/face_recognition_cli.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- +from __future__ import print_function +import click +import os +import re +import face_recognition.api as face_recognition +import multiprocessing +import itertools +import sys +import PIL.Image +import numpy as np + + +def scan_known_people(known_people_folder): + known_names = [] + known_face_encodings = [] + + for file in image_files_in_folder(known_people_folder): + basename = os.path.splitext(os.path.basename(file))[0] + img = face_recognition.load_image_file(file) + encodings = face_recognition.face_encodings(img) + + if len(encodings) > 1: + click.echo("WARNING: More than one face found in {}. Only considering the first face.".format(file)) + + if len(encodings) == 0: + click.echo("WARNING: No faces found in {}. Ignoring file.".format(file)) + else: + known_names.append(basename) + known_face_encodings.append(encodings[0]) + + return known_names, known_face_encodings + + +def print_result(filename, name, distance, show_distance=False): + if show_distance: + print("{},{},{}".format(filename, name, distance)) + else: + print("{},{}".format(filename, name)) + + +def test_image(image_to_check, known_names, known_face_encodings, tolerance=0.6, show_distance=False): + unknown_image = face_recognition.load_image_file(image_to_check) + + # Scale down image if it's giant so things run a little faster + if max(unknown_image.shape) > 1600: + pil_img = PIL.Image.fromarray(unknown_image) + pil_img.thumbnail((1600, 1600), PIL.Image.LANCZOS) + unknown_image = np.array(pil_img) + + unknown_encodings = face_recognition.face_encodings(unknown_image) + + for unknown_encoding in unknown_encodings: + distances = face_recognition.face_distance(known_face_encodings, unknown_encoding) + result = list(distances <= tolerance) + + if True in result: + [print_result(image_to_check, name, distance, show_distance) for is_match, name, distance in zip(result, known_names, distances) if is_match] + else: + print_result(image_to_check, "unknown_person", None, show_distance) + + if not unknown_encodings: + # print out fact that no faces were found in image + print_result(image_to_check, "no_persons_found", None, show_distance) + + +def image_files_in_folder(folder): + return [os.path.join(folder, f) for f in os.listdir(folder) if re.match(r'.*\.(jpg|jpeg|png)', f, flags=re.I)] + + +def process_images_in_process_pool(images_to_check, known_names, known_face_encodings, number_of_cpus, tolerance, show_distance): + if number_of_cpus == -1: + processes = None + else: + processes = number_of_cpus + + # macOS will crash due to a bug in libdispatch if you don't use 'forkserver' + context = multiprocessing + if "forkserver" in multiprocessing.get_all_start_methods(): + context = multiprocessing.get_context("forkserver") + + pool = context.Pool(processes=processes) + + function_parameters = zip( + images_to_check, + itertools.repeat(known_names), + itertools.repeat(known_face_encodings), + itertools.repeat(tolerance), + itertools.repeat(show_distance) + ) + + pool.starmap(test_image, function_parameters) + + +@click.command() +@click.argument('known_people_folder') +@click.argument('image_to_check') +@click.option('--cpus', default=1, help='number of CPU cores to use in parallel (can speed up processing lots of images). -1 means "use all in system"') +@click.option('--tolerance', default=0.6, help='Tolerance for face comparisons. Default is 0.6. Lower this if you get multiple matches for the same person.') +@click.option('--show-distance', default=False, type=bool, help='Output face distance. Useful for tweaking tolerance setting.') +def main(known_people_folder, image_to_check, cpus, tolerance, show_distance): + known_names, known_face_encodings = scan_known_people(known_people_folder) + + # Multi-core processing only supported on Python 3.4 or greater + if (sys.version_info < (3, 4)) and cpus != 1: + click.echo("WARNING: Multi-processing support requires Python 3.4 or greater. Falling back to single-threaded processing!") + cpus = 1 + + if os.path.isdir(image_to_check): + if cpus == 1: + [test_image(image_file, known_names, known_face_encodings, tolerance, show_distance) for image_file in image_files_in_folder(image_to_check)] + else: + process_images_in_process_pool(image_files_in_folder(image_to_check), known_names, known_face_encodings, cpus, tolerance, show_distance) + else: + test_image(image_to_check, known_names, known_face_encodings, tolerance, show_distance) + + +if __name__ == "__main__": + main() diff --git a/face_recognition-master/requirements.txt b/face_recognition-master/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..051fd3cc512c2a0f371ecf3f34eb355745066257 --- /dev/null +++ b/face_recognition-master/requirements.txt @@ -0,0 +1,6 @@ +face_recognition_models +Click>=6.0 +dlib>=19.3.0 +numpy +Pillow +scipy>=0.17.0 diff --git a/face_recognition-master/requirements_dev.txt b/face_recognition-master/requirements_dev.txt new file mode 100644 index 0000000000000000000000000000000000000000..aaa5793b4fe5e66934731ffd8fb79a228643c15a --- /dev/null +++ b/face_recognition-master/requirements_dev.txt @@ -0,0 +1,15 @@ +pip==8.1.2 +bumpversion==0.5.3 +wheel==0.29.0 +watchdog==0.8.3 +flake8==2.6.0 +tox==2.3.1 +coverage==4.1 +Sphinx==1.4.8 +cryptography==1.7 +PyYAML==3.11 +face_recognition_models +Click>=6.0 +dlib>=19.3.0 +numpy +scipy diff --git a/face_recognition-master/requirements_docs.txt b/face_recognition-master/requirements_docs.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/face_recognition-master/setup.cfg b/face_recognition-master/setup.cfg new file mode 100644 index 0000000000000000000000000000000000000000..9d5ddc947864ed3951af4c8527f413d3683ab260 --- /dev/null +++ b/face_recognition-master/setup.cfg @@ -0,0 +1,31 @@ +[bumpversion] +current_version = 1.2.1 +commit = True +tag = True + +[bumpversion:file:setup.py] +search = version='{current_version}' +replace = version='{new_version}' + +[bumpversion:file:face_recognition/__init__.py] +search = __version__ = '{current_version}' +replace = __version__ = '{new_version}' + +[bdist_wheel] +universal = 1 + +[flake8] +exclude = + .github, + .idea, + .eggs, + examples, + docs, + .tox, + bin, + dist, + tools, + *.egg-info, + __init__.py, + *.yml +max-line-length = 160 diff --git a/face_recognition-master/setup.py b/face_recognition-master/setup.py new file mode 100644 index 0000000000000000000000000000000000000000..93d4cdb0a67dc2465c8e617e3de5a000911a621d --- /dev/null +++ b/face_recognition-master/setup.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from setuptools import setup + +with open('README.rst') as readme_file: + readme = readme_file.read() + +with open('HISTORY.rst') as history_file: + history = history_file.read() + +requirements = [ + 'face_recognition_models>=0.3.0', + 'Click>=6.0', + 'dlib>=19.7', + 'numpy', + 'Pillow' +] + +test_requirements = [ + 'tox', + 'flake8==2.6.0' +] + +setup( + name='face_recognition', + version='1.2.3', + description="Recognize faces from Python or from the command line", + long_description=readme + '\n\n' + history, + author="Adam Geitgey", + author_email='ageitgey@gmail.com', + url='https://github.com/ageitgey/face_recognition', + packages=[ + 'face_recognition', + ], + package_dir={'face_recognition': 'face_recognition'}, + package_data={ + 'face_recognition': ['models/*.dat'] + }, + entry_points={ + 'console_scripts': [ + 'face_recognition=face_recognition.face_recognition_cli:main', + 'face_detection=face_recognition.face_detection_cli:main' + ] + }, + install_requires=requirements, + license="MIT license", + zip_safe=False, + keywords='face_recognition', + classifiers=[ + 'Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: MIT License', + 'Natural Language :: English', + "Programming Language :: Python :: 2", + 'Programming Language :: Python :: 2.6', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + ], + test_suite='tests', + tests_require=test_requirements +) diff --git a/face_recognition-master/tests/__init__.py b/face_recognition-master/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..40a96afc6ff09d58a702b76e3f7dd412fe975e26 --- /dev/null +++ b/face_recognition-master/tests/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/face_recognition-master/tests/test_face_recognition.py b/face_recognition-master/tests/test_face_recognition.py new file mode 100644 index 0000000000000000000000000000000000000000..c0e5500575b5ec332df37142ee1b03cad3fce895 --- /dev/null +++ b/face_recognition-master/tests/test_face_recognition.py @@ -0,0 +1,337 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +test_face_recognition +---------------------------------- + +Tests for `face_recognition` module. +""" + + +import unittest +import os +import numpy as np +from click.testing import CliRunner + +from face_recognition import api +from face_recognition import face_recognition_cli +from face_recognition import face_detection_cli + + +class Test_face_recognition(unittest.TestCase): + + def test_load_image_file(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg')) + self.assertEqual(img.shape, (1137, 910, 3)) + + def test_load_image_file_32bit(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', '32bit.png')) + self.assertEqual(img.shape, (1200, 626, 3)) + + def test_raw_face_locations(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg')) + detected_faces = api._raw_face_locations(img) + + self.assertEqual(len(detected_faces), 1) + self.assertEqual(detected_faces[0].top(), 142) + self.assertEqual(detected_faces[0].bottom(), 409) + + def test_cnn_raw_face_locations(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg')) + detected_faces = api._raw_face_locations(img, model="cnn") + + self.assertEqual(len(detected_faces), 1) + self.assertAlmostEqual(detected_faces[0].rect.top(), 144, delta=25) + self.assertAlmostEqual(detected_faces[0].rect.bottom(), 389, delta=25) + + def test_raw_face_locations_32bit_image(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', '32bit.png')) + detected_faces = api._raw_face_locations(img) + + self.assertEqual(len(detected_faces), 1) + self.assertEqual(detected_faces[0].top(), 290) + self.assertEqual(detected_faces[0].bottom(), 558) + + def test_cnn_raw_face_locations_32bit_image(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', '32bit.png')) + detected_faces = api._raw_face_locations(img, model="cnn") + + self.assertEqual(len(detected_faces), 1) + self.assertAlmostEqual(detected_faces[0].rect.top(), 259, delta=25) + self.assertAlmostEqual(detected_faces[0].rect.bottom(), 552, delta=25) + + def test_face_locations(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg')) + detected_faces = api.face_locations(img) + + self.assertEqual(len(detected_faces), 1) + self.assertEqual(detected_faces[0], (142, 617, 409, 349)) + + def test_cnn_face_locations(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg')) + detected_faces = api.face_locations(img, model="cnn") + + self.assertEqual(len(detected_faces), 1) + self.assertAlmostEqual(detected_faces[0][0], 144, delta=25) + self.assertAlmostEqual(detected_faces[0][1], 608, delta=25) + self.assertAlmostEqual(detected_faces[0][2], 389, delta=25) + self.assertAlmostEqual(detected_faces[0][3], 363, delta=25) + + def test_partial_face_locations(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama_partial_face.jpg')) + detected_faces = api.face_locations(img) + + self.assertEqual(len(detected_faces), 1) + self.assertEqual(detected_faces[0], (142, 191, 365, 0)) + + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama_partial_face2.jpg')) + detected_faces = api.face_locations(img) + + self.assertEqual(len(detected_faces), 1) + self.assertEqual(detected_faces[0], (142, 551, 409, 349)) + + def test_raw_face_locations_batched(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg')) + images = [img, img, img] + batched_detected_faces = api._raw_face_locations_batched(images, number_of_times_to_upsample=0) + + for detected_faces in batched_detected_faces: + self.assertEqual(len(detected_faces), 1) + self.assertEqual(detected_faces[0].rect.top(), 154) + self.assertEqual(detected_faces[0].rect.bottom(), 390) + + def test_batched_face_locations(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg')) + images = [img, img, img] + + batched_detected_faces = api.batch_face_locations(images, number_of_times_to_upsample=0) + + for detected_faces in batched_detected_faces: + self.assertEqual(len(detected_faces), 1) + self.assertEqual(detected_faces[0], (154, 611, 390, 375)) + + def test_raw_face_landmarks(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg')) + face_landmarks = api._raw_face_landmarks(img) + example_landmark = face_landmarks[0].parts()[10] + + self.assertEqual(len(face_landmarks), 1) + self.assertEqual(face_landmarks[0].num_parts, 68) + self.assertEqual((example_landmark.x, example_landmark.y), (552, 399)) + + def test_face_landmarks(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg')) + face_landmarks = api.face_landmarks(img) + + self.assertEqual( + set(face_landmarks[0].keys()), + set(['chin', 'left_eyebrow', 'right_eyebrow', 'nose_bridge', + 'nose_tip', 'left_eye', 'right_eye', 'top_lip', + 'bottom_lip'])) + self.assertEqual( + face_landmarks[0]['chin'], + [(369, 220), (372, 254), (378, 289), (384, 322), (395, 353), + (414, 382), (437, 407), (464, 424), (495, 428), (527, 420), + (552, 399), (576, 372), (594, 344), (604, 314), (610, 282), + (613, 250), (615, 219)]) + + def test_face_landmarks_small_model(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg')) + face_landmarks = api.face_landmarks(img, model="small") + + self.assertEqual( + set(face_landmarks[0].keys()), + set(['nose_tip', 'left_eye', 'right_eye'])) + self.assertEqual(face_landmarks[0]['nose_tip'], [(496, 295)]) + + def test_face_encodings(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg')) + encodings = api.face_encodings(img) + + self.assertEqual(len(encodings), 1) + self.assertEqual(len(encodings[0]), 128) + + def test_face_distance(self): + img_a1 = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg')) + img_a2 = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama2.jpg')) + img_a3 = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama3.jpg')) + + img_b1 = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'biden.jpg')) + + face_encoding_a1 = api.face_encodings(img_a1)[0] + face_encoding_a2 = api.face_encodings(img_a2)[0] + face_encoding_a3 = api.face_encodings(img_a3)[0] + face_encoding_b1 = api.face_encodings(img_b1)[0] + + faces_to_compare = [ + face_encoding_a2, + face_encoding_a3, + face_encoding_b1] + + distance_results = api.face_distance(faces_to_compare, face_encoding_a1) + + # 0.6 is the default face distance match threshold. So we'll spot-check that the numbers returned + # are above or below that based on if they should match (since the exact numbers could vary). + self.assertEqual(type(distance_results), np.ndarray) + self.assertLessEqual(distance_results[0], 0.6) + self.assertLessEqual(distance_results[1], 0.6) + self.assertGreater(distance_results[2], 0.6) + + def test_face_distance_empty_lists(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'biden.jpg')) + face_encoding = api.face_encodings(img)[0] + + # empty python list + faces_to_compare = [] + + distance_results = api.face_distance(faces_to_compare, face_encoding) + self.assertEqual(type(distance_results), np.ndarray) + self.assertEqual(len(distance_results), 0) + + # empty numpy list + faces_to_compare = np.array([]) + + distance_results = api.face_distance(faces_to_compare, face_encoding) + self.assertEqual(type(distance_results), np.ndarray) + self.assertEqual(len(distance_results), 0) + + def test_compare_faces(self): + img_a1 = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg')) + img_a2 = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama2.jpg')) + img_a3 = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'obama3.jpg')) + + img_b1 = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'biden.jpg')) + + face_encoding_a1 = api.face_encodings(img_a1)[0] + face_encoding_a2 = api.face_encodings(img_a2)[0] + face_encoding_a3 = api.face_encodings(img_a3)[0] + face_encoding_b1 = api.face_encodings(img_b1)[0] + + faces_to_compare = [ + face_encoding_a2, + face_encoding_a3, + face_encoding_b1] + + match_results = api.compare_faces(faces_to_compare, face_encoding_a1) + + self.assertEqual(type(match_results), list) + self.assertTrue(match_results[0]) + self.assertTrue(match_results[1]) + self.assertFalse(match_results[2]) + + def test_compare_faces_empty_lists(self): + img = api.load_image_file(os.path.join(os.path.dirname(__file__), 'test_images', 'biden.jpg')) + face_encoding = api.face_encodings(img)[0] + + # empty python list + faces_to_compare = [] + + match_results = api.compare_faces(faces_to_compare, face_encoding) + self.assertEqual(type(match_results), list) + self.assertListEqual(match_results, []) + + # empty numpy list + faces_to_compare = np.array([]) + + match_results = api.compare_faces(faces_to_compare, face_encoding) + self.assertEqual(type(match_results), list) + self.assertListEqual(match_results, []) + + def test_command_line_interface_options(self): + target_string = 'Show this message and exit.' + runner = CliRunner() + help_result = runner.invoke(face_recognition_cli.main, ['--help']) + self.assertEqual(help_result.exit_code, 0) + self.assertTrue(target_string in help_result.output) + + def test_command_line_interface(self): + target_string = 'obama.jpg,obama' + runner = CliRunner() + image_folder = os.path.join(os.path.dirname(__file__), 'test_images') + image_file = os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg') + + result = runner.invoke(face_recognition_cli.main, args=[image_folder, image_file]) + + self.assertEqual(result.exit_code, 0) + self.assertTrue(target_string in result.output) + + def test_command_line_interface_big_image(self): + target_string = 'obama3.jpg,obama' + runner = CliRunner() + image_folder = os.path.join(os.path.dirname(__file__), 'test_images') + image_file = os.path.join(os.path.dirname(__file__), 'test_images', 'obama3.jpg') + + result = runner.invoke(face_recognition_cli.main, args=[image_folder, image_file]) + + self.assertEqual(result.exit_code, 0) + self.assertTrue(target_string in result.output) + + def test_command_line_interface_tolerance(self): + target_string = 'obama.jpg,obama' + runner = CliRunner() + image_folder = os.path.join(os.path.dirname(__file__), 'test_images') + image_file = os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg') + + result = runner.invoke(face_recognition_cli.main, args=[image_folder, image_file, "--tolerance", "0.55"]) + + self.assertEqual(result.exit_code, 0) + self.assertTrue(target_string in result.output) + + def test_command_line_interface_show_distance(self): + target_string = 'obama.jpg,obama,0.0' + runner = CliRunner() + image_folder = os.path.join(os.path.dirname(__file__), 'test_images') + image_file = os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg') + + result = runner.invoke(face_recognition_cli.main, args=[image_folder, image_file, "--show-distance", "1"]) + + self.assertEqual(result.exit_code, 0) + self.assertTrue(target_string in result.output) + + def test_fd_command_line_interface_options(self): + target_string = 'Show this message and exit.' + runner = CliRunner() + help_result = runner.invoke(face_detection_cli.main, ['--help']) + self.assertEqual(help_result.exit_code, 0) + self.assertTrue(target_string in help_result.output) + + def test_fd_command_line_interface(self): + runner = CliRunner() + image_file = os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg') + + result = runner.invoke(face_detection_cli.main, args=[image_file]) + self.assertEqual(result.exit_code, 0) + parts = result.output.split(",") + self.assertTrue("obama.jpg" in parts[0]) + self.assertEqual(len(parts), 5) + + def test_fd_command_line_interface_folder(self): + runner = CliRunner() + image_file = os.path.join(os.path.dirname(__file__), 'test_images') + + result = runner.invoke(face_detection_cli.main, args=[image_file]) + self.assertEqual(result.exit_code, 0) + self.assertTrue("obama_partial_face2.jpg" in result.output) + self.assertTrue("obama.jpg" in result.output) + self.assertTrue("obama2.jpg" in result.output) + self.assertTrue("obama3.jpg" in result.output) + self.assertTrue("biden.jpg" in result.output) + + def test_fd_command_line_interface_hog_model(self): + target_string = 'obama.jpg' + runner = CliRunner() + image_file = os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg') + + result = runner.invoke(face_detection_cli.main, args=[image_file, "--model", "hog"]) + self.assertEqual(result.exit_code, 0) + self.assertTrue(target_string in result.output) + + def test_fd_command_line_interface_cnn_model(self): + target_string = 'obama.jpg' + runner = CliRunner() + image_file = os.path.join(os.path.dirname(__file__), 'test_images', 'obama.jpg') + + result = runner.invoke(face_detection_cli.main, args=[image_file, "--model", "cnn"]) + self.assertEqual(result.exit_code, 0) + self.assertTrue(target_string in result.output) diff --git a/face_recognition-master/tests/test_images/32bit.png b/face_recognition-master/tests/test_images/32bit.png new file mode 100644 index 0000000000000000000000000000000000000000..30e66eb673dec8a9495892aa9fb9a74d85bfaa39 Binary files /dev/null and b/face_recognition-master/tests/test_images/32bit.png differ diff --git a/face_recognition-master/tests/test_images/biden.jpg b/face_recognition-master/tests/test_images/biden.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3a0bdc974e9067b1595a6a623a3d898265b0a7a2 Binary files /dev/null and b/face_recognition-master/tests/test_images/biden.jpg differ diff --git a/face_recognition-master/tests/test_images/obama.jpg b/face_recognition-master/tests/test_images/obama.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1ce4b846f50bea6c0e8348a351413bfdd6ea1f86 Binary files /dev/null and b/face_recognition-master/tests/test_images/obama.jpg differ diff --git a/face_recognition-master/tests/test_images/obama2.jpg b/face_recognition-master/tests/test_images/obama2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b9b60c4680686f27cee2e2b242e115dde62b6443 Binary files /dev/null and b/face_recognition-master/tests/test_images/obama2.jpg differ diff --git a/face_recognition-master/tests/test_images/obama3.jpg b/face_recognition-master/tests/test_images/obama3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d34fd2a57fceb2d6e1a5ae658a1857042bc482b6 Binary files /dev/null and b/face_recognition-master/tests/test_images/obama3.jpg differ diff --git a/face_recognition-master/tests/test_images/obama_partial_face.jpg b/face_recognition-master/tests/test_images/obama_partial_face.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8e0db4cfe1c271ea26c1b6ab14464a121095963e Binary files /dev/null and b/face_recognition-master/tests/test_images/obama_partial_face.jpg differ diff --git a/face_recognition-master/tests/test_images/obama_partial_face2.jpg b/face_recognition-master/tests/test_images/obama_partial_face2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..608c9dc34934eca9da8670df8babc08bd3d71995 Binary files /dev/null and b/face_recognition-master/tests/test_images/obama_partial_face2.jpg differ diff --git a/face_recognition-master/tox.ini b/face_recognition-master/tox.ini new file mode 100644 index 0000000000000000000000000000000000000000..03799ea76eaa0242ade806fa593ddb9d1a135953 --- /dev/null +++ b/face_recognition-master/tox.ini @@ -0,0 +1,28 @@ +[tox] +envlist = + py27 + py34 + py35 + py36 + flake8 + + +[travis] +python = + 2.7: py27, flake8 + 3.4: py34, flake8 + 3.5: py35, flake8 + 3.6: py36, flake8 + + +[testenv] +commands = + python setup.py test + + +[testenv:flake8] +deps = + flake8==2.6.0 + +commands = + flake8 diff --git "a/uml\346\236\204\344\273\266\345\233\276.jpg" "b/uml\346\236\204\344\273\266\345\233\276.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..f43bdfb41f42e493878c4aae845b0d00ed6a870b Binary files /dev/null and "b/uml\346\236\204\344\273\266\345\233\276.jpg" differ diff --git "a/uml\347\212\266\346\200\201\345\233\276.png.jpg" "b/uml\347\212\266\346\200\201\345\233\276.png.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..64ca18cd688bee593262f27fd290cf8d7c573967 Binary files /dev/null and "b/uml\347\212\266\346\200\201\345\233\276.png.jpg" differ diff --git "a/uml\347\273\204\344\273\266\345\233\276.png" "b/uml\347\273\204\344\273\266\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..e621609d79e1f085af183b0fbf2676154c150b2b Binary files /dev/null and "b/uml\347\273\204\344\273\266\345\233\276.png" differ diff --git "a/uml\351\203\250\347\275\262\345\233\276.jpg" "b/uml\351\203\250\347\275\262\345\233\276.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..b80198450d0491d5a52cf736a53e3afcbada9672 Binary files /dev/null and "b/uml\351\203\250\347\275\262\345\233\276.jpg" differ diff --git "a/uml\351\241\272\345\272\217\345\233\276-\347\216\213\346\224\277\351\234\226.png" "b/uml\351\241\272\345\272\217\345\233\276-\347\216\213\346\224\277\351\234\226.png" new file mode 100644 index 0000000000000000000000000000000000000000..729c7c6aea4d42d6429147f59e032d59e3378bc2 Binary files /dev/null and "b/uml\351\241\272\345\272\217\345\233\276-\347\216\213\346\224\277\351\234\226.png" differ diff --git "a/\344\271\224\345\262\251\345\262\251 201601450138 16\347\247\221\344\270\200.docx" "b/\344\271\224\345\262\251\345\262\251 201601450138 16\347\247\221\344\270\200.docx" new file mode 100644 index 0000000000000000000000000000000000000000..6aca2db799816d6ecfa567f673fb474307c3232e Binary files /dev/null and "b/\344\271\224\345\262\251\345\262\251 201601450138 16\347\247\221\344\270\200.docx" differ diff --git "a/\345\215\217\344\275\234\345\233\276.png" "b/\345\215\217\344\275\234\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..e9430c6410575a3da167d3e83d8e68625c64de04 Binary files /dev/null and "b/\345\215\217\344\275\234\345\233\276.png" differ diff --git "a/\345\274\240\346\226\207\344\270\271 201601450137 \350\256\241\347\247\221\344\270\200\347\217\255 \344\272\272\350\204\270\350\257\206\345\210\253 \347\273\204\344\273\266\345\233\276.mdl" "b/\345\274\240\346\226\207\344\270\271 201601450137 \350\256\241\347\247\221\344\270\200\347\217\255 \344\272\272\350\204\270\350\257\206\345\210\253 \347\273\204\344\273\266\345\233\276.mdl" new file mode 100644 index 0000000000000000000000000000000000000000..0805060d721936d7e4fbfc84e6464dc72d575d3d --- /dev/null +++ "b/\345\274\240\346\226\207\344\270\271 201601450137 \350\256\241\347\247\221\344\270\200\347\217\255 \344\272\272\350\204\270\350\257\206\345\210\253 \347\273\204\344\273\266\345\233\276.mdl" @@ -0,0 +1,2793 @@ + +(object Petal + version 50 + _written "Rose 2006.0.0.060314" + charSet 134) + +(object Design "Logical View" + is_unit TRUE + is_loaded TRUE + attributes (list Attribute_Set + (object Attribute + tool "Java" + name "IDE" + value "Internal Editor")) + quid "5C2F070B0354" + enforceClosureAutoLoad FALSE + defaults (object defaults + rightMargin 0.250000 + leftMargin 0.250000 + topMargin 0.250000 + bottomMargin 0.500000 + pageOverlap 0.250000 + clipIconLabels TRUE + autoResize TRUE + snapToGrid TRUE + gridX 0 + gridY 0 + defaultFont (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + showMessageNum 3 + showClassOfObject TRUE + notation "Unified") + root_usecase_package (object Class_Category "Use Case View" + quid "5C2F070B0356" + exportControl "Public" + global TRUE + logical_models (list unit_reference_list) + logical_presentations (list unit_reference_list + (object UseCaseDiagram "Main" + quid "5C2F070E02E7" + title "Main" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 0 + origin_y 0 + items (list diagram_item_list)))) + root_category (object Class_Category "Logical View" + quid "5C2F070B0355" + exportControl "Public" + global TRUE + subsystem "Component View" + quidu "5C2F070B0357" + logical_models (list unit_reference_list) + logical_presentations (list unit_reference_list + (object ClassDiagram "Main" + quid "5C2F070E02EF" + title "Main" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 0 + origin_y 0 + items (list diagram_item_list)))) + root_subsystem (object SubSystem "Component View" + quid "5C2F070B0357" + physical_models (list unit_reference_list + (object module "test" "NotAModuleType" "NotAModulePart" + quid "5C2F092D0028" + stereotype "" + visible_modules (list dependency_list + (object Module_Visibility_Relationship + quid "5C2F0A8400B7" + supplier "Component View::_init_." + quidu "5C2F0A7601F1" + supplier_is_spec TRUE) + (object Module_Visibility_Relationship + quid "5C2F0A8602DF" + supplier "Component View::api" + quidu "5C2F092F0349" + supplier_is_spec TRUE)) + language "") + (object module "api" "NotAModuleType" "NotAModulePart" + quid "5C2F092F0349" + stereotype "" + visible_modules (list dependency_list + (object Module_Visibility_Relationship + quid "5C2F0AB201E6" + supplier "Component View::image" + quidu "5C2F0931034F" + supplier_is_spec TRUE) + (object Module_Visibility_Relationship + quid "5C2F0E770388" + supplier "Component View::numerictypes" + quidu "5C2F0C790024" + supplier_is_spec TRUE)) + language "") + (object module "image" "NotAModuleType" "NotAModulePart" + quid "5C2F0931034F" + stereotype "" + visible_modules (list dependency_list + (object Module_Visibility_Relationship + quid "5C2F0BCB0094" + supplier "Component View::io" + quidu "5C2F0BC40023" + supplier_is_spec TRUE) + (object Module_Visibility_Relationship + quid "5C2F0C1B0263" + supplier "Component View::warnings" + quidu "5C2F0C1801E3" + supplier_is_spec TRUE) + (object Module_Visibility_Relationship + quid "5C2F0C910303" + supplier "Component View::numerictypes" + quidu "5C2F0C790024" + supplier_is_spec TRUE) + (object Module_Visibility_Relationship + quid "5C2F0DD70163" + supplier "Component View::_init_." + quidu "5C2F0A7601F1" + supplier_is_spec TRUE) + (object Module_Visibility_Relationship + quid "5C2F0DF90278" + supplier "Component View::_init_PLL" + quidu "5C2F0DEA02E9" + supplier_is_spec TRUE)) + language "") + (object module "_init_." "NotAModuleType" "NotAModulePart" + quid "5C2F0A7601F1" + stereotype "" + language "") + (object module "io" "NotAModuleType" "NotAModulePart" + quid "5C2F0BC40023" + stereotype "" + language "") + (object module "warnings" "NotAModuleType" "NotAModulePart" + quid "5C2F0C1801E3" + stereotype "" + language "") + (object module "numerictypes" "NotAModuleType" "NotAModulePart" + quid "5C2F0C790024" + stereotype "" + language "") + (object module "_init_PLL" "NotAModuleType" "NotAModulePart" + quid "5C2F0DEA02E9" + stereotype "" + language "")) + physical_presentations (list unit_reference_list + (object Module_Diagram "Main" + quid "5C2F070E02E6" + title "Main" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 437 + origin_y 0 + items (list diagram_item_list + (object ModView "Component View::test" "NotAModuleType" "NotAModulePart" @1 + location (450, 556) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @1 + location (406, 531) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 162 + justify 1 + label "test") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2F092D0028" + width 292 + autoResize TRUE + width 292 + height 162) + (object ModView "Component View::api" "NotAModuleType" "NotAModulePart" @2 + location (1014, 556) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @2 + location (968, 531) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 171 + justify 1 + label "api") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2F092F0349" + width 308 + autoResize TRUE + width 308 + height 162) + (object ModView "Component View::image" "NotAModuleType" "NotAModulePart" @3 + location (1640, 556) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @3 + location (1593, 531) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 174 + justify 1 + label "image") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2F0931034F" + width 314 + autoResize TRUE + width 314 + height 162) + (object ModView "Component View::_init_." "NotAModuleType" "NotAModulePart" @4 + location (475, 1100) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @4 + location (430, 1075) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 166 + justify 1 + label "_init_.") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2F0A7601F1" + width 298 + autoResize TRUE + width 298 + height 162) + (object ModVisView "" @5 + stereotype TRUE + line_color 3342489 + quidu "5C2F0A8400B7" + client @1 + supplier @4 + vertices (list Points + (451, 634) + (468, 1020)) + line_style 0) + (object ModVisView "" @6 + stereotype TRUE + line_color 3342489 + quidu "5C2F0A8602DF" + client @1 + supplier @2 + vertices (list Points + (591, 556) + (861, 556)) + line_style 0) + (object ModVisView "" @7 + stereotype TRUE + line_color 3342489 + quidu "5C2F0AB201E6" + client @2 + supplier @3 + vertices (list Points + (1163, 556) + (1486, 556)) + line_style 0) + (object ModView "Component View::io" "NotAModuleType" "NotAModulePart" @8 + location (2380, 556) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @8 + location (2335, 531) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 166 + justify 1 + label "io") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2F0BC40023" + width 298 + autoResize TRUE + width 298 + height 162) + (object ModVisView "" @9 + stereotype TRUE + line_color 3342489 + quidu "5C2F0BCB0094" + client @3 + supplier @8 + vertices (list Points + (1792, 556) + (2231, 556)) + line_style 0) + (object ModView "Component View::warnings" "NotAModuleType" "NotAModulePart" @10 + location (2184, 1053) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @10 + location (2139, 1028) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 166 + justify 1 + label "warnings") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2F0C1801E3" + width 298 + autoResize TRUE + width 298 + height 162) + (object ModVisView "" @11 + stereotype TRUE + line_color 3342489 + quidu "5C2F0C1B0263" + client @3 + supplier @10 + vertices (list Points + (1724, 634) + (2093, 971)) + line_style 0) + (object ModView "Component View::numerictypes" "NotAModuleType" "NotAModulePart" @12 + location (1281, 1087) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @12 + location (1236, 1062) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 166 + justify 1 + label "numerictypes") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2F0C790024" + width 298 + autoResize TRUE + width 298 + height 162) + (object ModVisView "" @13 + stereotype TRUE + line_color 3342489 + quidu "5C2F0C910303" + client @3 + supplier @12 + vertices (list Points + (1581, 634) + (1330, 1007)) + line_style 0) + (object ModView "Component View::_init_PLL" "NotAModuleType" "NotAModulePart" @14 + location (1581, 156) + font (object Font + size 10 + face "Arial" + bold FALSE + italics FALSE + underline FALSE + strike FALSE + color 0 + default_color TRUE) + label (object ItemLabel + Parent_View @14 + location (1536, 131) + fill_color 13434879 + anchor_loc 3 + nlines 2 + max_width 166 + justify 1 + label "_init_PLL") + icon_style "Icon" + line_color 3342489 + fill_color 13434879 + quidu "5C2F0DEA02E9" + width 298 + autoResize TRUE + width 298 + height 162) + (object ModVisView "" @15 + stereotype TRUE + line_color 3342489 + quidu "5C2F0DF90278" + client @3 + supplier @14 + vertices (list Points + (1624, 476) + (1589, 234)) + line_style 0) + (object ModVisView "" @16 + stereotype TRUE + line_color 3342489 + quidu "5C2F0E770388" + client @2 + supplier @12 + vertices (list Points + (1052, 634) + (1238, 1007)) + line_style 0)))) + category "Logical View" + quidu "5C2F070B0355") + process_structure (object Processes + quid "5C2F070B0358" + ProcsNDevs (list + (object Process_Diagram "Deployment View" + quid "5C2F070B035A" + title "Deployment View" + zoom 100 + max_height 28350 + max_width 21600 + origin_x 0 + origin_y 0 + items (list diagram_item_list)))) + properties (object Properties + attributes (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "propertyId" + value "809135966") + (object Attribute + tool "Cplusplus" + name "default__Role" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Synchronize" + value TRUE) + (object Attribute + tool "Cplusplus" + name "CodeName" + value "") + (object Attribute + tool "Cplusplus" + name "InitialValue" + value ""))) + (object Attribute + tool "Cplusplus" + name "default__Inherit" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Synchronize" + value TRUE))) + (object Attribute + tool "Cplusplus" + name "default__Module-Spec" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Synchronize" + value TRUE) + (object Attribute + tool "Cplusplus" + name "RevEngRootDirectory" + value "") + (object Attribute + tool "Cplusplus" + name "RootPackage" + value "C++ Reverse Engineered") + (object Attribute + tool "Cplusplus" + name "RevEngDirectoriesAsPackages" + value FALSE) + (object Attribute + tool "Cplusplus" + name "HeaderFileExtension" + value ".h") + (object Attribute + tool "Cplusplus" + name "ImplementationFileExtension" + value ".cpp") + (object Attribute + tool "Cplusplus" + name "NewHeaderFileDirectory" + value "") + (object Attribute + tool "Cplusplus" + name "NewImplementationFileDirectory" + value "") + (object Attribute + tool "Cplusplus" + name "FileCapitalization" + value ("FileCapitalizationSet" 0)) + (object Attribute + tool "Cplusplus" + name "CodeGenExtraDirectories" + value ("CodeGenExtraDirectoriesSet" 0)) + (object Attribute + tool "Cplusplus" + name "StripClassPrefix" + value "") + (object Attribute + tool "Cplusplus" + name "UseTabs" + value FALSE) + (object Attribute + tool "Cplusplus" + name "TabWidth" + value 8) + (object Attribute + tool "Cplusplus" + name "IndentWidth" + value 4) + (object Attribute + tool "Cplusplus" + name "AccessIndentation" + value -2) + (object Attribute + tool "Cplusplus" + name "CreateBackupFiles" + value FALSE) + (object Attribute + tool "Cplusplus" + name "ModelIdCommentRules" + value ("ModelIdCommentRulesSet" 1)) + (object Attribute + tool "Cplusplus" + name "CommentRules" + value ("CommentRulesSet" 1)) + (object Attribute + tool "Cplusplus" + name "PageWidth" + value 80) + (object Attribute + tool "Cplusplus" + name "ClassMemberOrder" + value ("MemberOrderSet" 1)) + (object Attribute + tool "Cplusplus" + name "OneParameterPerLine" + value FALSE) + (object Attribute + tool "Cplusplus" + name "NamespaceBraceStyle" + value ("BraceStyleSet" 1)) + (object Attribute + tool "Cplusplus" + name "ClassBraceStyle" + value ("BraceStyleSet" 2)) + (object Attribute + tool "Cplusplus" + name "FunctionBraceStyle" + value ("BraceStyleSet" 2)) + (object Attribute + tool "Cplusplus" + name "CommentStyleProperty" + value ("CommentStyleSet" 1)) + (object Attribute + tool "Cplusplus" + name "Copyright" + value (value Text "")) + (object Attribute + tool "Cplusplus" + name "InitialHeaderIncludes" + value (value Text "")) + (object Attribute + tool "Cplusplus" + name "InitialBodyIncludes" + value (value Text "")) + (object Attribute + tool "Cplusplus" + name "CodeGenExtraDirectoriesSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "None" + value 0) + (object Attribute + tool "Cplusplus" + name "Namespaces" + value 1) + (object Attribute + tool "Cplusplus" + name "Packages" + value 2))) + (object Attribute + tool "Cplusplus" + name "FileCapitalizationSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Same as model" + value 0) + (object Attribute + tool "Cplusplus" + name "Lower case" + value 1) + (object Attribute + tool "Cplusplus" + name "Upper case" + value 2) + (object Attribute + tool "Cplusplus" + name "Lower case with underscores" + value 3))) + (object Attribute + tool "Cplusplus" + name "CommentStyleSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "C++ Comment" + value 1) + (object Attribute + tool "Cplusplus" + name "C Comment" + value 2) + (object Attribute + tool "Cplusplus" + name "XML Comment" + value 3) + (object Attribute + tool "Cplusplus" + name "JavaDoc Comment" + value 4))) + (object Attribute + tool "Cplusplus" + name "BraceStyleSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "B1" + value 1) + (object Attribute + tool "Cplusplus" + name "B2" + value 2) + (object Attribute + tool "Cplusplus" + name "B3" + value 3) + (object Attribute + tool "Cplusplus" + name "B4" + value 4) + (object Attribute + tool "Cplusplus" + name "B5" + value 5))) + (object Attribute + tool "Cplusplus" + name "MemberOrderSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Public First" + value 1) + (object Attribute + tool "Cplusplus" + name "Private First" + value 2) + (object Attribute + tool "Cplusplus" + name "Order by kind" + value 3) + (object Attribute + tool "Cplusplus" + name "Unordered" + value 4))) + (object Attribute + tool "Cplusplus" + name "ModelIdCommentRulesSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Code generation only" + value 1) + (object Attribute + tool "Cplusplus" + name "Code generation and reverse engineering" + value 2) + (object Attribute + tool "Cplusplus" + name "Never generate model IDs" + value 3))) + (object Attribute + tool "Cplusplus" + name "CommentRulesSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Always synchronize" + value 1) + (object Attribute + tool "Cplusplus" + name "Code generation only" + value 2) + (object Attribute + tool "Cplusplus" + name "Reverse engineering only" + value 3) + (object Attribute + tool "Cplusplus" + name "Never synchronize" + value 4))))) + (object Attribute + tool "Cplusplus" + name "default__Module-Body" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Synchronize" + value TRUE) + (object Attribute + tool "Cplusplus" + name "RevEngRootDirectory" + value "") + (object Attribute + tool "Cplusplus" + name "RootPackage" + value "C++ Reverse Engineered") + (object Attribute + tool "Cplusplus" + name "RevEngDirectoriesAsPackages" + value FALSE) + (object Attribute + tool "Cplusplus" + name "HeaderFileExtension" + value ".h") + (object Attribute + tool "Cplusplus" + name "ImplementationFileExtension" + value ".cpp") + (object Attribute + tool "Cplusplus" + name "NewHeaderFileDirectory" + value "") + (object Attribute + tool "Cplusplus" + name "NewImplementationFileDirectory" + value "") + (object Attribute + tool "Cplusplus" + name "FileCapitalization" + value ("FileCapitalizationSet" 0)) + (object Attribute + tool "Cplusplus" + name "CodeGenExtraDirectories" + value ("CodeGenExtraDirectoriesSet" 0)) + (object Attribute + tool "Cplusplus" + name "StripClassPrefix" + value "") + (object Attribute + tool "Cplusplus" + name "UseTabs" + value FALSE) + (object Attribute + tool "Cplusplus" + name "TabWidth" + value 8) + (object Attribute + tool "Cplusplus" + name "IndentWidth" + value 4) + (object Attribute + tool "Cplusplus" + name "AccessIndentation" + value -2) + (object Attribute + tool "Cplusplus" + name "CreateBackupFiles" + value FALSE) + (object Attribute + tool "Cplusplus" + name "ModelIdCommentRules" + value ("ModelIdCommentRulesSet" 1)) + (object Attribute + tool "Cplusplus" + name "CommentRules" + value ("CommentRulesSet" 1)) + (object Attribute + tool "Cplusplus" + name "PageWidth" + value 80) + (object Attribute + tool "Cplusplus" + name "ClassMemberOrder" + value ("MemberOrderSet" 1)) + (object Attribute + tool "Cplusplus" + name "OneParameterPerLine" + value FALSE) + (object Attribute + tool "Cplusplus" + name "NamespaceBraceStyle" + value ("BraceStyleSet" 2)) + (object Attribute + tool "Cplusplus" + name "ClassBraceStyle" + value ("BraceStyleSet" 2)) + (object Attribute + tool "Cplusplus" + name "FunctionBraceStyle" + value ("BraceStyleSet" 2)) + (object Attribute + tool "Cplusplus" + name "CommentStyleProperty" + value ("CommentStyleSet" 1)) + (object Attribute + tool "Cplusplus" + name "Copyright" + value (value Text "")) + (object Attribute + tool "Cplusplus" + name "InitialHeaderIncludes" + value (value Text "")) + (object Attribute + tool "Cplusplus" + name "InitialBodyIncludes" + value (value Text "")) + (object Attribute + tool "Cplusplus" + name "CodeGenExtraDirectoriesSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "None" + value 0) + (object Attribute + tool "Cplusplus" + name "Namespaces" + value 1) + (object Attribute + tool "Cplusplus" + name "Packages" + value 2))) + (object Attribute + tool "Cplusplus" + name "FileCapitalizationSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Same as model" + value 0) + (object Attribute + tool "Cplusplus" + name "Lower case" + value 1) + (object Attribute + tool "Cplusplus" + name "Upper case" + value 2) + (object Attribute + tool "Cplusplus" + name "Lower case with underscores" + value 3))) + (object Attribute + tool "Cplusplus" + name "CommentStyleSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "C++ Comment" + value 1) + (object Attribute + tool "Cplusplus" + name "C Comment" + value 2) + (object Attribute + tool "Cplusplus" + name "XML Comment" + value 3) + (object Attribute + tool "Cplusplus" + name "JavaDoc Comment" + value 4))) + (object Attribute + tool "Cplusplus" + name "BraceStyleSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "B1" + value 1) + (object Attribute + tool "Cplusplus" + name "B2" + value 2) + (object Attribute + tool "Cplusplus" + name "B3" + value 3) + (object Attribute + tool "Cplusplus" + name "B4" + value 4) + (object Attribute + tool "Cplusplus" + name "B5" + value 5))) + (object Attribute + tool "Cplusplus" + name "MemberOrderSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Public First" + value 1) + (object Attribute + tool "Cplusplus" + name "Private First" + value 2) + (object Attribute + tool "Cplusplus" + name "Order by kind" + value 3) + (object Attribute + tool "Cplusplus" + name "Unordered" + value 4))) + (object Attribute + tool "Cplusplus" + name "ModelIdCommentRulesSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Code generation only" + value 1) + (object Attribute + tool "Cplusplus" + name "Code generation and reverse engineering" + value 2) + (object Attribute + tool "Cplusplus" + name "Never generate model IDs" + value 3))) + (object Attribute + tool "Cplusplus" + name "CommentRulesSet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Always synchronize" + value 1) + (object Attribute + tool "Cplusplus" + name "Code generation only" + value 2) + (object Attribute + tool "Cplusplus" + name "Reverse engineering only" + value 3) + (object Attribute + tool "Cplusplus" + name "Never synchronize" + value 4))))) + (object Attribute + tool "Cplusplus" + name "default__Param" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "CodeName" + value ""))) + (object Attribute + tool "Cplusplus" + name "default__Attribute" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Synchronize" + value TRUE) + (object Attribute + tool "Cplusplus" + name "CodeName" + value ""))) + (object Attribute + tool "Cplusplus" + name "default__Operation" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Synchronize" + value TRUE) + (object Attribute + tool "Cplusplus" + name "CodeName" + value "") + (object Attribute + tool "Cplusplus" + name "InitialCodeBody" + value "") + (object Attribute + tool "Cplusplus" + name "Inline" + value FALSE) + (object Attribute + tool "Cplusplus" + name "GenerateFunctionBody" + value ("GenerateFunctionBodySet" 2)) + (object Attribute + tool "Cplusplus" + name "GenerateFunctionBodySet" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Default" + value 2) + (object Attribute + tool "Cplusplus" + name "True" + value 1) + (object Attribute + tool "Cplusplus" + name "False" + value 0))))) + (object Attribute + tool "Cplusplus" + name "default__Class" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "Synchronize" + value TRUE) + (object Attribute + tool "Cplusplus" + name "CodeName" + value "") + (object Attribute + tool "Cplusplus" + name "ImplementationType" + value "") + (object Attribute + tool "Cplusplus" + name "HeaderSourceFile" + value "") + (object Attribute + tool "Cplusplus" + name "BodySourceFile" + value ""))) + (object Attribute + tool "Cplusplus" + name "default__Category" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "CodeName" + value "") + (object Attribute + tool "Cplusplus" + name "IsNamespace" + value FALSE))) + (object Attribute + tool "Cplusplus" + name "default__Uses" + value (list Attribute_Set + (object Attribute + tool "Cplusplus" + name "BodyReferenceOnly" + value FALSE))) + (object Attribute + tool "Cplusplus" + name "HiddenTool" + value FALSE) + (object Attribute + tool "ANSIConvert" + name "HiddenTool" + value FALSE) + (object Attribute + tool "CORBA" + name "propertyId" + value "809135966") + (object Attribute + tool "CORBA" + name "default__Project" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "CreateMissingDirectories" + value TRUE) + (object Attribute + tool "CORBA" + name "Editor" + value ("EditorType" 100)) + (object Attribute + tool "CORBA" + name "IncludePath" + value "") + (object Attribute + tool "CORBA" + name "StopOnError" + value TRUE) + (object Attribute + tool "CORBA" + name "EditorType" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "BuiltIn" + value 100) + (object Attribute + tool "CORBA" + name "WindowsShell" + value 101))) + (object Attribute + tool "CORBA" + name "PathSeparator" + value "") + (object Attribute + tool "CORBA" + name "GenerateRoseID" + value TRUE) + (object Attribute + tool "CORBA" + name "NotShowRoseIDDlg" + value FALSE) + (object Attribute + tool "CORBA" + name "GenerateComments" + value TRUE) + (object Attribute + tool "CORBA" + name "UseTabs" + value FALSE) + (object Attribute + tool "CORBA" + name "UseSpaces" + value TRUE) + (object Attribute + tool "CORBA" + name "SpacingItems" + value 4) + (object Attribute + tool "CORBA" + name "BraceOnNewLine" + value FALSE) + (object Attribute + tool "CORBA" + name "FundamentalTypes" + value "short; long; long long; unsigned short; unsigned long; unsigned long long; float; double; long double; char; boolean; wchar; octet; any;string; wstring; sequence; fixed; Object"))) + (object Attribute + tool "CORBA" + name "default__Class" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "ArrayDimensions" + value "") + (object Attribute + tool "CORBA" + name "ConstValue" + value "") + (object Attribute + tool "CORBA" + name "ImplementationType" + value "") + (object Attribute + tool "CORBA" + name "IsLocal" + value FALSE))) + (object Attribute + tool "CORBA" + name "default__Module-Spec" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "AdditionalIncludes" + value (value Text "")) + (object Attribute + tool "CORBA" + name "CmIdentification" + value (value Text " %X% %Q% %Z% %W%")) + (object Attribute + tool "CORBA" + name "CopyrightNotice" + value (value Text "")) + (object Attribute + tool "CORBA" + name "InclusionProtectionSymbol" + value "AUTO GENERATE"))) + (object Attribute + tool "CORBA" + name "default__Module-Body" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "AdditionalIncludes" + value (value Text "")) + (object Attribute + tool "CORBA" + name "CmIdentification" + value (value Text " %X% %Q% %Z% %W%")) + (object Attribute + tool "CORBA" + name "CopyrightNotice" + value (value Text "")) + (object Attribute + tool "CORBA" + name "InclusionProtectionSymbol" + value "AUTO GENERATE"))) + (object Attribute + tool "CORBA" + name "default__Operation" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "Context" + value "") + (object Attribute + tool "CORBA" + name "OperationIsOneWay" + value FALSE))) + (object Attribute + tool "CORBA" + name "default__Attribute" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "ArrayDimensions" + value "") + (object Attribute + tool "CORBA" + name "CaseSpecifier" + value "") + (object Attribute + tool "CORBA" + name "IsReadOnly" + value FALSE) + (object Attribute + tool "CORBA" + name "Order" + value ""))) + (object Attribute + tool "CORBA" + name "default__Role" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "ArrayDimensions" + value "") + (object Attribute + tool "CORBA" + name "CaseSpecifier" + value "") + (object Attribute + tool "CORBA" + name "GenerateForwardReference" + value FALSE) + (object Attribute + tool "CORBA" + name "IsReadOnly" + value FALSE) + (object Attribute + tool "CORBA" + name "Order" + value "") + (object Attribute + tool "CORBA" + name "BoundedRoleType" + value ("AssocTypeSet" 47)) + (object Attribute + tool "CORBA" + name "AssocTypeSet" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "Array" + value 24) + (object Attribute + tool "CORBA" + name "Sequence" + value 47))))) + (object Attribute + tool "CORBA" + name "default__Uses" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "GenerateForwardReference" + value FALSE))) + (object Attribute + tool "CORBA" + name "default__Param" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "Direction" + value ("ParamDirectionTypeSet" 102)) + (object Attribute + tool "CORBA" + name "ParamDirectionTypeSet" + value (list Attribute_Set + (object Attribute + tool "CORBA" + name "in" + value 102) + (object Attribute + tool "CORBA" + name "inout" + value 103) + (object Attribute + tool "CORBA" + name "out" + value 104))))) + (object Attribute + tool "CORBA" + name "HiddenTool" + value FALSE) + (object Attribute + tool "Deploy" + name "HiddenTool" + value FALSE) + (object Attribute + tool "framework" + name "HiddenTool" + value FALSE) + (object Attribute + tool "Java" + name "propertyId" + value "809135966") + (object Attribute + tool "Java" + name "default__Project" + value (list Attribute_Set + (object Attribute + tool "Java" + name "RootDir" + value "") + (object Attribute + tool "Java" + name "CreateMissingDirectories" + value TRUE) + (object Attribute + tool "Java" + name "StopOnError" + value FALSE) + (object Attribute + tool "Java" + name "UsePrefixes" + value FALSE) + (object Attribute + tool "Java" + name "AutoSync" + value FALSE) + (object Attribute + tool "Java" + name "NotShowRoseIDDlg" + value FALSE) + (object Attribute + tool "Java" + name "ShowCodegenDlg" + value FALSE) + (object Attribute + tool "Java" + name "GenerateRoseID" + value TRUE) + (object Attribute + tool "Java" + name "GenerateDefaultJ2EEJavadoc" + value TRUE) + (object Attribute + tool "Java" + name "GenerateDefaultReturnLine" + value TRUE) + (object Attribute + tool "Java" + name "JavadocDefaultAuthor" + value "") + (object Attribute + tool "Java" + name "JavadocDefaultVersion" + value "") + (object Attribute + tool "Java" + name "JavadocDefaultSince" + value "") + (object Attribute + tool "Java" + name "UserDefineJavaDocTags" + value "") + (object Attribute + tool "Java" + name "JavadocNumAsterisks" + value 0) + (object Attribute + tool "Java" + name "MaxNumChars" + value 80) + (object Attribute + tool "Java" + name "Editor" + value ("EditorType" 100)) + (object Attribute + tool "Java" + name "VM" + value ("VMType" 200)) + (object Attribute + tool "Java" + name "ClassPath" + value "C:\\Program Files\\Java\\jdk1.8.0_181\\lib\\tools.jar;C:\\Program Files (x86)\\Java\\jdk1.8.0_192\\jre\\lib\\rt.jar;C:\\Program Files (x86)\\Java\\jdk1.8.0_192\\lib\\dt.jar;C:\\Program Files (x86)\\Java\\jdk1.8.0_192\\lib\\tools.jar") + (object Attribute + tool "Java" + name "ReferenceClasspath" + value "") + (object Attribute + tool "Java" + name "EditorType" + value (list Attribute_Set + (object Attribute + tool "Java" + name "BuiltIn" + value 100))) + (object Attribute + tool "Java" + name "VMType" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Sun" + value 200))) + (object Attribute + tool "Java" + name "VAJavaWorkingFolder" + value "") + (object Attribute + tool "Java" + name "InstanceVariablePrefix" + value "") + (object Attribute + tool "Java" + name "ClassVariablePrefix" + value "") + (object Attribute + tool "Java" + name "DefaultAttributeDataType" + value "int") + (object Attribute + tool "Java" + name "DefaultOperationReturnType" + value "void") + (object Attribute + tool "Java" + name "NoClassCustomDlg" + value FALSE) + (object Attribute + tool "Java" + name "GlobalImports" + value (value Text "")) + (object Attribute + tool "Java" + name "OpenBraceClassStyle" + value TRUE) + (object Attribute + tool "Java" + name "OpenBraceMethodStyle" + value TRUE) + (object Attribute + tool "Java" + name "UseTabs" + value FALSE) + (object Attribute + tool "Java" + name "UseSpaces" + value TRUE) + (object Attribute + tool "Java" + name "SpacingItems" + value 3) + (object Attribute + tool "Java" + name "RoseDefaultCommentStyle" + value TRUE) + (object Attribute + tool "Java" + name "AsteriskCommentStyle" + value TRUE) + (object Attribute + tool "Java" + name "JavaCommentStyle" + value TRUE) + (object Attribute + tool "Java" + name "JavadocAuthor" + value FALSE) + (object Attribute + tool "Java" + name "JavadocSince" + value FALSE) + (object Attribute + tool "Java" + name "JavadocVersion" + value FALSE) + (object Attribute + tool "Java" + name "JavadocExceptionTag" + value "@throws") + (object Attribute + tool "Java" + name "BeanPrefix" + value "") + (object Attribute + tool "Java" + name "BeanSuffix" + value "") + (object Attribute + tool "Java" + name "RemotePrefix" + value "") + (object Attribute + tool "Java" + name "RemoteSuffix" + value "") + (object Attribute + tool "Java" + name "HomePrefix" + value "") + (object Attribute + tool "Java" + name "HomeSuffix" + value "") + (object Attribute + tool "Java" + name "LocalPrefix" + value "") + (object Attribute + tool "Java" + name "LocalSuffix" + value "") + (object Attribute + tool "Java" + name "LocalHomePrefix" + value "") + (object Attribute + tool "Java" + name "LocalHomeSuffix" + value "") + (object Attribute + tool "Java" + name "PrimaryKeyPrefix" + value "") + (object Attribute + tool "Java" + name "PrimaryKeySuffix" + value "") + (object Attribute + tool "Java" + name "EJBDTDLocation" + value "") + (object Attribute + tool "Java" + name "ServletDTDLocation" + value "") + (object Attribute + tool "Java" + name "DefaultEJBVersion" + value "") + (object Attribute + tool "Java" + name "DefaultServletVersion" + value "") + (object Attribute + tool "Java" + name "SourceControl" + value FALSE) + (object Attribute + tool "Java" + name "SCCSelected" + value FALSE) + (object Attribute + tool "Java" + name "SCCProjectSourceRoot" + value "") + (object Attribute + tool "Java" + name "SCCProjectName" + value "") + (object Attribute + tool "Java" + name "SCCComment" + value FALSE) + (object Attribute + tool "Java" + name "FundamentalType" + value "boolean; char; byte; short; int; long; float; double; Boolean; Byte; Character; Double; Float; Integer; Long; Object; Short; String; StringBuffer; Void; java.math.BigDecimal; java.math.BigInteger; java.sql.Date; java.sql.Time; java.sql.Timestamp; java.util.AbstractCollection; java.util.AbstractList;java.util.AbstractMap; java.util.AbstractSequentialList; java.util.AbstractSet; java.util.ArrayList; java.util.Arrays; java.util.BitSet; java.util.Calendar; java.util.Collections; java.util.Date; java.util.Date; java.util.Dictionary; java.util.EventObject; java.util.GregorianCalendar; java.util.HashMap; java.util.HashSet; java.util.Hashtable; java.util.LinkedList; java.util.ListResourceBundle; java.util.Locale; java.util.Observable; java.util.Properties; java.util.PropertyPermission; java.util.PropertyResourceBundle; java.util.Random; java.util.ResourceBundle; java.util.SimpleTimeZone; java.util.Stack; java.util.StringTokenizer; java.util.Timer; java.util.TimerTask; java.util.TimeZone; java.util.TreeMap; java.util.TreeSet; java.util.Vector; java.util.WeakHashMap;int; float; boolean; char; double; short; long; byte; ;Boolean; Byte; Character; Double; Float; Integer; Long; Object; Short; String; StringBuffer; Void; java.math.BigDecimal; java.math.BigInteger; java.sql.Date; java.sql.Time; java.sql.Timestamp; ;java.util.AbstractCollection; java.util.AbstractList; java.util.AbstractMap; java.util.AbstractSequentialList; java.util.AbstractSet; java.util.ArrayList; java.util.Arrays; java.util.BitSet; java.util.Calendar; java.util.Collections; java.util.Date; java.util.Dictionary; java.util.EventObject; java.util.GregorianCalendar; java.util.HashMap; java.util.HashSet; java.util.Hashtable; java.util.LinkedList; java.util.ListResourceBundle; java.util.Locale; java.util.Observable; java.util.Properties; java.util.PropertyPermission; java.util.PropertyResourceBundle; java.util.Random; java.util.ResourceBundle; java.util.ArrayList; java.util.SimpleTimeZone; java.util.Stack; java.util.StringTokenizer; java.util.Timer; java.util.TimerTask; java.util.TimerTask; java.util.TimeZone; java.util.TreeMap; java.util.TreeSet; java.util.Vector; java.util.WeakHashMap; "))) + (object Attribute + tool "Java" + name "default__Class" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Final" + value FALSE) + (object Attribute + tool "Java" + name "Static" + value FALSE) + (object Attribute + tool "Java" + name "GenerateDefaultConstructor" + value TRUE) + (object Attribute + tool "Java" + name "ConstructorIs" + value ("Ctor_Set" 62)) + (object Attribute + tool "Java" + name "Ctor_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "public" + value 62) + (object Attribute + tool "Java" + name "protected" + value 63) + (object Attribute + tool "Java" + name "private" + value 64) + (object Attribute + tool "Java" + name "package" + value 65))) + (object Attribute + tool "Java" + name "GenerateFinalizer" + value FALSE) + (object Attribute + tool "Java" + name "GenerateStaticInitializer" + value FALSE) + (object Attribute + tool "Java" + name "GenerateInstanceInitializer" + value FALSE) + (object Attribute + tool "Java" + name "GenerateCode" + value TRUE) + (object Attribute + tool "Java" + name "DisableAutoSync" + value FALSE) + (object Attribute + tool "Java" + name "ReadOnly" + value FALSE) + (object Attribute + tool "Java" + name "Strictfp" + value FALSE))) + (object Attribute + tool "Java" + name "Default_Servlet__Class" + value (list Attribute_Set + (object Attribute + tool "Java" + name "ServletName" + value "") + (object Attribute + tool "Java" + name "ServletContextRef" + value FALSE) + (object Attribute + tool "Java" + name "IsSingleThread" + value FALSE) + (object Attribute + tool "Java" + name "ServletInitParameter" + value "") + (object Attribute + tool "Java" + name "ServletInitParameterNames" + value FALSE) + (object Attribute + tool "Java" + name "ServletIsSecure" + value FALSE) + (object Attribute + tool "Java" + name "ServletRequestDispatcher" + value FALSE) + (object Attribute + tool "Java" + name "ServletRequestDispatcherPath" + value "") + (object Attribute + tool "Java" + name "DispatcherInclude" + value FALSE) + (object Attribute + tool "Java" + name "DispatcherForward" + value FALSE) + (object Attribute + tool "Java" + name "ServletSecurityRoles" + value "") + (object Attribute + tool "Java" + name "ServletgetInfo" + value "") + (object Attribute + tool "Java" + name "ServletXMLFilePath" + value ""))) + (object Attribute + tool "Java" + name "Http_Servlet__Class" + value (list Attribute_Set + (object Attribute + tool "Java" + name "ServletRequestAttribute" + value "") + (object Attribute + tool "Java" + name "ServletRequestAttributesNames" + value FALSE) + (object Attribute + tool "Java" + name "MethodForRequestAttributes" + value "") + (object Attribute + tool "Java" + name "ServletRequestParameter" + value "") + (object Attribute + tool "Java" + name "ServletRequestParameterNames" + value FALSE) + (object Attribute + tool "Java" + name "MethodForRequestParameters" + value "") + (object Attribute + tool "Java" + name "ServletHeader" + value "") + (object Attribute + tool "Java" + name "ServletHeaderNames" + value FALSE) + (object Attribute + tool "Java" + name "MethodForHeaders" + value "") + (object Attribute + tool "Java" + name "ServletIntHeader" + value FALSE) + (object Attribute + tool "Java" + name "ServletDateHeader" + value FALSE) + (object Attribute + tool "Java" + name "ServletCookie" + value FALSE) + (object Attribute + tool "Java" + name "MethodForCookie" + value "") + (object Attribute + tool "Java" + name "ServletContentType" + value "") + (object Attribute + tool "Java" + name "GenerateHTML" + value FALSE))) + (object Attribute + tool "Java" + name "Default_EJB__Class" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Generate_XML_DD" + value TRUE) + (object Attribute + tool "Java" + name "EJBCmpField" + value "") + (object Attribute + tool "Java" + name "EJBEnvironmentProperties" + value "") + (object Attribute + tool "Java" + name "EJBCnxFactory" + value "") + (object Attribute + tool "Java" + name "EJBReferences" + value "") + (object Attribute + tool "Java" + name "EJBSecurityRoles" + value "") + (object Attribute + tool "Java" + name "EJBNameInJAR" + value "") + (object Attribute + tool "Java" + name "EJBSessionType" + value ("EJBSessionType_Set" 200)) + (object Attribute + tool "Java" + name "EJBSessionType_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "" + value 200) + (object Attribute + tool "Java" + name "Stateless" + value 201) + (object Attribute + tool "Java" + name "Stateful" + value 202))) + (object Attribute + tool "Java" + name "EJBTransactionType" + value ("EJBTransactionType_Set" 211)) + (object Attribute + tool "Java" + name "EJBTransactionType_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Container" + value 211) + (object Attribute + tool "Java" + name "Bean" + value 212))) + (object Attribute + tool "Java" + name "EJBPersistenceType" + value ("EJBPersistenceType_Set" 220)) + (object Attribute + tool "Java" + name "EJBPersistenceType_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "" + value 220) + (object Attribute + tool "Java" + name "Bean" + value 221) + (object Attribute + tool "Java" + name "Container" + value 222))) + (object Attribute + tool "Java" + name "EJBReentrant" + value FALSE) + (object Attribute + tool "Java" + name "EJBSessionSync" + value FALSE) + (object Attribute + tool "Java" + name "EJBVersion" + value ("EJBVersion_Set" 230)) + (object Attribute + tool "Java" + name "EJBVersion_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "2.0" + value 230) + (object Attribute + tool "Java" + name "1.x" + value 231))) + (object Attribute + tool "Java" + name "EJBXMLFilePath" + value ""))) + (object Attribute + tool "Java" + name "default__Module-Spec" + value (list Attribute_Set + (object Attribute + tool "Java" + name "CmIdentification" + value (value Text "")) + (object Attribute + tool "Java" + name "CopyrightNotice" + value (value Text "")))) + (object Attribute + tool "Java" + name "default__Module-Body" + value (list Attribute_Set + (object Attribute + tool "Java" + name "CmIdentification" + value (value Text "")) + (object Attribute + tool "Java" + name "CopyrightNotice" + value (value Text "")))) + (object Attribute + tool "Java" + name "default__Operation" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Abstract" + value FALSE) + (object Attribute + tool "Java" + name "Static" + value FALSE) + (object Attribute + tool "Java" + name "Final" + value FALSE) + (object Attribute + tool "Java" + name "Native" + value FALSE) + (object Attribute + tool "Java" + name "Synchronized" + value FALSE) + (object Attribute + tool "Java" + name "GenerateFullyQualifiedReturn" + value FALSE) + (object Attribute + tool "Java" + name "ReplaceExistingCode" + value TRUE) + (object Attribute + tool "Java" + name "Strictfp" + value FALSE))) + (object Attribute + tool "Java" + name "default__Attribute" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Final" + value FALSE) + (object Attribute + tool "Java" + name "Transient" + value FALSE) + (object Attribute + tool "Java" + name "Volatile" + value FALSE) + (object Attribute + tool "Java" + name "PropertyType" + value ("BeanProperty_Set" 71)) + (object Attribute + tool "Java" + name "BeanProperty_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Not A Property" + value 71) + (object Attribute + tool "Java" + name "Simple" + value 72) + (object Attribute + tool "Java" + name "Bound" + value 73) + (object Attribute + tool "Java" + name "Constrained" + value 74))) + (object Attribute + tool "Java" + name "IndividualChangeMgt" + value FALSE) + (object Attribute + tool "Java" + name "Read/Write" + value ("Read/Write_Set" 81)) + (object Attribute + tool "Java" + name "Read/Write_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Read & Write" + value 81) + (object Attribute + tool "Java" + name "Read Only" + value 82) + (object Attribute + tool "Java" + name "Write Only" + value 83))) + (object Attribute + tool "Java" + name "GenerateFullyQualifiedTypes" + value FALSE))) + (object Attribute + tool "Java" + name "default__Role" + value (list Attribute_Set + (object Attribute + tool "Java" + name "ContainerClass" + value "") + (object Attribute + tool "Java" + name "InitialValue" + value "") + (object Attribute + tool "Java" + name "Final" + value FALSE) + (object Attribute + tool "Java" + name "Transient" + value FALSE) + (object Attribute + tool "Java" + name "Volatile" + value FALSE) + (object Attribute + tool "Java" + name "PropertyType" + value ("BeanProperty_Set" 71)) + (object Attribute + tool "Java" + name "BeanProperty_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Not A Property" + value 71) + (object Attribute + tool "Java" + name "Simple" + value 72) + (object Attribute + tool "Java" + name "Bound" + value 73) + (object Attribute + tool "Java" + name "Constrained" + value 74))) + (object Attribute + tool "Java" + name "IndividualChangeMgt" + value FALSE) + (object Attribute + tool "Java" + name "Read/Write" + value ("Read/Write_Set" 81)) + (object Attribute + tool "Java" + name "Read/Write_Set" + value (list Attribute_Set + (object Attribute + tool "Java" + name "Read & Write" + value 81) + (object Attribute + tool "Java" + name "Read Only" + value 82) + (object Attribute + tool "Java" + name "Write Only" + value 83))) + (object Attribute + tool "Java" + name "GenerateFullyQualifiedTypes" + value FALSE) + (object Attribute + tool "Java" + name "IsNavigable" + value TRUE))) + (object Attribute + tool "Java" + name "HiddenTool" + value FALSE) + (object Attribute + tool "Oracle8" + name "propertyId" + value "360000002") + (object Attribute + tool "Oracle8" + name "default__Project" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "DDLScriptFilename" + value "DDL1.SQL") + (object Attribute + tool "Oracle8" + name "DropClause" + value FALSE) + (object Attribute + tool "Oracle8" + name "PrimaryKeyColumnName" + value "_ID") + (object Attribute + tool "Oracle8" + name "PrimaryKeyColumnType" + value "NUMBER(5,0)") + (object Attribute + tool "Oracle8" + name "SchemaNamePrefix" + value "") + (object Attribute + tool "Oracle8" + name "SchemaNameSuffix" + value "") + (object Attribute + tool "Oracle8" + name "TableNamePrefix" + value "") + (object Attribute + tool "Oracle8" + name "TableNameSuffix" + value "") + (object Attribute + tool "Oracle8" + name "TypeNamePrefix" + value "") + (object Attribute + tool "Oracle8" + name "TypeNameSuffix" + value "") + (object Attribute + tool "Oracle8" + name "ViewNamePrefix" + value "") + (object Attribute + tool "Oracle8" + name "ViewNameSuffix" + value "") + (object Attribute + tool "Oracle8" + name "VarrayNamePrefix" + value "") + (object Attribute + tool "Oracle8" + name "VarrayNameSuffix" + value "") + (object Attribute + tool "Oracle8" + name "NestedTableNamePrefix" + value "") + (object Attribute + tool "Oracle8" + name "NestedTableNameSuffix" + value "") + (object Attribute + tool "Oracle8" + name "ObjectTableNamePrefix" + value "") + (object Attribute + tool "Oracle8" + name "ObjectTableNameSuffix" + value ""))) + (object Attribute + tool "Oracle8" + name "default__Module-Spec" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "IsSchema" + value FALSE))) + (object Attribute + tool "Oracle8" + name "default__Class" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "OID" + value "") + (object Attribute + tool "Oracle8" + name "WhereClause" + value "") + (object Attribute + tool "Oracle8" + name "CheckConstraint" + value "") + (object Attribute + tool "Oracle8" + name "CollectionTypeLength" + value "") + (object Attribute + tool "Oracle8" + name "CollectionTypePrecision" + value "") + (object Attribute + tool "Oracle8" + name "CollectionTypeScale" + value "") + (object Attribute + tool "Oracle8" + name "CollectionOfREFS" + value FALSE))) + (object Attribute + tool "Oracle8" + name "default__Operation" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "MethodKind" + value ("MethodKindSet" 1903)) + (object Attribute + tool "Oracle8" + name "OverloadID" + value "") + (object Attribute + tool "Oracle8" + name "OrderNumber" + value "") + (object Attribute + tool "Oracle8" + name "IsReadNoDataState" + value FALSE) + (object Attribute + tool "Oracle8" + name "IsReadNoProcessState" + value FALSE) + (object Attribute + tool "Oracle8" + name "IsWriteNoDataState" + value FALSE) + (object Attribute + tool "Oracle8" + name "IsWriteNoProcessState" + value FALSE) + (object Attribute + tool "Oracle8" + name "IsSelfish" + value FALSE) + (object Attribute + tool "Oracle8" + name "TriggerType" + value ("TriggerTypeSet" 1801)) + (object Attribute + tool "Oracle8" + name "TriggerEvent" + value ("TriggerEventSet" 1601)) + (object Attribute + tool "Oracle8" + name "TriggerText" + value "") + (object Attribute + tool "Oracle8" + name "TriggerReferencingNames" + value "") + (object Attribute + tool "Oracle8" + name "TriggerForEach" + value ("TriggerForEachSet" 1701)) + (object Attribute + tool "Oracle8" + name "TriggerWhenClause" + value "") + (object Attribute + tool "Oracle8" + name "MethodKindSet" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "MapMethod" + value 1901) + (object Attribute + tool "Oracle8" + name "OrderMethod" + value 1902) + (object Attribute + tool "Oracle8" + name "Function" + value 1903) + (object Attribute + tool "Oracle8" + name "Procedure" + value 1904) + (object Attribute + tool "Oracle8" + name "Operator" + value 1905) + (object Attribute + tool "Oracle8" + name "Constructor" + value 1906) + (object Attribute + tool "Oracle8" + name "Destructor" + value 1907) + (object Attribute + tool "Oracle8" + name "Trigger" + value 1908) + (object Attribute + tool "Oracle8" + name "Calculated" + value 1909))) + (object Attribute + tool "Oracle8" + name "TriggerTypeSet" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "AFTER" + value 1801) + (object Attribute + tool "Oracle8" + name "BEFORE" + value 1802) + (object Attribute + tool "Oracle8" + name "INSTEAD OF" + value 1803))) + (object Attribute + tool "Oracle8" + name "TriggerForEachSet" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "ROW" + value 1701) + (object Attribute + tool "Oracle8" + name "STATEMENT" + value 1702))) + (object Attribute + tool "Oracle8" + name "TriggerEventSet" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "INSERT" + value 1601) + (object Attribute + tool "Oracle8" + name "UPDATE" + value 1602) + (object Attribute + tool "Oracle8" + name "DELETE" + value 1603) + (object Attribute + tool "Oracle8" + name "INSERT OR UPDATE" + value 1604) + (object Attribute + tool "Oracle8" + name "INSERT OR DELETE" + value 1605) + (object Attribute + tool "Oracle8" + name "UPDATE OR DELETE" + value 1606) + (object Attribute + tool "Oracle8" + name "INSERT OR UPDATE OR DELETE" + value 1607))))) + (object Attribute + tool "Oracle8" + name "default__Role" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "OrderNumber" + value ""))) + (object Attribute + tool "Oracle8" + name "default__Attribute" + value (list Attribute_Set + (object Attribute + tool "Oracle8" + name "OrderNumber" + value "") + (object Attribute + tool "Oracle8" + name "IsUnique" + value FALSE) + (object Attribute + tool "Oracle8" + name "NullsAllowed" + value TRUE) + (object Attribute + tool "Oracle8" + name "Length" + value "") + (object Attribute + tool "Oracle8" + name "Precision" + value "2") + (object Attribute + tool "Oracle8" + name "Scale" + value "6") + (object Attribute + tool "Oracle8" + name "IsIndex" + value FALSE) + (object Attribute + tool "Oracle8" + name "IsPrimaryKey" + value FALSE) + (object Attribute + tool "Oracle8" + name "CompositeUnique" + value FALSE) + (object Attribute + tool "Oracle8" + name "CheckConstraint" + value ""))) + (object Attribute + tool "Oracle8" + name "HiddenTool" + value FALSE) + (object Attribute + tool "Rose Model Integrator" + name "HiddenTool" + value FALSE) + (object Attribute + tool "Rose Web Publisher" + name "HiddenTool" + value FALSE) + (object Attribute + tool "TopLink" + name "HiddenTool" + value FALSE) + (object Attribute + tool "COM" + name "propertyId" + value "783606378") + (object Attribute + tool "COM" + name "default__Class" + value (list Attribute_Set + (object Attribute + tool "COM" + name "TypeKinds" + value (list Attribute_Set + (object Attribute + tool "COM" + name "enum" + value 100) + (object Attribute + tool "COM" + name "record" + value 101) + (object Attribute + tool "COM" + name "module" + value 102) + (object Attribute + tool "COM" + name "interface" + value 103) + (object Attribute + tool "COM" + name "dispinterface" + value 104) + (object Attribute + tool "COM" + name "coclass" + value 105) + (object Attribute + tool "COM" + name "alias" + value 106) + (object Attribute + tool "COM" + name "union" + value 107) + (object Attribute + tool "COM" + name "max" + value 108) + (object Attribute + tool "COM" + name "(none)" + value 109))) + (object Attribute + tool "COM" + name "Generate" + value TRUE) + (object Attribute + tool "COM" + name "kind" + value ("TypeKinds" 109)) + (object Attribute + tool "COM" + name "uuid" + value "") + (object Attribute + tool "COM" + name "version" + value "") + (object Attribute + tool "COM" + name "helpstring" + value "") + (object Attribute + tool "COM" + name "helpcontext" + value "") + (object Attribute + tool "COM" + name "attributes" + value "") + (object Attribute + tool "COM" + name "dllname" + value "") + (object Attribute + tool "COM" + name "alias" + value ""))) + (object Attribute + tool "COM" + name "default__Operation" + value (list Attribute_Set + (object Attribute + tool "COM" + name "Generate" + value TRUE) + (object Attribute + tool "COM" + name "id" + value "") + (object Attribute + tool "COM" + name "helpstring" + value "") + (object Attribute + tool "COM" + name "attributes" + value ""))) + (object Attribute + tool "COM" + name "default__Attribute" + value (list Attribute_Set + (object Attribute + tool "COM" + name "Generate" + value TRUE) + (object Attribute + tool "COM" + name "id" + value "") + (object Attribute + tool "COM" + name "helpstring" + value "") + (object Attribute + tool "COM" + name "attributes" + value ""))) + (object Attribute + tool "COM" + name "default__Module-Spec" + value (list Attribute_Set + (object Attribute + tool "COM" + name "Generate" + value TRUE) + (object Attribute + tool "COM" + name "filename" + value "") + (object Attribute + tool "COM" + name "library" + value "") + (object Attribute + tool "COM" + name "uuid" + value "") + (object Attribute + tool "COM" + name "version" + value "") + (object Attribute + tool "COM" + name "helpstring" + value "") + (object Attribute + tool "COM" + name "helpfile" + value "") + (object Attribute + tool "COM" + name "helpcontext" + value "") + (object Attribute + tool "COM" + name "lcid" + value "") + (object Attribute + tool "COM" + name "attributes" + value ""))) + (object Attribute + tool "COM" + name "default__Param" + value (list Attribute_Set + (object Attribute + tool "COM" + name "attributes" + value ""))) + (object Attribute + tool "COM" + name "HiddenTool" + value FALSE) + (object Attribute + tool "Version Control" + name "HiddenTool" + value FALSE) + (object Attribute + tool "VisualStudio" + name "HiddenTool" + value FALSE) + (object Attribute + tool "XML_DTD" + name "propertyId" + value "809135966") + (object Attribute + tool "XML_DTD" + name "default__Project" + value (list Attribute_Set + (object Attribute + tool "XML_DTD" + name "CreateMissingDirectories" + value TRUE) + (object Attribute + tool "XML_DTD" + name "Editor" + value ("EditorType" 100)) + (object Attribute + tool "XML_DTD" + name "StopOnError" + value TRUE) + (object Attribute + tool "XML_DTD" + name "EditorType" + value (list Attribute_Set + (object Attribute + tool "XML_DTD" + name "BuiltIn" + value 100) + (object Attribute + tool "XML_DTD" + name "WindowsShell" + value 101))))) + (object Attribute + tool "XML_DTD" + name "default__Class" + value (list Attribute_Set + (object Attribute + tool "XML_DTD" + name "Entity_SystemID" + value "") + (object Attribute + tool "XML_DTD" + name "Entity_PublicID" + value "") + (object Attribute + tool "XML_DTD" + name "NotationValue" + value "") + (object Attribute + tool "XML_DTD" + name "InternalValue" + value "") + (object Attribute + tool "XML_DTD" + name "ParameterEntity" + value FALSE) + (object Attribute + tool "XML_DTD" + name "ExternalEntity" + value FALSE) + (object Attribute + tool "XML_DTD" + name "Notation_SystemID" + value "") + (object Attribute + tool "XML_DTD" + name "Notation_PublicID" + value ""))) + (object Attribute + tool "XML_DTD" + name "default__Attribute" + value (list Attribute_Set + (object Attribute + tool "XML_DTD" + name "DefaultDeclType" + value ""))) + (object Attribute + tool "XML_DTD" + name "default__Module-Spec" + value (list Attribute_Set + (object Attribute + tool "XML_DTD" + name "Assign All" + value FALSE) + (object Attribute + tool "XML_DTD" + name "ComponentPath" + value ""))) + (object Attribute + tool "XML_DTD" + name "HiddenTool" + value FALSE)) + quid "5C2F070B0359")) diff --git "a/\345\274\240\346\226\207\344\270\271201601450137\350\256\241\347\256\227\346\234\272\347\247\221\345\255\246\344\270\216\346\212\200\346\234\257\344\270\200\347\217\255.docx" "b/\345\274\240\346\226\207\344\270\271201601450137\350\256\241\347\256\227\346\234\272\347\247\221\345\255\246\344\270\216\346\212\200\346\234\257\344\270\200\347\217\255.docx" new file mode 100644 index 0000000000000000000000000000000000000000..48e045db6b2f857a6a451e1646dac2e84d0b7fdf Binary files /dev/null and "b/\345\274\240\346\226\207\344\270\271201601450137\350\256\241\347\256\227\346\234\272\347\247\221\345\255\246\344\270\216\346\212\200\346\234\257\344\270\200\347\217\255.docx" differ diff --git "a/\346\235\216\346\231\223\346\242\205-201601450131-16\350\256\241\347\247\221\344\270\200\347\217\255.docx" "b/\346\235\216\346\231\223\346\242\205-201601450131-16\350\256\241\347\247\221\344\270\200\347\217\255.docx" new file mode 100644 index 0000000000000000000000000000000000000000..d86665d4804fa0faa762927cc401a93ce6c5d4a1 Binary files /dev/null and "b/\346\235\216\346\231\223\346\242\205-201601450131-16\350\256\241\347\247\221\344\270\200\347\217\255.docx" differ diff --git "a/\347\216\213\345\206\254\351\233\250201601450140\350\256\241\347\256\227\346\234\272\347\247\221\345\255\246\344\270\216\346\212\200\346\234\2571\347\217\255.docx" "b/\347\216\213\345\206\254\351\233\250201601450140\350\256\241\347\256\227\346\234\272\347\247\221\345\255\246\344\270\216\346\212\200\346\234\2571\347\217\255.docx" new file mode 100644 index 0000000000000000000000000000000000000000..dea2fcf89ccb6ae04c1dec6cb280d100b2a2a0e2 Binary files /dev/null and "b/\347\216\213\345\206\254\351\233\250201601450140\350\256\241\347\256\227\346\234\272\347\247\221\345\255\246\344\270\216\346\212\200\346\234\2571\347\217\255.docx" differ diff --git "a/\347\216\213\346\224\277\351\234\226-201601450105-16\350\256\241\347\247\221\344\270\200\347\217\255.docx" "b/\347\216\213\346\224\277\351\234\226-201601450105-16\350\256\241\347\247\221\344\270\200\347\217\255.docx" new file mode 100644 index 0000000000000000000000000000000000000000..44349a3dc2dd4b5fb8f36d7594cade076475427e Binary files /dev/null and "b/\347\216\213\346\224\277\351\234\226-201601450105-16\350\256\241\347\247\221\344\270\200\347\217\255.docx" differ