├── .gitattributes ├── .gitignore ├── .gitmodules ├── .travis.yml ├── .travis_descriptor.json ├── AppArchitecture.png ├── CHANGELOG.md ├── LICENSE.txt ├── NOTICE.txt ├── POLICY.md ├── README.md ├── USER MANUAL.md ├── _config.yml ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── ch │ │ └── zhaw │ │ └── facerecognition │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── ch │ │ │ └── zhaw │ │ │ └── facerecognition │ │ │ ├── Activities │ │ │ ├── AddPersonActivity.java │ │ │ ├── AddPersonPreviewActivity.java │ │ │ ├── AppCompatPreferenceActivity.java │ │ │ ├── DetectionActivity.java │ │ │ ├── DetectionTestActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── RecognitionActivity.java │ │ │ ├── SettingsActivity.java │ │ │ ├── TestActivity.java │ │ │ └── TrainingActivity.java │ │ │ └── Helpers │ │ │ ├── EditTextPreference.java │ │ │ ├── ListPreference.java │ │ │ ├── MultiSelectListPreference.java │ │ │ └── SwitchPreference.java │ └── res │ │ ├── drawable-hdpi │ │ ├── ic_camera.png │ │ ├── ic_info_black_24dp.png │ │ ├── ic_notifications_black_24dp.png │ │ └── ic_sync_black_24dp.png │ │ ├── drawable-mdpi │ │ ├── ic_camera.png │ │ ├── ic_info_black_24dp.png │ │ ├── ic_notifications_black_24dp.png │ │ └── ic_sync_black_24dp.png │ │ ├── drawable-v21 │ │ ├── ic_info_black_24dp.xml │ │ ├── ic_notifications_black_24dp.xml │ │ └── ic_sync_black_24dp.xml │ │ ├── drawable-xhdpi │ │ ├── ic_camera.png │ │ ├── ic_info_black_24dp.png │ │ ├── ic_notifications_black_24dp.png │ │ └── ic_sync_black_24dp.png │ │ ├── drawable-xxhdpi │ │ ├── ic_camera.png │ │ ├── ic_info_black_24dp.png │ │ ├── ic_notifications_black_24dp.png │ │ └── ic_sync_black_24dp.png │ │ ├── drawable-xxxhdpi │ │ ├── ic_info_black_24dp.png │ │ ├── ic_notifications_black_24dp.png │ │ └── ic_sync_black_24dp.png │ │ ├── drawable │ │ └── background_main.jpg │ │ ├── layout │ │ ├── activity_add_person.xml │ │ ├── activity_add_person_preview.xml │ │ ├── activity_detection.xml │ │ ├── activity_detection_test.xml │ │ ├── activity_main.xml │ │ ├── activity_test.xml │ │ ├── activity_training.xml │ │ └── recognition_layout.xml │ │ ├── menu │ │ └── options.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── ch │ └── zhaw │ └── facerecognition │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── import-summary.txt └── settings.gradle /.gitattributes: -------------------------------------------------------------------------------- 1 | .idea/* linguist-vendored 2 | build/* linguist-vendored 3 | gradle/* linguist-vendored 4 | app/src/main/jniLibs/* linguist-vendored 5 | jni-build/obj/* linguist-vendored 6 | jni-build/libs/* linguist-vendored 7 | jni-build/jni/genfiles/* linguist-vendored 8 | jni-build/jni/include/* linguist-vendored 9 | jni-build/jni/libs/* linguist-vendored 10 | jni-build/jni/libsvm/* linguist-vendored 11 | openCVLibrary310/* linguist-vendored 12 | 13 | CHANGELOG.md linguist-documentation 14 | LICENSE.txt linguist-documentation 15 | NOTICE.txt linguist-documentation 16 | README.md linguist-documentation 17 | USER MANUAL.md linguist-documentation -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | local.properties 2 | 3 | /.gradle/ 4 | /build/ 5 | 6 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 7 | !gradle-wrapper.jar 8 | 9 | *.iml 10 | /.idea/ 11 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "facerecognitionlibrary"] 2 | path = facerecognitionlibrary 3 | url = https://github.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Library.git 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | script: 2 | - "./gradlew build" 3 | language: android 4 | jdk: 5 | - oraclejdk8 6 | android: 7 | components: 8 | - tools 9 | - build-tools-23.0.1 10 | - android-23 11 | - extra-android-m2repository 12 | deploy: 13 | provider: bintray 14 | file: ".travis_descriptor.json" 15 | user: sladomic 16 | key: 17 | secure: sniav6EuV1bZckwlY2lp0W0fDwSvt6d9SuzWshDlQ7xY21T6a8B8JDa8hlYCrl9ANqNKpN3FwHQnMaeFuZhUrfv/G40rxfUqE9Cm6BKbFXPfQEpUlnKKIDNBA/GphYTpbXnas7h5OLmBgQIafZUsg9y17xweKcYm0GmxcnZiFtuELIOMi+Gp8Uxm3hNOLSLm8mF54azpZDTBZRWDbZXDsesKfSt+yXp2O75VwYxXMSRnl7IBsP1LycHogE7OdzSS/4Qccq4nFqiKH6vC/ZcuFdefMSr6MhkXPVBeeWIdpuRSy+9ha7OFfksHvSwgpFQmCJGjB1E3CJH83EC5TdkreXoc1+lksyqyAcJjK/Dof3aLsdCT/thI1hAO31L7zPuvNRd+ZCDfi+syU0FPfrUqAP8J99bA8+LS6OlC6LjC9wOU8ufwENOxS33B83/aYymP1CMEt71cmaM8eNZvdteDiy6TGstWfJsL+8My4VwJCEAZ2Nk29VHvsmb5ODubyM60epWLFBmF7ZzY8e/uC6cWWY8vGo6BqDwECSQzGl6lWRqMgCjnrqv/WHU0owm8uyz/8YZ/RqpPBjEEE9LZzmmLhyMlKLHBWIhCPGarulO44TDInrNgDwT+mTyn3By9iUyTIPSZcWbXPklZB1dxqoLcRrgwiFsXWBSL0DoT8EQ4VnI= -------------------------------------------------------------------------------- /.travis_descriptor.json: -------------------------------------------------------------------------------- 1 | { 2 | "package": { 3 | "name": "auto-upload", 4 | "repo": "Android-Face-Recognition-Deep-Learning-Library", 5 | "subject": "sladomic", 6 | "website_url": "www.jfrog.com", 7 | "issue_tracker_url": "https://github.com/qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/issues", 8 | "vcs_url": "https://github.com/qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework.git", 9 | "github_use_tag_release_notes": true, 10 | "github_release_notes_file": "RELEASE.txt", 11 | "licenses": ["Apache-2.0"], 12 | "public_download_numbers": false, 13 | "public_stats": false 14 | }, 15 | 16 | "version": { 17 | "name": "0.5" 18 | }, 19 | 20 | "files": 21 | [ 22 | {"includePattern": "facerecognitionlibrary/build/outputs/aar/facerecognitionlibrary-release.aar"} 23 | ], 24 | "publish": true 25 | } -------------------------------------------------------------------------------- /AppArchitecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/AppArchitecture.png -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | # Release 1.1.1 4 | 5 | Initial release of Android Face Recognition with Deep Learning. 6 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2016 Michael Sladoje and Mike Schälchli. All rights reserved. 2 | 3 | 4 | Apache License 5 | Version 2.0, January 2004 6 | http://www.apache.org/licenses/ 7 | 8 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 9 | 10 | 1. Definitions. 11 | 12 | "License" shall mean the terms and conditions for use, reproduction, 13 | and distribution as defined by Sections 1 through 9 of this document. 14 | 15 | "Licensor" shall mean the copyright owner or entity authorized by 16 | the copyright owner that is granting the License. 17 | 18 | "Legal Entity" shall mean the union of the acting entity and all 19 | other entities that control, are controlled by, or are under common 20 | control with that entity. For the purposes of this definition, 21 | "control" means (i) the power, direct or indirect, to cause the 22 | direction or management of such entity, whether by contract or 23 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 24 | outstanding shares, or (iii) beneficial ownership of such entity. 25 | 26 | "You" (or "Your") shall mean an individual or Legal Entity 27 | exercising permissions granted by this License. 28 | 29 | "Source" form shall mean the preferred form for making modifications, 30 | including but not limited to software source code, documentation 31 | source, and configuration files. 32 | 33 | "Object" form shall mean any form resulting from mechanical 34 | transformation or translation of a Source form, including but 35 | not limited to compiled object code, generated documentation, 36 | and conversions to other media types. 37 | 38 | "Work" shall mean the work of authorship, whether in Source or 39 | Object form, made available under the License, as indicated by a 40 | copyright notice that is included in or attached to the work 41 | (an example is provided in the Appendix below). 42 | 43 | "Derivative Works" shall mean any work, whether in Source or Object 44 | form, that is based on (or derived from) the Work and for which the 45 | editorial revisions, annotations, elaborations, or other modifications 46 | represent, as a whole, an original work of authorship. For the purposes 47 | of this License, Derivative Works shall not include works that remain 48 | separable from, or merely link (or bind by name) to the interfaces of, 49 | the Work and Derivative Works thereof. 50 | 51 | "Contribution" shall mean any work of authorship, including 52 | the original version of the Work and any modifications or additions 53 | to that Work or Derivative Works thereof, that is intentionally 54 | submitted to Licensor for inclusion in the Work by the copyright owner 55 | or by an individual or Legal Entity authorized to submit on behalf of 56 | the copyright owner. For the purposes of this definition, "submitted" 57 | means any form of electronic, verbal, or written communication sent 58 | to the Licensor or its representatives, including but not limited to 59 | communication on electronic mailing lists, source code control systems, 60 | and issue tracking systems that are managed by, or on behalf of, the 61 | Licensor for the purpose of discussing and improving the Work, but 62 | excluding communication that is conspicuously marked or otherwise 63 | designated in writing by the copyright owner as "Not a Contribution." 64 | 65 | "Contributor" shall mean Licensor and any individual or Legal Entity 66 | on behalf of whom a Contribution has been received by Licensor and 67 | subsequently incorporated within the Work. 68 | 69 | 2. Grant of Copyright License. Subject to the terms and conditions of 70 | this License, each Contributor hereby grants to You a perpetual, 71 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 72 | copyright license to reproduce, prepare Derivative Works of, 73 | publicly display, publicly perform, sublicense, and distribute the 74 | Work and such Derivative Works in Source or Object form. 75 | 76 | 3. Grant of Patent License. Subject to the terms and conditions of 77 | this License, each Contributor hereby grants to You a perpetual, 78 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 79 | (except as stated in this section) patent license to make, have made, 80 | use, offer to sell, sell, import, and otherwise transfer the Work, 81 | where such license applies only to those patent claims licensable 82 | by such Contributor that are necessarily infringed by their 83 | Contribution(s) alone or by combination of their Contribution(s) 84 | with the Work to which such Contribution(s) was submitted. If You 85 | institute patent litigation against any entity (including a 86 | cross-claim or counterclaim in a lawsuit) alleging that the Work 87 | or a Contribution incorporated within the Work constitutes direct 88 | or contributory patent infringement, then any patent licenses 89 | granted to You under this License for that Work shall terminate 90 | as of the date such litigation is filed. 91 | 92 | 4. Redistribution. You may reproduce and distribute copies of the 93 | Work or Derivative Works thereof in any medium, with or without 94 | modifications, and in Source or Object form, provided that You 95 | meet the following conditions: 96 | 97 | (a) You must give any other recipients of the Work or 98 | Derivative Works a copy of this License; and 99 | 100 | (b) You must cause any modified files to carry prominent notices 101 | stating that You changed the files; and 102 | 103 | (c) You must retain, in the Source form of any Derivative Works 104 | that You distribute, all copyright, patent, trademark, and 105 | attribution notices from the Source form of the Work, 106 | excluding those notices that do not pertain to any part of 107 | the Derivative Works; and 108 | 109 | (d) If the Work includes a "NOTICE" text file as part of its 110 | distribution, then any Derivative Works that You distribute must 111 | include a readable copy of the attribution notices contained 112 | within such NOTICE file, excluding those notices that do not 113 | pertain to any part of the Derivative Works, in at least one 114 | of the following places: within a NOTICE text file distributed 115 | as part of the Derivative Works; within the Source form or 116 | documentation, if provided along with the Derivative Works; or, 117 | within a display generated by the Derivative Works, if and 118 | wherever such third-party notices normally appear. The contents 119 | of the NOTICE file are for informational purposes only and 120 | do not modify the License. You may add Your own attribution 121 | notices within Derivative Works that You distribute, alongside 122 | or as an addendum to the NOTICE text from the Work, provided 123 | that such additional attribution notices cannot be construed 124 | as modifying the License. 125 | 126 | You may add Your own copyright statement to Your modifications and 127 | may provide additional or different license terms and conditions 128 | for use, reproduction, or distribution of Your modifications, or 129 | for any such Derivative Works as a whole, provided Your use, 130 | reproduction, and distribution of the Work otherwise complies with 131 | the conditions stated in this License. 132 | 133 | 5. Submission of Contributions. Unless You explicitly state otherwise, 134 | any Contribution intentionally submitted for inclusion in the Work 135 | by You to the Licensor shall be under the terms and conditions of 136 | this License, without any additional terms or conditions. 137 | Notwithstanding the above, nothing herein shall supersede or modify 138 | the terms of any separate license agreement you may have executed 139 | with Licensor regarding such Contributions. 140 | 141 | 6. Trademarks. This License does not grant permission to use the trade 142 | names, trademarks, service marks, or product names of the Licensor, 143 | except as required for reasonable and customary use in describing the 144 | origin of the Work and reproducing the content of the NOTICE file. 145 | 146 | 7. Disclaimer of Warranty. Unless required by applicable law or 147 | agreed to in writing, Licensor provides the Work (and each 148 | Contributor provides its Contributions) on an "AS IS" BASIS, 149 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 150 | implied, including, without limitation, any warranties or conditions 151 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 152 | PARTICULAR PURPOSE. You are solely responsible for determining the 153 | appropriateness of using or redistributing the Work and assume any 154 | risks associated with Your exercise of permissions under this License. 155 | 156 | 8. Limitation of Liability. In no event and under no legal theory, 157 | whether in tort (including negligence), contract, or otherwise, 158 | unless required by applicable law (such as deliberate and grossly 159 | negligent acts) or agreed to in writing, shall any Contributor be 160 | liable to You for damages, including any direct, indirect, special, 161 | incidental, or consequential damages of any character arising as a 162 | result of this License or out of the use or inability to use the 163 | Work (including but not limited to damages for loss of goodwill, 164 | work stoppage, computer failure or malfunction, or any and all 165 | other commercial damages or losses), even if such Contributor 166 | has been advised of the possibility of such damages. 167 | 168 | 9. Accepting Warranty or Additional Liability. While redistributing 169 | the Work or Derivative Works thereof, You may choose to offer, 170 | and charge a fee for, acceptance of support, warranty, indemnity, 171 | or other liability obligations and/or rights consistent with this 172 | License. However, in accepting such obligations, You may act only 173 | on Your own behalf and on Your sole responsibility, not on behalf 174 | of any other Contributor, and only if You agree to indemnify, 175 | defend, and hold each Contributor harmless for any liability 176 | incurred by, or claims asserted against, such Contributor by reason 177 | of your accepting any such warranty or additional liability. 178 | 179 | END OF TERMS AND CONDITIONS 180 | 181 | APPENDIX: How to apply the Apache License to your work. 182 | 183 | To apply the Apache License to your work, attach the following 184 | boilerplate notice, with the fields enclosed by brackets "[]" 185 | replaced with your own identifying information. (Don't include 186 | the brackets!) The text should be enclosed in the appropriate 187 | comment syntax for the file format. We also recommend that a 188 | file or class name and description of purpose be included on the 189 | same "printed page" as the copyright notice for easier 190 | identification within third-party archives. 191 | 192 | Copyright [yyyy] [name of copyright owner] 193 | 194 | Licensed under the Apache License, Version 2.0 (the "License"); 195 | you may not use this file except in compliance with the License. 196 | You may obtain a copy of the License at 197 | 198 | http://www.apache.org/licenses/LICENSE-2.0 199 | 200 | Unless required by applicable law or agreed to in writing, software 201 | distributed under the License is distributed on an "AS IS" BASIS, 202 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 203 | See the License for the specific language governing permissions and 204 | limitations under the License. 205 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | Android Face Recognition with Deep Learning 2 | Copyright 2016 Michael Sladoje and Mike Schälchli. 3 | 4 | This software contains code derived from the following sources: 5 | 6 | /// OpenCV 7 | 8 | By downloading, copying, installing or using the software you agree to this license. 9 | If you do not agree to this license, do not download, install, 10 | copy or use the software. 11 | 12 | 13 | License Agreement 14 | For Open Source Computer Vision Library 15 | (3-clause BSD License) 16 | 17 | Copyright (C) 2000-2016, Intel Corporation, all rights reserved. 18 | Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. 19 | Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved. 20 | Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. 21 | Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved. 22 | Copyright (C) 2015-2016, Itseez Inc., all rights reserved. 23 | Third party copyrights are property of their respective owners. 24 | 25 | Redistribution and use in source and binary forms, with or without modification, 26 | are permitted provided that the following conditions are met: 27 | 28 | * Redistributions of source code must retain the above copyright notice, 29 | this list of conditions and the following disclaimer. 30 | 31 | * Redistributions in binary form must reproduce the above copyright notice, 32 | this list of conditions and the following disclaimer in the documentation 33 | and/or other materials provided with the distribution. 34 | 35 | * Neither the names of the copyright holders nor the names of the contributors 36 | may be used to endorse or promote products derived from this software 37 | without specific prior written permission. 38 | 39 | This software is provided by the copyright holders and contributors "as is" and 40 | any express or implied warranties, including, but not limited to, the implied 41 | warranties of merchantability and fitness for a particular purpose are disclaimed. 42 | In no event shall copyright holders or contributors be liable for any direct, 43 | indirect, incidental, special, exemplary, or consequential damages 44 | (including, but not limited to, procurement of substitute goods or services; 45 | loss of use, data, or profits; or business interruption) however caused 46 | and on any theory of liability, whether in contract, strict liability, 47 | or tort (including negligence or otherwise) arising in any way out of 48 | the use of this software, even if advised of the possibility of such damage. 49 | 50 | //////////////////////////////////////////////////////////////////////////////////// 51 | 52 | /// LIBSVM 53 | 54 | Copyright (c) 2000-2014 Chih-Chung Chang and Chih-Jen Lin 55 | All rights reserved. 56 | 57 | Redistribution and use in source and binary forms, with or without 58 | modification, are permitted provided that the following conditions 59 | are met: 60 | 61 | 1. Redistributions of source code must retain the above copyright 62 | notice, this list of conditions and the following disclaimer. 63 | 64 | 2. Redistributions in binary form must reproduce the above copyright 65 | notice, this list of conditions and the following disclaimer in the 66 | documentation and/or other materials provided with the distribution. 67 | 68 | 3. Neither name of copyright holders nor the names of its contributors 69 | may be used to endorse or promote products derived from this software 70 | without specific prior written permission. 71 | 72 | 73 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 74 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 75 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 76 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 77 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 78 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 79 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 80 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 81 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 82 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 83 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 84 | 85 | //////////////////////////////////////////////////////////////////////////////////// 86 | 87 | /// TensorFlow 88 | 89 | Copyright 2015 The TensorFlow Authors. All rights reserved. 90 | 91 | Apache License 92 | Version 2.0, January 2004 93 | http://www.apache.org/licenses/ 94 | 95 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 96 | 97 | 1. Definitions. 98 | 99 | "License" shall mean the terms and conditions for use, reproduction, 100 | and distribution as defined by Sections 1 through 9 of this document. 101 | 102 | "Licensor" shall mean the copyright owner or entity authorized by 103 | the copyright owner that is granting the License. 104 | 105 | "Legal Entity" shall mean the union of the acting entity and all 106 | other entities that control, are controlled by, or are under common 107 | control with that entity. For the purposes of this definition, 108 | "control" means (i) the power, direct or indirect, to cause the 109 | direction or management of such entity, whether by contract or 110 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 111 | outstanding shares, or (iii) beneficial ownership of such entity. 112 | 113 | "You" (or "Your") shall mean an individual or Legal Entity 114 | exercising permissions granted by this License. 115 | 116 | "Source" form shall mean the preferred form for making modifications, 117 | including but not limited to software source code, documentation 118 | source, and configuration files. 119 | 120 | "Object" form shall mean any form resulting from mechanical 121 | transformation or translation of a Source form, including but 122 | not limited to compiled object code, generated documentation, 123 | and conversions to other media types. 124 | 125 | "Work" shall mean the work of authorship, whether in Source or 126 | Object form, made available under the License, as indicated by a 127 | copyright notice that is included in or attached to the work 128 | (an example is provided in the Appendix below). 129 | 130 | "Derivative Works" shall mean any work, whether in Source or Object 131 | form, that is based on (or derived from) the Work and for which the 132 | editorial revisions, annotations, elaborations, or other modifications 133 | represent, as a whole, an original work of authorship. For the purposes 134 | of this License, Derivative Works shall not include works that remain 135 | separable from, or merely link (or bind by name) to the interfaces of, 136 | the Work and Derivative Works thereof. 137 | 138 | "Contribution" shall mean any work of authorship, including 139 | the original version of the Work and any modifications or additions 140 | to that Work or Derivative Works thereof, that is intentionally 141 | submitted to Licensor for inclusion in the Work by the copyright owner 142 | or by an individual or Legal Entity authorized to submit on behalf of 143 | the copyright owner. For the purposes of this definition, "submitted" 144 | means any form of electronic, verbal, or written communication sent 145 | to the Licensor or its representatives, including but not limited to 146 | communication on electronic mailing lists, source code control systems, 147 | and issue tracking systems that are managed by, or on behalf of, the 148 | Licensor for the purpose of discussing and improving the Work, but 149 | excluding communication that is conspicuously marked or otherwise 150 | designated in writing by the copyright owner as "Not a Contribution." 151 | 152 | "Contributor" shall mean Licensor and any individual or Legal Entity 153 | on behalf of whom a Contribution has been received by Licensor and 154 | subsequently incorporated within the Work. 155 | 156 | 2. Grant of Copyright License. Subject to the terms and conditions of 157 | this License, each Contributor hereby grants to You a perpetual, 158 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 159 | copyright license to reproduce, prepare Derivative Works of, 160 | publicly display, publicly perform, sublicense, and distribute the 161 | Work and such Derivative Works in Source or Object form. 162 | 163 | 3. Grant of Patent License. Subject to the terms and conditions of 164 | this License, each Contributor hereby grants to You a perpetual, 165 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 166 | (except as stated in this section) patent license to make, have made, 167 | use, offer to sell, sell, import, and otherwise transfer the Work, 168 | where such license applies only to those patent claims licensable 169 | by such Contributor that are necessarily infringed by their 170 | Contribution(s) alone or by combination of their Contribution(s) 171 | with the Work to which such Contribution(s) was submitted. If You 172 | institute patent litigation against any entity (including a 173 | cross-claim or counterclaim in a lawsuit) alleging that the Work 174 | or a Contribution incorporated within the Work constitutes direct 175 | or contributory patent infringement, then any patent licenses 176 | granted to You under this License for that Work shall terminate 177 | as of the date such litigation is filed. 178 | 179 | 4. Redistribution. You may reproduce and distribute copies of the 180 | Work or Derivative Works thereof in any medium, with or without 181 | modifications, and in Source or Object form, provided that You 182 | meet the following conditions: 183 | 184 | (a) You must give any other recipients of the Work or 185 | Derivative Works a copy of this License; and 186 | 187 | (b) You must cause any modified files to carry prominent notices 188 | stating that You changed the files; and 189 | 190 | (c) You must retain, in the Source form of any Derivative Works 191 | that You distribute, all copyright, patent, trademark, and 192 | attribution notices from the Source form of the Work, 193 | excluding those notices that do not pertain to any part of 194 | the Derivative Works; and 195 | 196 | (d) If the Work includes a "NOTICE" text file as part of its 197 | distribution, then any Derivative Works that You distribute must 198 | include a readable copy of the attribution notices contained 199 | within such NOTICE file, excluding those notices that do not 200 | pertain to any part of the Derivative Works, in at least one 201 | of the following places: within a NOTICE text file distributed 202 | as part of the Derivative Works; within the Source form or 203 | documentation, if provided along with the Derivative Works; or, 204 | within a display generated by the Derivative Works, if and 205 | wherever such third-party notices normally appear. The contents 206 | of the NOTICE file are for informational purposes only and 207 | do not modify the License. You may add Your own attribution 208 | notices within Derivative Works that You distribute, alongside 209 | or as an addendum to the NOTICE text from the Work, provided 210 | that such additional attribution notices cannot be construed 211 | as modifying the License. 212 | 213 | You may add Your own copyright statement to Your modifications and 214 | may provide additional or different license terms and conditions 215 | for use, reproduction, or distribution of Your modifications, or 216 | for any such Derivative Works as a whole, provided Your use, 217 | reproduction, and distribution of the Work otherwise complies with 218 | the conditions stated in this License. 219 | 220 | 5. Submission of Contributions. Unless You explicitly state otherwise, 221 | any Contribution intentionally submitted for inclusion in the Work 222 | by You to the Licensor shall be under the terms and conditions of 223 | this License, without any additional terms or conditions. 224 | Notwithstanding the above, nothing herein shall supersede or modify 225 | the terms of any separate license agreement you may have executed 226 | with Licensor regarding such Contributions. 227 | 228 | 6. Trademarks. This License does not grant permission to use the trade 229 | names, trademarks, service marks, or product names of the Licensor, 230 | except as required for reasonable and customary use in describing the 231 | origin of the Work and reproducing the content of the NOTICE file. 232 | 233 | 7. Disclaimer of Warranty. Unless required by applicable law or 234 | agreed to in writing, Licensor provides the Work (and each 235 | Contributor provides its Contributions) on an "AS IS" BASIS, 236 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 237 | implied, including, without limitation, any warranties or conditions 238 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 239 | PARTICULAR PURPOSE. You are solely responsible for determining the 240 | appropriateness of using or redistributing the Work and assume any 241 | risks associated with Your exercise of permissions under this License. 242 | 243 | 8. Limitation of Liability. In no event and under no legal theory, 244 | whether in tort (including negligence), contract, or otherwise, 245 | unless required by applicable law (such as deliberate and grossly 246 | negligent acts) or agreed to in writing, shall any Contributor be 247 | liable to You for damages, including any direct, indirect, special, 248 | incidental, or consequential damages of any character arising as a 249 | result of this License or out of the use or inability to use the 250 | Work (including but not limited to damages for loss of goodwill, 251 | work stoppage, computer failure or malfunction, or any and all 252 | other commercial damages or losses), even if such Contributor 253 | has been advised of the possibility of such damages. 254 | 255 | 9. Accepting Warranty or Additional Liability. While redistributing 256 | the Work or Derivative Works thereof, You may choose to offer, 257 | and charge a fee for, acceptance of support, warranty, indemnity, 258 | or other liability obligations and/or rights consistent with this 259 | License. However, in accepting such obligations, You may act only 260 | on Your own behalf and on Your sole responsibility, not on behalf 261 | of any other Contributor, and only if You agree to indemnify, 262 | defend, and hold each Contributor harmless for any liability 263 | incurred by, or claims asserted against, such Contributor by reason 264 | of your accepting any such warranty or additional liability. 265 | 266 | END OF TERMS AND CONDITIONS 267 | 268 | APPENDIX: How to apply the Apache License to your work. 269 | 270 | To apply the Apache License to your work, attach the following 271 | boilerplate notice, with the fields enclosed by brackets "[]" 272 | replaced with your own identifying information. (Don't include 273 | the brackets!) The text should be enclosed in the appropriate 274 | comment syntax for the file format. We also recommend that a 275 | file or class name and description of purpose be included on the 276 | same "printed page" as the copyright notice for easier 277 | identification within third-party archives. 278 | 279 | Copyright 2015, The TensorFlow Authors. 280 | 281 | Licensed under the Apache License, Version 2.0 (the "License"); 282 | you may not use this file except in compliance with the License. 283 | You may obtain a copy of the License at 284 | 285 | http://www.apache.org/licenses/LICENSE-2.0 286 | 287 | Unless required by applicable law or agreed to in writing, software 288 | distributed under the License is distributed on an "AS IS" BASIS, 289 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 290 | See the License for the specific language governing permissions and 291 | limitations under the License. 292 | 293 | //////////////////////////////////////////////////////////////////////////////////// 294 | 295 | /// Caffe 296 | 297 | COPYRIGHT 298 | 299 | All contributions by the University of California: 300 | Copyright (c) 2014, 2015, The Regents of the University of California (Regents) 301 | All rights reserved. 302 | 303 | All other contributions: 304 | Copyright (c) 2014, 2015, the respective contributors 305 | All rights reserved. 306 | 307 | Caffe uses a shared copyright model: each contributor holds copyright over 308 | their contributions to Caffe. The project versioning records all such 309 | contribution and copyright details. If a contributor wants to further mark 310 | their specific copyright on a particular contribution, they should indicate 311 | their copyright solely in the commit message of the change when it is 312 | committed. 313 | 314 | LICENSE 315 | 316 | Redistribution and use in source and binary forms, with or without 317 | modification, are permitted provided that the following conditions are met: 318 | 319 | 1. Redistributions of source code must retain the above copyright notice, this 320 | list of conditions and the following disclaimer. 321 | 2. Redistributions in binary form must reproduce the above copyright notice, 322 | this list of conditions and the following disclaimer in the documentation 323 | and/or other materials provided with the distribution. 324 | 325 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 326 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 327 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 328 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 329 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 330 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 331 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 332 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 333 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 334 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 335 | 336 | CONTRIBUTION AGREEMENT 337 | 338 | By contributing to the BVLC/caffe repository through pull-request, comment, 339 | or otherwise, the contributor releases their content to the 340 | license and copyright terms herein. 341 | 342 | //////////////////////////////////////////////////////////////////////////////////// 343 | 344 | /// caffe-android-lib 345 | 346 | Copyright (c) 2015, Shiro Bai 347 | All rights reserved. 348 | 349 | Redistribution and use in source and binary forms, with or without 350 | modification, are permitted provided that the following conditions are met: 351 | 352 | 1. Redistributions of source code must retain the above copyright notice, this 353 | list of conditions and the following disclaimer. 354 | 2. Redistributions in binary form must reproduce the above copyright notice, 355 | this list of conditions and the following disclaimer in the documentation 356 | and/or other materials provided with the distribution. 357 | 358 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 359 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 360 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 361 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 362 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 363 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 364 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 365 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 366 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 367 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 368 | 369 | The views and conclusions contained in the software and documentation are those 370 | of the authors and should not be interpreted as representing official policies, 371 | either expressed or implied, of the FreeBSD Project. 372 | 373 | //////////////////////////////////////////////////////////////////////////////////// 374 | 375 | /// caffe-android-demo 376 | 377 | The MIT License (MIT) 378 | 379 | Copyright (c) 2014 sh1r0 380 | 381 | Permission is hereby granted, free of charge, to any person obtaining a copy 382 | of this software and associated documentation files (the "Software"), to deal 383 | in the Software without restriction, including without limitation the rights 384 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 385 | copies of the Software, and to permit persons to whom the Software is 386 | furnished to do so, subject to the following conditions: 387 | 388 | The above copyright notice and this permission notice shall be included in all 389 | copies or substantial portions of the Software. 390 | 391 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 392 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 393 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 394 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 395 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 396 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 397 | SOFTWARE. 398 | 399 | //////////////////////////////////////////////////////////////////////////////////// 400 | 401 | /// Facenet 402 | 403 | MIT License 404 | 405 | Copyright (c) 2016 David Sandberg 406 | 407 | Permission is hereby granted, free of charge, to any person obtaining a copy 408 | of this software and associated documentation files (the "Software"), to deal 409 | in the Software without restriction, including without limitation the rights 410 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 411 | copies of the Software, and to permit persons to whom the Software is 412 | furnished to do so, subject to the following conditions: 413 | 414 | The above copyright notice and this permission notice shall be included in all 415 | copies or substantial portions of the Software. 416 | 417 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 418 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 419 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 420 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 421 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 422 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 423 | SOFTWARE. 424 | -------------------------------------------------------------------------------- /POLICY.md: -------------------------------------------------------------------------------- 1 | # PRIVACY POLICY MODEL FOR MOBILE APPLICATIONS 2 | This privacy policy governs your use of the software application “Face Recognition” for mobile devices that was created by Michael Sladoje and Mike Schälchli. The Application is used as a framework for Android devices to test different face recognition methods. 3 | ## What information does the Application obtain and how is it used? 4 | None 5 | ## Does the Application collect precise real time location information of the device? 6 | No 7 | ## Do third parties see and/or have access to information obtained by the Application? 8 | No 9 | ## Contact us 10 | If you have any questions regarding privacy while using the Application, or have questions about our practices, please contact us via email at qualeams@gmail.com. 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android Face Recognition with Deep Learning - Test Framework 2 | ## Continuous integration 3 | [![Build Status](https://travis-ci.org/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework.svg)](https://travis-ci.org/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework) 4 | ## Acknowledgements 5 | This app was developed by Michael Sladoje and Mike Schälchli during a bachelor thesis at the Zurich University of Applied Sciences. 6 | 7 | Acknowledgements go to the thesis supervisors Dr. Martin Loeser, Dr. Oliver Dürr, Diego Browarnik and all the contributors of our code sources. 8 | 9 | Code has been derived from the following sources: 10 | - OpenCV - https://github.com/opencv/opencv 11 | - LIBSVM - https://github.com/cjlin1/libsvm 12 | - AndroidLibSvm - https://github.com/yctung/AndroidLibSvm 13 | - TensorFlow - https://github.com/tensorflow/tensorflow 14 | - facenet - https://github.com/davidsandberg/facenet/pull/240 15 | - Caffe - https://github.com/BVLC/caffe 16 | - caffe-android-demo - https://github.com/sh1r0/caffe-android-demo 17 | - caffe-android-lib - https://github.com/sh1r0/caffe-android-lib 18 | 19 | ## Library 20 | The core functions have been moved to a [separate repository](https://github.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Library.git) which can be used as an Android library (module). 21 | 22 | ## App architecture 23 | ![alt tag](https://github.com/Qualeams/Android-Face-Recognition-with-Deep-Learning/blob/master/AppArchitecture.png) 24 | 25 | ## Usage 26 | ### Clone 27 | ``` 28 | git clone https://github.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework.git 29 | ``` 30 | 31 | ### Compilation 32 | #### APK - Package 33 | The app can be downloaded directly from the Google Play Store - [Face Recognition](https://play.google.com/store/apps/details?id=ch.zhaw.facerecognition). 34 | #### Android SDK - Java 35 | The source can be compiled using Android Studio (common gradle scripts). 36 | 37 | ### User manual 38 | The user manual can be found [here](https://github.com/Qualeams/Android-Face-Recognition-with-Deep-Learning/blob/master/USER%20MANUAL.md) 39 | -------------------------------------------------------------------------------- /USER MANUAL.md: -------------------------------------------------------------------------------- 1 | # User manual 2 | 3 | ## Table of contents 4 | 1. [Introduction](#introduction) 5 | 2. [Test results](#testresults) 6 | 3. [Manual for using the app](#manualfor) 7 | 4. [Settings](#settings) 8 | 5. [Add Person](#addperson) 9 | 6. [Training](#training1) 10 | 7. [Test](#test1) 11 | 8. [Recognition](#recognition1) 12 | 13 | ## Introduction 14 | 15 | Face Recognition can be used as a test framework for several face recognition methods including the Neural Networks with TensorFlow and Caffe. 16 | It includes following preprocessing algorithms: 17 | - Grayscale 18 | - Crop 19 | - Eye Alignment 20 | - Gamma Correction 21 | - Difference of Gaussians 22 | - Canny-Filter 23 | - Local Binary Pattern 24 | - Histogramm Equalization (can only be used if grayscale is used too) 25 | - Resize 26 | 27 | You can choose from the following feature extraction and classification methods: 28 | - Eigenfaces with Nearest Neighbour 29 | - Image Reshaping with Support Vector Machine 30 | - TensorFlow with SVM or KNN 31 | - Caffe with SVM or KNN 32 | 33 | ## Test results 34 | Results of a test with 6 persons (100 training and 100 test pictures for each person): 35 | 36 | | **Accuracy** | **Performance** 37 | --- | --- | --- 38 | **Eigenfaces with NN** | 85.29 % | 0.46 s / image 39 | **Image Reshaping with SVM** | 95.29 % | 0.58 s / image 40 | **TensorFlow Inception model with SVM** | 88.57 % | 2.35 s / image 41 | **TensorFlow VGG Face Descriptor model with SVM** | 100 % | 6.27 s / image 42 | 43 | ## Manual for using the app 44 | 45 | ### Requirements on the Android device 46 | - Android 5.0 or higher 47 | - armeabi-v7a CPU architecture and higher 48 | - For best experience in recognition mode rotate the device to left. 49 | 50 | ### Quick Start 51 | #### Add Person 52 | Add at least 2 persons by using the "Add Person" function (at least 10 images per person). 53 | 54 | #### Training 55 | Train the classifier with the images captured before. 56 | 57 | #### Recognition 58 | Use the recognition function to classify/identify multiple persons in the camera preview. 59 | 60 | ### Deep learning with Convolutional Neural Networks 61 | #### TensorFlow 62 | ##### Inception5h model 63 | If you want to use the Tensorflow Inception5h model, download it from here: 64 | https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip 65 | 66 | Then copy the file "tensorflow_inception_graph.pb" to "/sdcard/Pictures/facerecognition/data/TensorFlow" 67 | 68 | Use these default settings for a start: 69 | Number of classes: 1001 (not relevant as we don't use the last layer) 70 | Input Size: 224 71 | Image mean: 128 72 | Output size: 1024 73 | Input layer: input 74 | Output layer: avgpool0 75 | Model file: tensorflow_inception_graph.pb 76 | 77 | ##### VGG Face Descriptor model 78 | If you want to use the VGG Face Descriptor model, download it from here: 79 | https://drive.google.com/file/d/0B9SVRVIKcFzAdm9rQ3JBOC16dkE/view?usp=sharing 80 | 81 | Caution: This model runs only on devices with at least 3 GB or RAM. 82 | 83 | Then copy the file "vgg_faces.pb" to "/sdcard/Pictures/facerecognition/data/TensorFlow" 84 | 85 | Use these default settings for a start: 86 | Number of classes: 1000 (not relevant as we don't use the last layer) 87 | Input Size: 224 88 | Image mean: 128 89 | Output size: 4096 90 | Input layer: Placeholder 91 | Output layer: fc7/fc7 92 | Model file: vgg_faces.pb 93 | 94 | #### Caffe 95 | ##### VGG Face Descriptor model 96 | If you want to use the VGG Face Descriptor model, download it from here: 97 | http://www.robots.ox.ac.uk/~vgg/software/vgg_face/src/vgg_face_caffe.tar.gz 98 | 99 | Caution: This model runs only on devices with at least 3 GB or RAM. 100 | 101 | Then copy the files "VGG_FACE_deploy.prototxt" and "VGG_FACE.caffemodel" to "/sdcard/Pictures/facerecognition/data/caffe" 102 | 103 | Use these default settings for a start: 104 | Mean values: 104, 117, 123 105 | Output layer: fc7 106 | Model file: VGG_FACE_deploy.prototxt 107 | Weights file: VGG_FACE.caffemodel 108 | 109 | ## Settings 110 | 111 | ### General 112 | #### Camera 113 | Choose between front and back camera 114 | #### Default Settings 115 | Reset all settings to default 116 | 117 | ### Add Person 118 | #### Number of pictures 119 | Only relevant if "TIME" is selected in "Add Person". The capturing will stop after this amount of pictures. 120 | #### Time between photos (in ms) 121 | Only relevant if "TIME" is selected in "Add Person". The capturing will wait with taking the next picture at least that long. 122 | 123 | ### Preprocessing 124 | The preprocessings will be carried out in the following order 125 | 126 | 1. Standard Preprocessing 127 | 2. Brightness Correction 128 | 3. Contours 129 | 4. Contrast Adjustment 130 | 5. Standard Postprocessing 131 | 132 | #### Standard Preprocessing 133 | The standard preprocessings will be carried out in the following order if selected 134 | 135 | 1. Grayscale 136 | 2. Crop (should always be used as it reduces noise by cropping the image to include the face only) 137 | 3. Eye Alignment 138 | 139 | #### Contours 140 | If you use these preprocessings it's best to use only one of them at once. The order is again given by the numbers. 141 | 142 | #### Contrast Adjustment 143 | The Histogramm Equalization can only be used if the image is in grayscale (therefore if the preprocessing grayscale has been used before). 144 | 145 | #### Standard Postprocessing 146 | Resize should always be used as it improves the performance by shrinking the image. 147 | 148 | #### gamma (Gamma Correction) 149 | This is the parameter gamma for the Gamma Correction (if preprocessing is selected). 150 | 151 | #### sigmas (comma separated - Difference of Gaussians) 152 | These are the parameteres sigma1 and sigma2 for the Difference of Gaussians filter (if preprocessing is selected) which need to be separated by commas (e.g. 0.25, 4) 153 | 154 | #### N (Resize to N x N) 155 | This is the size in pixels (N x N) for resizing the image (if preprocessing is selected). 156 | 157 | ### Algorithms General 158 | #### Feature extraction and classification method 159 | #### Eigenfaces with NN 160 | This is the classical Eigenfaces algorithm. Currently the implementation for storing and loading data is bad. So it will need a while (depending on how many pictures you have) to store the training data. Also the loading will take a while each time you use it. But once loaded, the Eigenfaces algorithm is the fastest (until you reach a critical limit of pictures of a few thousand, then the Image Reshaping with SVM performs better). 161 | 162 | ##### Image Reshaping with SVM 163 | This is the classical approach by reshaping the image to a vector which is used as a feature vector for the Support Vector Machine. This method has the best performance with many images and also a quiet good accuracy. 164 | 165 | #### TensorFlow with SVM or KNN 166 | Here you can use a Convolutional Neural Network (CNN) (TensorFlow model) to extract the feature vectors which are then used by the K-Nearest Neighbor or Support Vector Machine classifiers. The performance is very bad though as mobile devices can't use the GPU for the calculations at the moment. 167 | 168 | ##### Caffe with SVM or KNN 169 | The same as with TensorFlow but just using a Caffe model instead. The performance is worse as with TensorFlow (in the tests with the VGG Face Descriptor model it was twice as slow). 170 | 171 | #### Classification method for TensorFlow and Caffe 172 | Here you can choose the classifier if you selected TensorFlow or Caffe. 173 | 174 | #### K (Number of Nearest Neighbor) 175 | The parameter k for the K-Nearest Neighbor classifier (if K-Nearest Neighbor has been selected before). 176 | 177 | #### PCA Threshold (Eigenfaces) 178 | The threshold for the Eigenfaces algorithm (if Eigenfaces has been selected before). It determines how many eigenvectors are used based on the Principal Component Analysis. 179 | 180 | #### Train Options (LIBSVM) 181 | You can use different train options available in LIBSVM (if SVM has been selected before). The default is a linear kernel (-t 0) as the images have enough dimensions to give a good accuracy. 182 | 183 | ### TensorFlow 184 | #### Number of classes 185 | Number of classes the model has been trained on. 186 | 187 | #### Input Size 188 | The input size for the CNN. The image will be resized to this size before entering the CNN. You can still use a smaller size in preprocessing to improve performance but will loose information. 189 | 190 | #### Image mean 191 | The image mean for the specific model you use. It is used to normalize the image before entering the CNN. 192 | 193 | #### Output size 194 | The output size of the output layer you use. 195 | 196 | #### Input layer 197 | The input layer of the model you want to use. 198 | 199 | #### Output layer 200 | The output layer of the model you want to use. As TensorFlow isn't used as a classifier but as a feature extractor you shouldn't use the last layer but for example the last pooling layer. 201 | 202 | #### Model file 203 | Name of the model file you want to use. You need to copy the file to "/sdcard/Pictures/facerecognition/data/TensorFlow". 204 | 205 | ### Caffe 206 | #### Mean values (comma separated) 207 | The mean values you want to use for normalization. You need to enter them comma separated (e.g. 104, 117, 123). 208 | 209 | #### Output layer 210 | The output layer of the model you want to use. As Caffe isn't used as a classifiert but as a feature extractor you shouldn't use the last layer but for example the fc7 layer. 211 | 212 | #### Model file 213 | Name of the model file you want to use. You need to copy the file to "/sdcard/Pictures/facerecognition/data/caffe". 214 | 215 | #### Weight file 216 | Name of the weights file you want to use. You need to copy the file to "/sdcard/Pictures/facerecognition/data/caffe". 217 | 218 | ## Add Person 219 | You can either add persons by copying selfies (only one person per image) to "/sdcard/Pictures/facerecognition/training/NAMEOFTHEPERSON" or "/sdcard/Pictures/facerecognition/test/reference/NAMEOFTHEPERSON" or "/sdcard/Pictures/facerecognition/test/deviation/NAMEOFTHEPERSON". 220 | 221 | However it's recommended to use the built in "Add Person" function since it saves only pictures where a face was detected and crops the image accordingly. You can also copy these files to your computer for later reusability and when needed copy them back to the device. 222 | ### Name 223 | Each name represents a class. If you want to use the test function, you need to use the exact same name for the same person in training and test. 224 | 225 | ### Training / Test 226 | Switch between capturing for the training or test function. 227 | 228 | ### Reference / Deviation 229 | This is only needed if you capture images for the test function. Normally you just take a batch of pictures for testing (reference). But if you want to test some specific deviations (e.g. bad light conditions), then you can capture this specific test set in the deviation folder which will be compared to the reference folder. 230 | 231 | ### Time / Manually 232 | Time means that the capturing will be carried out automatically according to the settings you have set. If you want to capture the images manually you can do this and decide by yourself when to press the button and when to stop the capturing (by hitting the back button). 233 | 234 | ### Start 235 | Start capturing 236 | 237 | ## Training 238 | Executes the training for the images saved under "/sdcard/Pictures/facerecognition/training" with the algorithms defined in the settings. Saves the training data in the classifier folders (either Eigenfaces, SVM or KNN). 239 | 240 | ## Test 241 | Executes the test for the images saved under "/sdcard/Pictures/facerecognition/test" with the algorithms defined in the settings. Shows the accuracy after completion and saves the results under "/sdcard/Pictures/facerecognition/results". The feature vectors are also saved in the classifier folders like the training data for evaluation purposes (e.g. t-SNE visualization). 242 | 243 | ## Recognition 244 | Live recognition of multiple persons at once. Uses the trained data of the algorithms defined in the settings. 245 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | *.iml 3 | -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'net.saliman.cobertura' 3 | 4 | android { 5 | compileSdkVersion 23 6 | buildToolsVersion "23.0.1" 7 | 8 | defaultConfig { 9 | applicationId "ch.zhaw.facerecognition" 10 | minSdkVersion 21 11 | targetSdkVersion 21 12 | versionCode 28 13 | versionName "1.5.3" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | 22 | lintOptions { 23 | abortOnError false 24 | } 25 | } 26 | 27 | cobertura { 28 | coverageFormats = [ 'html', 'xml' ] 29 | } 30 | 31 | buildscript { 32 | repositories { 33 | jcenter() 34 | mavenCentral() 35 | maven { 36 | url "https://oss.sonatype.org/content/repositories/snapshots" 37 | } 38 | } 39 | dependencies { 40 | classpath 'net.saliman:gradle-cobertura-plugin:2.4.0' 41 | } 42 | } 43 | 44 | dependencies { 45 | compile fileTree(include: ['*.jar'], dir: 'libs') 46 | testCompile 'junit:junit:4.12' 47 | compile 'com.android.support:appcompat-v7:23.3.0' 48 | compile 'com.android.support:support-v4:23.3.0' 49 | compile 'ch.zhaw:facerecognitionlibrary:1.5.3' 50 | } 51 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\Michael\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/ch/zhaw/facerecognition/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | /* Copyright 2016 The Android Open Source Project 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | ==============================================================================*/ 15 | 16 | package ch.zhaw.facerecognition; 17 | 18 | import android.app.Application; 19 | import android.test.ApplicationTestCase; 20 | 21 | public class ApplicationTest extends ApplicationTestCase { 22 | public ApplicationTest() { 23 | super(Application.class); 24 | } 25 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 16 | 18 | 19 | 20 | 21 | 24 | 27 | 30 | 33 | 34 | 40 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 67 | 68 | 69 | 73 | 74 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /app/src/main/java/ch/zhaw/facerecognition/Activities/AddPersonActivity.java: -------------------------------------------------------------------------------- 1 | /* Copyright 2016 Michael Sladoje and Mike Schälchli. All Rights Reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | ==============================================================================*/ 15 | 16 | package ch.zhaw.facerecognition.Activities; 17 | 18 | import android.app.Activity; 19 | import android.content.Intent; 20 | import android.os.Bundle; 21 | import android.view.View; 22 | import android.widget.Button; 23 | import android.widget.EditText; 24 | import android.widget.Toast; 25 | import android.widget.ToggleButton; 26 | 27 | import java.io.File; 28 | 29 | import ch.zhaw.facerecognitionlibrary.Helpers.FileHelper; 30 | import ch.zhaw.facerecognition.R; 31 | 32 | public class AddPersonActivity extends Activity { 33 | 34 | @Override 35 | protected void onCreate(Bundle savedInstanceState) { 36 | super.onCreate(savedInstanceState); 37 | setContentView(R.layout.activity_add_person); 38 | 39 | final ToggleButton btnTrainingTest = (ToggleButton)findViewById(R.id.btnTrainingTest); 40 | final ToggleButton btnReferenceDeviation = (ToggleButton)findViewById(R.id.btnReferenceDeviation); 41 | final ToggleButton btnTimeManually = (ToggleButton)findViewById(R.id.btnTimeManually); 42 | btnTrainingTest.setOnClickListener(new View.OnClickListener() { 43 | @Override 44 | public void onClick(View v) { 45 | if(btnTrainingTest.isChecked()){ 46 | btnReferenceDeviation.setEnabled(true); 47 | } else { 48 | btnReferenceDeviation.setEnabled(false); 49 | } 50 | } 51 | }); 52 | 53 | Button btn_Start = (Button)findViewById(R.id.btn_Start); 54 | btn_Start.setOnClickListener(new View.OnClickListener() { 55 | @Override 56 | public void onClick(View v) { 57 | EditText txt_Name = (EditText)findViewById(R.id.txt_Name); 58 | String name = txt_Name.getText().toString(); 59 | Intent intent = new Intent(v.getContext(), AddPersonPreviewActivity.class); 60 | intent.putExtra("Name", name); 61 | intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 62 | 63 | if(btnTimeManually.isChecked()){ 64 | intent.putExtra("Method", AddPersonPreviewActivity.MANUALLY); 65 | } else { 66 | intent.putExtra("Method", AddPersonPreviewActivity.TIME); 67 | } 68 | 69 | if(btnTrainingTest.isChecked()){ 70 | // Add photos to "Test" folder 71 | if(isNameAlreadyUsed(new FileHelper().getTestList(), name)){ 72 | Toast.makeText(getApplicationContext(), "This name is already used. Please choose another one.", Toast.LENGTH_SHORT).show(); 73 | } else { 74 | intent.putExtra("Folder", "Test"); 75 | if(btnReferenceDeviation.isChecked()){ 76 | intent.putExtra("Subfolder", "deviation"); 77 | } else { 78 | intent.putExtra("Subfolder", "reference"); 79 | } 80 | startActivity(intent); 81 | } 82 | } else { 83 | // Add photos to "Training" folder 84 | 85 | if(isNameAlreadyUsed(new FileHelper().getTrainingList(), name)){ 86 | Toast.makeText(getApplicationContext(), "This name is already used. Please choose another one.", Toast.LENGTH_SHORT).show(); 87 | } else { 88 | intent.putExtra("Folder", "Training"); 89 | startActivity(intent); 90 | } 91 | } 92 | } 93 | }); 94 | } 95 | 96 | private boolean isNameAlreadyUsed(File[] list, String name){ 97 | boolean used = false; 98 | if(list != null && list.length > 0){ 99 | for(File person : list){ 100 | // The last token is the name --> Folder name = Person name 101 | String[] tokens = person.getAbsolutePath().split("/"); 102 | final String foldername = tokens[tokens.length-1]; 103 | if(foldername.equals(name)){ 104 | used = true; 105 | break; 106 | } 107 | } 108 | } 109 | return used; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /app/src/main/java/ch/zhaw/facerecognition/Activities/AddPersonPreviewActivity.java: -------------------------------------------------------------------------------- 1 | /* Copyright 2016 Michael Sladoje and Mike Schälchli. All Rights Reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | ==============================================================================*/ 15 | 16 | package ch.zhaw.facerecognition.Activities; 17 | 18 | import android.app.Activity; 19 | import android.content.Intent; 20 | import android.content.SharedPreferences; 21 | import android.preference.PreferenceManager; 22 | import android.os.Bundle; 23 | import android.view.SurfaceView; 24 | import android.view.View; 25 | import android.widget.ImageButton; 26 | 27 | import org.opencv.android.CameraBridgeViewBase; 28 | import org.opencv.android.OpenCVLoader; 29 | import org.opencv.core.Core; 30 | import org.opencv.core.Mat; 31 | import org.opencv.core.Rect; 32 | 33 | import java.io.File; 34 | import java.util.Date; 35 | import java.util.List; 36 | 37 | import ch.zhaw.facerecognitionlibrary.Helpers.CustomCameraView; 38 | import ch.zhaw.facerecognitionlibrary.Helpers.FileHelper; 39 | import ch.zhaw.facerecognitionlibrary.Helpers.MatName; 40 | import ch.zhaw.facerecognitionlibrary.Helpers.MatOperation; 41 | import ch.zhaw.facerecognitionlibrary.PreProcessor.PreProcessorFactory; 42 | import ch.zhaw.facerecognition.R; 43 | 44 | public class AddPersonPreviewActivity extends Activity implements CameraBridgeViewBase.CvCameraViewListener2 { 45 | public static final int TIME = 0; 46 | public static final int MANUALLY = 1; 47 | private CustomCameraView mAddPersonView; 48 | // The timerDiff defines after how many milliseconds a picture is taken 49 | private long timerDiff; 50 | private long lastTime; 51 | private PreProcessorFactory ppF; 52 | private FileHelper fh; 53 | private String folder; 54 | private String subfolder; 55 | private String name; 56 | private int total; 57 | private int numberOfPictures; 58 | private int method; 59 | private ImageButton btn_Capture; 60 | private boolean capturePressed; 61 | private boolean front_camera; 62 | private boolean night_portrait; 63 | private int exposure_compensation; 64 | 65 | static { 66 | if (!OpenCVLoader.initDebug()) { 67 | // Handle initialization error 68 | } 69 | } 70 | 71 | @Override 72 | protected void onCreate(Bundle savedInstanceState) { 73 | super.onCreate(savedInstanceState); 74 | setContentView(R.layout.activity_add_person_preview); 75 | 76 | Intent intent = getIntent(); 77 | folder = intent.getStringExtra("Folder"); 78 | if(folder.equals("Test")){ 79 | subfolder = intent.getStringExtra("Subfolder"); 80 | } 81 | name = intent.getStringExtra("Name"); 82 | method = intent.getIntExtra("Method", 0); 83 | capturePressed = false; 84 | if(method == MANUALLY){ 85 | btn_Capture = (ImageButton)findViewById(R.id.btn_Capture); 86 | btn_Capture.setVisibility(View.VISIBLE); 87 | btn_Capture.setOnClickListener(new View.OnClickListener() { 88 | @Override 89 | public void onClick(View v) { 90 | capturePressed = true; 91 | } 92 | }); 93 | } 94 | 95 | fh = new FileHelper(); 96 | total = 0; 97 | lastTime = new Date().getTime(); 98 | 99 | SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); 100 | timerDiff = Integer.valueOf(sharedPrefs.getString("key_timerDiff", "500")); 101 | 102 | mAddPersonView = (CustomCameraView) findViewById(R.id.AddPersonPreview); 103 | // Use camera which is selected in settings 104 | SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); 105 | front_camera = sharedPref.getBoolean("key_front_camera", true); 106 | 107 | numberOfPictures = Integer.valueOf(sharedPref.getString("key_numberOfPictures", "100")); 108 | 109 | night_portrait = sharedPref.getBoolean("key_night_portrait", false); 110 | exposure_compensation = Integer.valueOf(sharedPref.getString("key_exposure_compensation", "50")); 111 | 112 | if (front_camera){ 113 | mAddPersonView.setCameraIndex(CameraBridgeViewBase.CAMERA_ID_FRONT); 114 | } else { 115 | mAddPersonView.setCameraIndex(CameraBridgeViewBase.CAMERA_ID_BACK); 116 | } 117 | mAddPersonView.setVisibility(SurfaceView.VISIBLE); 118 | mAddPersonView.setCvCameraViewListener(this); 119 | 120 | int maxCameraViewWidth = Integer.parseInt(sharedPref.getString("key_maximum_camera_view_width", "640")); 121 | int maxCameraViewHeight = Integer.parseInt(sharedPref.getString("key_maximum_camera_view_height", "480")); 122 | mAddPersonView.setMaxFrameSize(maxCameraViewWidth, maxCameraViewHeight); 123 | } 124 | 125 | @Override 126 | public void onCameraViewStarted(int width, int height) { 127 | 128 | if (night_portrait) { 129 | mAddPersonView.setNightPortrait(); 130 | } 131 | 132 | if (exposure_compensation != 50 && 0 <= exposure_compensation && exposure_compensation <= 100) 133 | mAddPersonView.setExposure(exposure_compensation); 134 | } 135 | 136 | @Override 137 | public void onCameraViewStopped() { 138 | 139 | } 140 | 141 | @Override 142 | public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) { 143 | Mat imgRgba = inputFrame.rgba(); 144 | Mat imgCopy = new Mat(); 145 | imgRgba.copyTo(imgCopy); 146 | // Selfie / Mirror mode 147 | if(front_camera){ 148 | Core.flip(imgRgba,imgRgba,1); 149 | } 150 | 151 | long time = new Date().getTime(); 152 | if((method == MANUALLY) || (method == TIME) && (lastTime + timerDiff < time)){ 153 | lastTime = time; 154 | 155 | // Check that only 1 face is found. Skip if any or more than 1 are found. 156 | List images = ppF.getCroppedImage(imgCopy); 157 | if (images != null && images.size() == 1){ 158 | Mat img = images.get(0); 159 | if(img != null){ 160 | Rect[] faces = ppF.getFacesForRecognition(); 161 | //Only proceed if 1 face has been detected, ignore if 0 or more than 1 face have been detected 162 | if((faces != null) && (faces.length == 1)){ 163 | faces = MatOperation.rotateFaces(imgRgba, faces, ppF.getAngleForRecognition()); 164 | if(((method == MANUALLY) && capturePressed) || (method == TIME)){ 165 | MatName m = new MatName(name + "_" + total, img); 166 | if (folder.equals("Test")) { 167 | String wholeFolderPath = fh.TEST_PATH + name + "/" + subfolder; 168 | new File(wholeFolderPath).mkdirs(); 169 | fh.saveMatToImage(m, wholeFolderPath + "/"); 170 | } else { 171 | String wholeFolderPath = fh.TRAINING_PATH + name; 172 | new File(wholeFolderPath).mkdirs(); 173 | fh.saveMatToImage(m, wholeFolderPath + "/"); 174 | } 175 | 176 | for(int i = 0; i= numberOfPictures){ 184 | Intent intent = new Intent(getApplicationContext(), AddPersonActivity.class); 185 | intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 186 | startActivity(intent); 187 | } 188 | capturePressed = false; 189 | } else { 190 | for(int i = 0; i images = ppF.getCroppedImage(img); 84 | Rect[] faces = ppF.getFacesForRecognition(); 85 | 86 | // Selfie / Mirror mode 87 | if(front_camera){ 88 | Core.flip(imgRgba,imgRgba,1); 89 | } 90 | if(images == null || images.size() == 0 || faces == null || faces.length == 0 || ! (images.size() == faces.length)){ 91 | // skip 92 | return imgRgba; 93 | } else { 94 | faces = MatOperation.rotateFaces(imgRgba, faces, ppF.getAngleForRecognition()); 95 | for(int i = 0; i 0) { 63 | // total and matches are used to calculate the accuracy afterwards 64 | int total = 0; 65 | int matches = 0; 66 | List results = new ArrayList<>(); 67 | results.add("Expected Name;Expected File;Result"); 68 | Date time_start = new Date(); 69 | for (File folder : detectionFolders) { 70 | File[] files = folder.listFiles(); 71 | int counter = 1; 72 | for (File file : files) { 73 | if (FileHelper.isFileAnImage(file)) { 74 | Mat imgRgba = Imgcodecs.imread(file.getAbsolutePath()); 75 | Imgproc.cvtColor(imgRgba, imgRgba, Imgproc.COLOR_BGRA2RGBA); 76 | 77 | List images = ppF.getProcessedImage(imgRgba, PreProcessorFactory.PreprocessingMode.DETECTION); 78 | Rect[] faces = ppF.getFacesForRecognition(); 79 | 80 | String result = ""; 81 | 82 | if (faces == null || faces.length == 0) { 83 | result = RESULT_NEGATIVE; 84 | } else { 85 | result = RESULT_POSITIVE; 86 | faces = MatOperation.rotateFaces(imgRgba, faces, ppF.getAngleForRecognition()); 87 | for(int i = 0; i printMap = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getAll(); 128 | fileHelper.saveResultsToFile(printMap, accuracy, durationPerImage, results); 129 | 130 | final Intent intent = new Intent(getApplicationContext(), MainActivity.class); 131 | intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 132 | intent.putExtra("accuracy", accuracy); 133 | handler.post(new Runnable() { 134 | @Override 135 | public void run() { 136 | startActivity(intent); 137 | } 138 | }); 139 | } 140 | } else { 141 | Thread.currentThread().interrupt(); 142 | } 143 | } 144 | }); 145 | thread.start(); 146 | } 147 | 148 | @Override 149 | protected void onPause() { 150 | super.onPause(); 151 | thread.interrupt(); 152 | } 153 | 154 | @Override 155 | protected void onStop() { 156 | super.onStop(); 157 | thread.interrupt(); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /app/src/main/java/ch/zhaw/facerecognition/Activities/MainActivity.java: -------------------------------------------------------------------------------- 1 | /* Copyright 2016 Michael Sladoje and Mike Schälchli. All Rights Reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | ==============================================================================*/ 15 | 16 | package ch.zhaw.facerecognition.Activities; 17 | 18 | import android.app.Activity; 19 | import android.content.Intent; 20 | import android.net.Uri; 21 | import android.os.Bundle; 22 | import android.preference.PreferenceManager; 23 | import android.util.Log; 24 | import android.view.View; 25 | import android.widget.Button; 26 | import android.widget.Toast; 27 | 28 | import java.io.File; 29 | 30 | import ch.zhaw.facerecognitionlibrary.Helpers.FileHelper; 31 | import ch.zhaw.facerecognition.R; 32 | 33 | public class MainActivity extends Activity { 34 | 35 | @Override 36 | protected void onCreate(Bundle savedInstanceState) { 37 | 38 | super.onCreate(savedInstanceState); 39 | setContentView(R.layout.activity_main); 40 | 41 | Intent intent = getIntent(); 42 | String training = intent.getStringExtra("training"); 43 | if (training != null && !training.isEmpty()){ 44 | Toast.makeText(getApplicationContext(), training, Toast.LENGTH_SHORT).show(); 45 | intent.removeExtra("training"); 46 | } 47 | 48 | double accuracy = intent.getDoubleExtra("accuracy", 0); 49 | if (accuracy != 0){ 50 | Toast.makeText(getApplicationContext(), "The accuracy was " + accuracy * 100 + " %", Toast.LENGTH_LONG).show(); 51 | intent.removeExtra("accuracy"); 52 | } 53 | 54 | PreferenceManager.setDefaultValues(this, R.xml.preferences, false); 55 | 56 | Button callSettings = (Button)findViewById(R.id.button_settings); 57 | callSettings.setOnClickListener(new View.OnClickListener() { 58 | @Override 59 | public void onClick(View v) { 60 | startActivity(new Intent(v.getContext(), SettingsActivity.class)); 61 | } 62 | }); 63 | 64 | Button callAddPerson = (Button)findViewById(R.id.button_addPerson); 65 | callAddPerson.setOnClickListener(new View.OnClickListener() { 66 | @Override 67 | public void onClick(View v) { 68 | startActivity(new Intent(v.getContext(), AddPersonActivity.class)); 69 | } 70 | }); 71 | 72 | FileHelper fh = new FileHelper(); 73 | 74 | Button callDetectionTest = (Button)findViewById(R.id.button_detection_test); 75 | if(fh.getDetectionTestList().length == 0) callDetectionTest.setEnabled(false); 76 | callDetectionTest.setOnClickListener(new View.OnClickListener() { 77 | @Override 78 | public void onClick(View v) { 79 | startActivity(new Intent(v.getContext(), DetectionTestActivity.class)); 80 | } 81 | }); 82 | 83 | Button callDetectionView = (Button)findViewById(R.id.button_detection_view); 84 | callDetectionView.setOnClickListener(new View.OnClickListener() { 85 | @Override 86 | public void onClick(View v) { 87 | startActivity(new Intent(v.getContext(), DetectionActivity.class)); 88 | } 89 | }); 90 | 91 | Button callRecognition = (Button)findViewById(R.id.button_recognition_view); 92 | if(!((new File(fh.DATA_PATH)).exists())) callRecognition.setEnabled(false); 93 | callRecognition.setOnClickListener(new View.OnClickListener() { 94 | @Override 95 | public void onClick(View v) { 96 | startActivity(new Intent(v.getContext(), RecognitionActivity.class)); 97 | } 98 | }); 99 | 100 | 101 | Button callTraining = (Button)findViewById(R.id.button_recognition_training); 102 | if(fh.getTrainingList().length == 0) callTraining.setEnabled(false); 103 | callTraining.setOnClickListener(new View.OnClickListener() { 104 | @Override 105 | public void onClick(View v) { 106 | startActivity(new Intent(v.getContext(), TrainingActivity.class)); 107 | } 108 | }); 109 | 110 | Button callTest = (Button)findViewById(R.id.button_recognition_test); 111 | if(fh.getTestList().length == 0 || !((new File(fh.DATA_PATH)).exists())) callTest.setEnabled(false); 112 | callTest.setOnClickListener(new View.OnClickListener() { 113 | @Override 114 | public void onClick(View v) { 115 | startActivity(new Intent(v.getContext(), TestActivity.class)); 116 | } 117 | }); 118 | 119 | Button callAbout = (Button)findViewById(R.id.button_about); 120 | callAbout.setOnClickListener(new View.OnClickListener() { 121 | @Override 122 | public void onClick(View view) { 123 | String url = "https://github.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework"; 124 | Intent intent = new Intent(Intent.ACTION_VIEW); 125 | intent.setData(Uri.parse(url)); 126 | try { 127 | startActivity(intent); 128 | } catch (android.content.ActivityNotFoundException e) { 129 | Log.e(getClass().getName(), null, e); 130 | Toast.makeText(getApplicationContext(), "No browser found on the device to open the url", Toast.LENGTH_SHORT).show(); 131 | } 132 | } 133 | }); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /app/src/main/java/ch/zhaw/facerecognition/Activities/RecognitionActivity.java: -------------------------------------------------------------------------------- 1 | /* Copyright 2016 Michael Sladoje and Mike Schälchli. All Rights Reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | ==============================================================================*/ 15 | 16 | package ch.zhaw.facerecognition.Activities; 17 | 18 | import android.app.Activity; 19 | import android.content.SharedPreferences; 20 | import android.os.Bundle; 21 | import android.os.Looper; 22 | import android.preference.PreferenceManager; 23 | import android.util.Log; 24 | import android.view.SurfaceView; 25 | import android.view.View; 26 | import android.view.WindowManager; 27 | import android.widget.ProgressBar; 28 | 29 | import org.opencv.android.CameraBridgeViewBase; 30 | import org.opencv.android.OpenCVLoader; 31 | import org.opencv.core.Core; 32 | import org.opencv.core.Mat; 33 | import org.opencv.core.Rect; 34 | 35 | import java.io.File; 36 | import java.util.List; 37 | 38 | import ch.zhaw.facerecognitionlibrary.Helpers.CustomCameraView; 39 | import ch.zhaw.facerecognitionlibrary.Helpers.FileHelper; 40 | import ch.zhaw.facerecognitionlibrary.Helpers.MatOperation; 41 | import ch.zhaw.facerecognitionlibrary.Helpers.PreferencesHelper; 42 | import ch.zhaw.facerecognitionlibrary.PreProcessor.PreProcessorFactory; 43 | import ch.zhaw.facerecognition.R; 44 | import ch.zhaw.facerecognitionlibrary.Recognition.Recognition; 45 | import ch.zhaw.facerecognitionlibrary.Recognition.RecognitionFactory; 46 | 47 | public class RecognitionActivity extends Activity implements CameraBridgeViewBase.CvCameraViewListener2 { 48 | private CustomCameraView mRecognitionView; 49 | private static final String TAG = "Recognition"; 50 | private FileHelper fh; 51 | private Recognition rec; 52 | private PreProcessorFactory ppF; 53 | private ProgressBar progressBar; 54 | private boolean front_camera; 55 | private boolean night_portrait; 56 | private int exposure_compensation; 57 | 58 | static { 59 | if (!OpenCVLoader.initDebug()) { 60 | // Handle initialization error 61 | } 62 | } 63 | 64 | @Override 65 | public void onCreate(Bundle savedInstanceState) { 66 | Log.i(TAG,"called onCreate"); 67 | super.onCreate(savedInstanceState); 68 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 69 | setContentView(R.layout.recognition_layout); 70 | progressBar = (ProgressBar)findViewById(R.id.progressBar); 71 | fh = new FileHelper(); 72 | File folder = new File(fh.getFolderPath()); 73 | if(folder.mkdir() || folder.isDirectory()){ 74 | Log.i(TAG,"New directory for photos created"); 75 | } else { 76 | Log.i(TAG,"Photos directory already existing"); 77 | } 78 | mRecognitionView = (CustomCameraView) findViewById(R.id.RecognitionView); 79 | // Use camera which is selected in settings 80 | SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); 81 | front_camera = sharedPref.getBoolean("key_front_camera", true); 82 | night_portrait = sharedPref.getBoolean("key_night_portrait", false); 83 | exposure_compensation = Integer.valueOf(sharedPref.getString("key_exposure_compensation", "20")); 84 | 85 | if (front_camera){ 86 | mRecognitionView.setCameraIndex(CameraBridgeViewBase.CAMERA_ID_FRONT); 87 | } else { 88 | mRecognitionView.setCameraIndex(CameraBridgeViewBase.CAMERA_ID_BACK); 89 | } 90 | mRecognitionView.setVisibility(SurfaceView.VISIBLE); 91 | mRecognitionView.setCvCameraViewListener(this); 92 | 93 | int maxCameraViewWidth = Integer.parseInt(sharedPref.getString("key_maximum_camera_view_width", "640")); 94 | int maxCameraViewHeight = Integer.parseInt(sharedPref.getString("key_maximum_camera_view_height", "480")); 95 | mRecognitionView.setMaxFrameSize(maxCameraViewWidth, maxCameraViewHeight); 96 | } 97 | 98 | @Override 99 | public void onPause() 100 | { 101 | super.onPause(); 102 | if (mRecognitionView != null) 103 | mRecognitionView.disableView(); 104 | } 105 | 106 | public void onDestroy() { 107 | super.onDestroy(); 108 | if (mRecognitionView != null) 109 | mRecognitionView.disableView(); 110 | } 111 | 112 | public void onCameraViewStarted(int width, int height) { 113 | 114 | if (night_portrait) { 115 | mRecognitionView.setNightPortrait(); 116 | } 117 | 118 | if (exposure_compensation != 50 && 0 <= exposure_compensation && exposure_compensation <= 100) 119 | mRecognitionView.setExposure(exposure_compensation); 120 | } 121 | 122 | public void onCameraViewStopped() { 123 | } 124 | 125 | public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) { 126 | Mat imgRgba = inputFrame.rgba(); 127 | Mat img = new Mat(); 128 | imgRgba.copyTo(img); 129 | List images = ppF.getProcessedImage(img, PreProcessorFactory.PreprocessingMode.RECOGNITION); 130 | Rect[] faces = ppF.getFacesForRecognition(); 131 | 132 | // Selfie / Mirror mode 133 | if(front_camera){ 134 | Core.flip(imgRgba,imgRgba,1); 135 | } 136 | if(images == null || images.size() == 0 || faces == null || faces.length == 0 || ! (images.size() == faces.length)){ 137 | // skip 138 | return imgRgba; 139 | } else { 140 | faces = MatOperation.rotateFaces(imgRgba, faces, ppF.getAngleForRecognition()); 141 | for(int i = 0; i 0) { 81 | Recognition rec = RecognitionFactory.getRecognitionAlgorithm(getApplicationContext(), Recognition.RECOGNITION, algorithm); 82 | // total and matches are used to calculate the accuracy afterwards 83 | int total = 0; 84 | int total_reference = 0; 85 | int total_deviation = 0; 86 | int matches = 0; 87 | int matches_reference = 0; 88 | int matches_deviation = 0; 89 | List results = new ArrayList<>(); 90 | results.add("Set;Expected Name;Expected File;Result"); 91 | Date time_start = new Date(); 92 | for (File person : persons) { 93 | if (person.isDirectory()){ 94 | File[] folders = person.listFiles(); 95 | for (File folder : folders) { 96 | if (folder.isDirectory()){ 97 | File[] files = folder.listFiles(); 98 | int counter = 1; 99 | for (File file : files) { 100 | if (FileHelper.isFileAnImage(file)){ 101 | Date time_preprocessing_start = new Date(); 102 | Mat imgRgba = Imgcodecs.imread(file.getAbsolutePath()); 103 | Imgproc.cvtColor(imgRgba, imgRgba, Imgproc.COLOR_BGRA2RGBA); 104 | 105 | List images = ppF.getProcessedImage(imgRgba, PreProcessorFactory.PreprocessingMode.RECOGNITION); 106 | if (images == null || images.size() > 1) { 107 | // More than 1 face detected --> cannot use this file for training 108 | Date time_preprocessing_end = new Date(); 109 | // Subtract time of preprocessing 110 | time_start.setTime(time_start.getTime() + (time_preprocessing_end.getTime() - time_preprocessing_start.getTime())); 111 | continue; 112 | } else { 113 | imgRgba = images.get(0); 114 | } 115 | if (imgRgba.empty()) { 116 | Date time_preprocessing_end = new Date(); 117 | // Subtract time of preprocessing 118 | time_start.setTime(time_start.getTime() + (time_preprocessing_end.getTime() - time_preprocessing_start.getTime())); 119 | continue; 120 | } 121 | // The last token is the name --> Folder name = Person name 122 | String[] tokens = file.getParentFile().getParent().split("/"); 123 | final String name = tokens[tokens.length - 1]; 124 | tokens = file.getParent().split("/"); 125 | final String folderName = tokens[tokens.length - 1]; 126 | 127 | // fileHelper.saveCroppedImage(imgRgb, ppF, file, name, total); 128 | 129 | total++; 130 | if (folderName.equals("reference")) { 131 | total_reference++; 132 | } else if (folderName.equals("deviation")) { 133 | total_deviation++; 134 | } 135 | 136 | String name_recognized = rec.recognize(imgRgba, name); 137 | results.add(folderName + ";" + name + ";" + file.getName() + ";" + name_recognized); 138 | 139 | if (name.equals(name_recognized)) { 140 | matches++; 141 | if (folderName.equals("reference")) { 142 | matches_reference++; 143 | } else if (folderName.equals("deviation")) { 144 | matches_deviation++; 145 | } 146 | } 147 | // Update screen to show the progress 148 | final int counterPost = counter; 149 | final int filesLength = files.length; 150 | progress.post(new Runnable() { 151 | @Override 152 | public void run() { 153 | progress.append("Image " + counterPost + " of " + filesLength + " from " + name + "\n"); 154 | } 155 | }); 156 | counter++; 157 | } 158 | } 159 | } 160 | } 161 | } 162 | } 163 | Date time_end = new Date(); 164 | long duration = time_end.getTime() - time_start.getTime(); 165 | int durationPerImage = (int) duration / total; 166 | double accuracy = (double) matches / (double) total; 167 | double accuracy_reference = (double) matches_reference / (double) total_reference; 168 | double accuracy_deviation = (double) matches_deviation / (double) total_deviation; 169 | double robustness = accuracy_deviation / accuracy_reference; 170 | Map printMap = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getAll(); 171 | fileHelper.saveResultsToFile(printMap, accuracy, accuracy_reference, accuracy_deviation, robustness, durationPerImage, results); 172 | rec.saveTestData(); 173 | 174 | final Intent intent = new Intent(getApplicationContext(), MainActivity.class); 175 | intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 176 | intent.putExtra("accuracy", accuracy); 177 | handler.post(new Runnable() { 178 | @Override 179 | public void run() { 180 | startActivity(intent); 181 | } 182 | }); 183 | } 184 | } else { 185 | Thread.currentThread().interrupt(); 186 | } 187 | } 188 | }); 189 | thread.start(); 190 | } 191 | 192 | @Override 193 | protected void onPause() { 194 | super.onPause(); 195 | thread.interrupt(); 196 | } 197 | 198 | @Override 199 | protected void onStop() { 200 | super.onStop(); 201 | thread.interrupt(); 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /app/src/main/java/ch/zhaw/facerecognition/Activities/TrainingActivity.java: -------------------------------------------------------------------------------- 1 | /* Copyright 2016 Michael Sladoje and Mike Schälchli. All Rights Reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | ==============================================================================*/ 15 | 16 | package ch.zhaw.facerecognition.Activities; 17 | 18 | import android.app.Activity; 19 | import android.content.Intent; 20 | import android.content.SharedPreferences; 21 | import android.os.Handler; 22 | import android.os.Looper; 23 | import android.preference.PreferenceManager; 24 | import android.os.Bundle; 25 | import android.text.method.ScrollingMovementMethod; 26 | import android.widget.TextView; 27 | 28 | import org.opencv.android.OpenCVLoader; 29 | import org.opencv.core.Mat; 30 | import org.opencv.imgcodecs.Imgcodecs; 31 | import org.opencv.imgproc.Imgproc; 32 | 33 | import java.io.File; 34 | import java.util.List; 35 | 36 | import ch.zhaw.facerecognitionlibrary.Helpers.FileHelper; 37 | import ch.zhaw.facerecognitionlibrary.Helpers.MatName; 38 | import ch.zhaw.facerecognitionlibrary.Helpers.PreferencesHelper; 39 | import ch.zhaw.facerecognitionlibrary.PreProcessor.PreProcessorFactory; 40 | import ch.zhaw.facerecognition.R; 41 | import ch.zhaw.facerecognitionlibrary.Recognition.Recognition; 42 | import ch.zhaw.facerecognitionlibrary.Recognition.RecognitionFactory; 43 | 44 | public class TrainingActivity extends Activity { 45 | private static final String TAG = "Training"; 46 | TextView progress; 47 | Thread thread; 48 | 49 | static { 50 | if (!OpenCVLoader.initDebug()) { 51 | // Handle initialization error 52 | } 53 | } 54 | 55 | @Override 56 | protected void onCreate(Bundle savedInstanceState) { 57 | super.onCreate(savedInstanceState); 58 | setContentView(R.layout.activity_training); 59 | progress = (TextView) findViewById(R.id.progressText); 60 | progress.setMovementMethod(new ScrollingMovementMethod()); 61 | } 62 | 63 | @Override 64 | public void onResume() 65 | { 66 | super.onResume(); 67 | 68 | final Handler handler = new Handler(Looper.getMainLooper()); 69 | thread = new Thread(new Runnable() { 70 | public void run() { 71 | if(!Thread.currentThread().isInterrupted()){ 72 | PreProcessorFactory ppF = new PreProcessorFactory(getApplicationContext()); 73 | PreferencesHelper preferencesHelper = new PreferencesHelper(getApplicationContext()); 74 | String algorithm = preferencesHelper.getClassificationMethod(); 75 | 76 | FileHelper fileHelper = new FileHelper(); 77 | fileHelper.createDataFolderIfNotExsiting(); 78 | final File[] persons = fileHelper.getTrainingList(); 79 | if (persons.length > 0) { 80 | Recognition rec = RecognitionFactory.getRecognitionAlgorithm(getApplicationContext(), Recognition.TRAINING, algorithm); 81 | for (File person : persons) { 82 | if (person.isDirectory()){ 83 | File[] files = person.listFiles(); 84 | int counter = 1; 85 | for (File file : files) { 86 | if (FileHelper.isFileAnImage(file)){ 87 | Mat imgRgb = Imgcodecs.imread(file.getAbsolutePath()); 88 | Imgproc.cvtColor(imgRgb, imgRgb, Imgproc.COLOR_BGRA2RGBA); 89 | Mat processedImage = new Mat(); 90 | imgRgb.copyTo(processedImage); 91 | List images = ppF.getProcessedImage(processedImage, PreProcessorFactory.PreprocessingMode.RECOGNITION); 92 | if (images == null || images.size() > 1) { 93 | // More than 1 face detected --> cannot use this file for training 94 | continue; 95 | } else { 96 | processedImage = images.get(0); 97 | } 98 | if (processedImage.empty()) { 99 | continue; 100 | } 101 | // The last token is the name --> Folder name = Person name 102 | String[] tokens = file.getParent().split("/"); 103 | final String name = tokens[tokens.length - 1]; 104 | 105 | MatName m = new MatName("processedImage", processedImage); 106 | fileHelper.saveMatToImage(m, FileHelper.DATA_PATH); 107 | 108 | rec.addImage(processedImage, name, false); 109 | 110 | // fileHelper.saveCroppedImage(imgRgb, ppF, file, name, counter); 111 | 112 | // Update screen to show the progress 113 | final int counterPost = counter; 114 | final int filesLength = files.length; 115 | progress.post(new Runnable() { 116 | @Override 117 | public void run() { 118 | progress.append("Image " + counterPost + " of " + filesLength + " from " + name + " imported.\n"); 119 | } 120 | }); 121 | 122 | counter++; 123 | } 124 | } 125 | } 126 | } 127 | final Intent intent = new Intent(getApplicationContext(), MainActivity.class); 128 | intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 129 | if (rec.train()) { 130 | intent.putExtra("training", "Training successful"); 131 | } else { 132 | intent.putExtra("training", "Training failed"); 133 | } 134 | handler.post(new Runnable() { 135 | @Override 136 | public void run() { 137 | startActivity(intent); 138 | } 139 | }); 140 | } else { 141 | Thread.currentThread().interrupt(); 142 | } 143 | } 144 | } 145 | }); 146 | thread.start(); 147 | } 148 | 149 | @Override 150 | protected void onPause() { 151 | super.onPause(); 152 | thread.interrupt(); 153 | } 154 | 155 | @Override 156 | protected void onStop() { 157 | super.onStop(); 158 | thread.interrupt(); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /app/src/main/java/ch/zhaw/facerecognition/Helpers/EditTextPreference.java: -------------------------------------------------------------------------------- 1 | /* Copyright 2016 Michael Sladoje and Mike Schälchli. All Rights Reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | ==============================================================================*/ 15 | 16 | package ch.zhaw.facerecognition.Helpers; 17 | 18 | /*************************************************************************************** 19 | * Title: Android Preference: Show current value in summary 20 | * Author: Enzam 21 | * Date: 29.09.2013 22 | * Code version: - 23 | * Availability: https://enzam.wordpress.com 24 | * 25 | ***************************************************************************************/ 26 | 27 | import android.content.Context; 28 | import android.util.AttributeSet; 29 | 30 | public class EditTextPreference extends android.preference.EditTextPreference { 31 | 32 | public EditTextPreference(Context context, AttributeSet attrs) { 33 | super(context, attrs); 34 | } 35 | 36 | @Override 37 | protected void onDialogClosed(boolean positiveResult) { 38 | super.onDialogClosed(positiveResult); 39 | 40 | setSummary(getSummary()); 41 | } 42 | 43 | @Override 44 | public CharSequence getSummary() { 45 | return this.getText(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/ch/zhaw/facerecognition/Helpers/ListPreference.java: -------------------------------------------------------------------------------- 1 | /* Copyright 2016 Michael Sladoje and Mike Schälchli. All Rights Reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | ==============================================================================*/ 15 | 16 | package ch.zhaw.facerecognition.Helpers; 17 | 18 | import android.content.Context; 19 | import android.util.AttributeSet; 20 | 21 | public class ListPreference extends android.preference.ListPreference { 22 | public ListPreference(Context context, AttributeSet attrs) { 23 | super(context, attrs); 24 | } 25 | 26 | @Override 27 | public CharSequence getSummary() { 28 | return this.getValue(); 29 | } 30 | 31 | @Override 32 | protected void onDialogClosed(boolean positiveResult) { 33 | super.onDialogClosed(positiveResult); 34 | 35 | setSummary(getSummary()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/ch/zhaw/facerecognition/Helpers/MultiSelectListPreference.java: -------------------------------------------------------------------------------- 1 | /* Copyright 2016 Michael Sladoje and Mike Schälchli. All Rights Reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | ==============================================================================*/ 15 | 16 | package ch.zhaw.facerecognition.Helpers; 17 | 18 | import android.content.Context; 19 | import android.util.AttributeSet; 20 | 21 | public class MultiSelectListPreference extends android.preference.MultiSelectListPreference { 22 | public MultiSelectListPreference(Context context, AttributeSet attrs) { 23 | super(context, attrs); 24 | } 25 | 26 | @Override 27 | public CharSequence getSummary() { 28 | String result = ""; 29 | for(String s : this.getValues()){ 30 | result += s + " "; 31 | } 32 | return result; 33 | } 34 | 35 | @Override 36 | protected void onDialogClosed(boolean positiveResult) { 37 | super.onDialogClosed(positiveResult); 38 | 39 | setSummary(getSummary()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/ch/zhaw/facerecognition/Helpers/SwitchPreference.java: -------------------------------------------------------------------------------- 1 | /* Copyright 2016 Michael Sladoje and Mike Schälchli. All Rights Reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | ==============================================================================*/ 15 | 16 | package ch.zhaw.facerecognition.Helpers; 17 | 18 | import android.content.Context; 19 | import android.util.AttributeSet; 20 | 21 | public class SwitchPreference extends android.preference.SwitchPreference { 22 | public SwitchPreference(Context context, AttributeSet attrs) { 23 | super(context, attrs); 24 | } 25 | 26 | @Override 27 | public CharSequence getSummary() { 28 | if(this.isChecked()) { 29 | return this.getSwitchTextOn(); 30 | } else { 31 | return this.getSwitchTextOff(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_camera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-hdpi/ic_camera.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_info_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-hdpi/ic_info_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_notifications_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-hdpi/ic_notifications_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_sync_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-hdpi/ic_sync_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_camera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-mdpi/ic_camera.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_info_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-mdpi/ic_info_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_notifications_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-mdpi/ic_notifications_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_sync_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-mdpi/ic_sync_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_info_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_notifications_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_sync_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_camera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-xhdpi/ic_camera.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_info_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-xhdpi/ic_info_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_notifications_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-xhdpi/ic_notifications_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_sync_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-xhdpi/ic_sync_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_camera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-xxhdpi/ic_camera.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_info_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-xxhdpi/ic_info_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_notifications_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-xxhdpi/ic_notifications_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_sync_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-xxhdpi/ic_sync_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_info_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-xxxhdpi/ic_info_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_notifications_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-xxxhdpi/ic_notifications_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_sync_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable-xxxhdpi/ic_sync_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/background_main.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qualeams/Android-Face-Recognition-with-Deep-Learning-Test-Framework/3997843efa9d72e147655ba3909467bddc2e1dca/app/src/main/res/drawable/background_main.jpg -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_add_person.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 18 | 26 | 27 | 35 | 36 | 45 | 46 | 56 | 57 | 66 | 67 |