Skip to content
This repository was archived by the owner on Jun 18, 2024. It is now read-only.

Commit e085b52

Browse files
committed
- Fix issue in feeding image to TensorFlow
- Add optimized_facenet model and change default settings to use TensorFlow by default
1 parent b29f637 commit e085b52

File tree

9 files changed

+104
-57
lines changed

9 files changed

+104
-57
lines changed

NOTICE.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,3 +395,29 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
395395
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
396396
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
397397
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.

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Code has been derived from the following sources:
99
- LIBSVM - https://github.com/cjlin1/libsvm
1010
- AndroidLibSvm - https://github.com/yctung/AndroidLibSvm
1111
- TensorFlow - https://github.com/tensorflow/tensorflow
12-
- TensorFlow Android Demo - https://github.com/miyosuda/TensorFlowAndroidDemo
12+
- facenet - https://github.com/davidsandberg/facenet/pull/240
1313
- Caffe - https://github.com/BVLC/caffe
1414
- caffe-android-demo - https://github.com/sh1r0/caffe-android-demo
1515
- caffe-android-lib - https://github.com/sh1r0/caffe-android-lib
@@ -29,7 +29,7 @@ Most parameters are set in the settings/preferences.
2929
Either train and classify by passing images (OpenCV Mat object) to the library or if features already obtained from the image (getFeatureVector), the feature vector can be passed (OpenCV Mat object) together with the flag "featuresAlreadyExtracted" set to 'true'.
3030

3131
### Android NDK - C++
32-
The libs for LIBSVM and TensorFlow can be compiled outside of Android Studio with the make command (the Makefile is located under /jni-build).
32+
The libs for LIBSVM can be compiled outside of Android Studio with the make command (the Makefile is located under /jni-build).
3333
There are 3 different usages:
3434
- make clean (executes ndk-build clean)
3535
- make (executes ndk-build)

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ android {
88
minSdkVersion 21
99
targetSdkVersion 21
1010
versionCode 25
11-
versionName "1.5.0"
11+
versionName "1.5.1"
1212
}
1313
buildTypes {
1414
release {

facerecognitionlibrary.iml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,20 @@
6363
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
6464
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
6565
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
66-
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
67-
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
68-
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
69-
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
70-
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
71-
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
72-
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
7366
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
7467
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
7568
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
7669
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
7770
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
7871
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
7972
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
73+
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
74+
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
75+
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
76+
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
77+
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
78+
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
79+
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
8080
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/annotations" />
8181
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
8282
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
87.1 MB
Binary file not shown.

src/main/java/ch/zhaw/facerecognitionlibrary/Helpers/PreferencesHelper.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -154,31 +154,39 @@ public int getN(){
154154
}
155155

156156
public int getFaceSize(){
157-
return Integer.valueOf(sharedPreferences.getString("key_faceSize", "224"));
157+
return Integer.valueOf(sharedPreferences.getString("key_faceSize", "160"));
158158
}
159159

160160
public int getTensorFlowInputSize(){
161-
return Integer.valueOf(sharedPreferences.getString("key_inputSize", "224"));
161+
return Integer.valueOf(sharedPreferences.getString("key_inputSize", "160"));
162162
}
163163

164-
public int getTensorFlowChannels(){
165-
return Integer.valueOf(sharedPreferences.getString("key_channels", "3"));
164+
public int getTensorFlowInputChannels(){
165+
return Integer.valueOf(sharedPreferences.getString("key_inputChannels", "3"));
166+
}
167+
168+
public int getTensorFlowImageMean(){
169+
return Integer.valueOf(sharedPreferences.getString("key_imageMean", "128"));
170+
}
171+
172+
public int getTensorFlowImageStd(){
173+
return Integer.valueOf(sharedPreferences.getString("key_imageStd", "128"));
166174
}
167175

168176
public int getTensorFlowOutputSize(){
169-
return Integer.valueOf(sharedPreferences.getString("key_outputSize", "1024"));
177+
return Integer.valueOf(sharedPreferences.getString("key_outputSize", "128"));
170178
}
171179

172180
public String getTensorFlowInputLayer(){
173181
return sharedPreferences.getString("key_inputLayer", "input");
174182
}
175183

176184
public String getTensorFlowOutputLayer(){
177-
return sharedPreferences.getString("key_outputLayer", "avgpool0");
185+
return sharedPreferences.getString("key_outputLayer", "embeddings");
178186
}
179187

180188
public String getTensorFlowModelFile(){
181-
return sharedPreferences.getString("key_modelFileTensorFlow", "tensorflow_inception_graph.pb");
189+
return sharedPreferences.getString("key_modelFileTensorFlow", "facenet.pb");
182190
}
183191

184192
public float getPCAThreshold(){

src/main/java/ch/zhaw/facerecognitionlibrary/Recognition/TensorFlow.java

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@
1616
package ch.zhaw.facerecognitionlibrary.Recognition;
1717

1818
import android.content.Context;
19+
import android.graphics.Bitmap;
1920

20-
import org.opencv.core.CvType;
21+
import org.opencv.android.Utils;
2122
import org.opencv.core.Mat;
2223
import org.opencv.core.Size;
2324
import org.opencv.imgproc.Imgproc;
2425
import org.opencv.utils.Converters;
2526
import org.tensorflow.contrib.android.TensorFlowInferenceInterface;
2627

28+
import java.io.File;
2729
import java.util.ArrayList;
2830
import java.util.List;
2931

@@ -44,9 +46,10 @@ public class TensorFlow implements Recognition {
4446
private String outputLayer;
4547

4648
private int inputSize;
47-
private int outputSize;
48-
4949
private int channels;
50+
private int imageMean;
51+
private int imageStd;
52+
private int outputSize;
5053

5154
private Recognition rec;
5255

@@ -58,14 +61,23 @@ public TensorFlow(Context context, int method) {
5861
String dataPath = FileHelper.TENSORFLOW_PATH;
5962
PreferencesHelper preferencesHelper = new PreferencesHelper(context);
6063
inputSize = preferencesHelper.getTensorFlowInputSize();
64+
channels = preferencesHelper.getTensorFlowInputChannels();
65+
imageMean = preferencesHelper.getTensorFlowImageMean();
66+
imageStd = preferencesHelper.getTensorFlowImageStd();
6167
outputSize = preferencesHelper.getTensorFlowOutputSize();
6268
inputLayer = preferencesHelper.getTensorFlowInputLayer();
6369
outputLayer = preferencesHelper.getTensorFlowOutputLayer();
64-
channels = preferencesHelper.getTensorFlowChannels();
70+
6571
String modelFile = preferencesHelper.getTensorFlowModelFile();
6672
Boolean classificationMethod = preferencesHelper.getClassificationMethodTFCaffe();
6773

68-
inferenceInterface = new TensorFlowInferenceInterface(context.getAssets(), dataPath + modelFile);
74+
// Use internal assets file as fallback, if no model file is provided
75+
File file = new File(dataPath + modelFile);
76+
if(file.exists()){
77+
inferenceInterface = new TensorFlowInferenceInterface(context.getAssets(), dataPath + modelFile);
78+
} else {
79+
inferenceInterface = new TensorFlowInferenceInterface(context.getAssets(), modelFile);
80+
}
6981

7082
if(classificationMethod){
7183
rec = new SupportVectorMachine(context, method);
@@ -135,15 +147,19 @@ public Mat getFeatureVector(Mat img){
135147
}
136148

137149
private float[] getPixels(Mat img){
138-
img.convertTo(img, CvType.CV_32FC4);
139-
float[] pixels = new float[img.rows() * img.cols() * channels];
140-
for (int col=0; col<img.cols(); col++){
141-
for (int row=0; row<img.rows(); row++){
142-
pixels[col*row] = (float)img.get(row, col)[0];
143-
pixels[col*row + 1] = (float)img.get(row, col)[1];
144-
pixels[col*row + 2] = (float)img.get(row, col)[2];
145-
}
150+
Bitmap bmp = Bitmap.createBitmap(inputSize, inputSize, Bitmap.Config.ARGB_8888);
151+
Utils.matToBitmap(img, bmp);
152+
int[] intValues = new int[inputSize * inputSize];
153+
bmp.getPixels(intValues, 0, inputSize, 0, 0, inputSize, inputSize);
154+
155+
float[] floatValues = new float[inputSize * inputSize * channels];
156+
for (int i = 0; i < intValues.length; ++i) {
157+
final int val = intValues[i];
158+
floatValues[i * 3 + 0] = (((float)((val >> 16) & 0xFF)) - imageMean) / imageStd;
159+
floatValues[i * 3 + 1] = (((float)((val >> 8) & 0xFF)) - imageMean) / imageStd;
160+
floatValues[i * 3 + 2] = (((float)(val & 0xFF)) - imageMean) / imageStd;
146161
}
147-
return pixels;
162+
163+
return floatValues;
148164
}
149165
}

src/main/res/values/preferences_lists.xml

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,9 @@
2525
<item>@string/grayscale</item>
2626
<item>@string/eyeAlignment</item>
2727
</string-array>
28-
<string-array name="standard_pre_default">
29-
<item>@string/grayscale</item>
30-
<item>@string/eyeAlignment</item>
31-
</string-array>
3228
<string-array name="brightness">
3329
<item>@string/gammaCorrection</item>
3430
</string-array>
35-
<string-array name="brightness_default">
36-
<item>@string/gammaCorrection</item>
37-
</string-array>
3831
<string-array name="contours">
3932
<item>@string/doG</item>
4033
<item>@string/masking</item>
@@ -43,9 +36,6 @@
4336
<string-array name="contrast">
4437
<item>@string/histogrammEqualization</item>
4538
</string-array>
46-
<string-array name="contrast_default">
47-
<item>@string/histogrammEqualization</item>
48-
</string-array>
4939
<string-array name="standard_post">
5040
<item>@string/resize</item>
5141
</string-array>

src/main/res/xml/preferences.xml

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
android:key="key_timerDiff"/>
6868
<ch.zhaw.facerecognition.Helpers.EditTextPreference
6969
android:title="Face size: N (Resize to N x N)"
70-
android:defaultValue="224"
70+
android:defaultValue="160"
7171
android:numeric="integer"
7272
android:key="key_faceSize"/>
7373
</PreferenceCategory>
@@ -164,14 +164,12 @@
164164
android:title="Standard Preprocessing"
165165
android:entries="@array/standard_pre"
166166
android:entryValues="@array/standard_pre"
167-
android:key="key_standard_pre"
168-
android:defaultValue="@array/standard_pre_default"/>
167+
android:key="key_standard_pre" />
169168
<ch.zhaw.facerecognition.Helpers.MultiSelectListPreference
170169
android:title="Brightness Correction"
171170
android:entries="@array/brightness"
172171
android:entryValues="@array/brightness"
173-
android:key="key_brightness"
174-
android:defaultValue="@array/brightness_default"/>
172+
android:key="key_brightness" />
175173
<ch.zhaw.facerecognition.Helpers.MultiSelectListPreference
176174
android:title="Contours"
177175
android:entries="@array/contours"
@@ -182,8 +180,7 @@
182180
android:title="Contrast Adjustment"
183181
android:entries="@array/contrast"
184182
android:entryValues="@array/contrast"
185-
android:key="key_contrast"
186-
android:defaultValue="@array/contrast_default"/>
183+
android:key="key_contrast" />
187184
<ch.zhaw.facerecognition.Helpers.MultiSelectListPreference
188185
android:title="Standard Postprocessing"
189186
android:entries="@array/standard_post"
@@ -202,7 +199,7 @@
202199
android:key="key_sigmas"/>
203200
<ch.zhaw.facerecognition.Helpers.EditTextPreference
204201
android:title="N (Resize to N x N)"
205-
android:defaultValue="25"
202+
android:defaultValue="160"
206203
android:numeric="integer"
207204
android:key="key_N"/>
208205
</PreferenceCategory>
@@ -212,7 +209,7 @@
212209
android:title="Feature extraction and classification method"
213210
android:entries="@array/classification_method"
214211
android:entryValues="@array/classification_method"
215-
android:defaultValue="@string/imageReshaping"
212+
android:defaultValue="@string/tensorflow"
216213
android:key="key_classification_method"/>
217214
<ch.zhaw.facerecognition.Helpers.SwitchPreference
218215
android:title="Classification method for TensorFlow or Caffe"
@@ -241,30 +238,40 @@
241238
android:title="TensorFlow">
242239
<ch.zhaw.facerecognition.Helpers.EditTextPreference
243240
android:title="Input Size"
244-
android:defaultValue="224"
241+
android:defaultValue="160"
245242
android:numeric="integer"
246243
android:key="key_inputSize"/>
247244
<ch.zhaw.facerecognition.Helpers.EditTextPreference
248-
android:title="Number of channels"
245+
android:title="Number of input channels"
249246
android:defaultValue="3"
250247
android:numeric="integer"
251-
android:key="key_channels" />
248+
android:key="key_inputChannels" />
249+
<ch.zhaw.facerecognition.Helpers.EditTextPreference
250+
android:title="Image mean"
251+
android:defaultValue="128"
252+
android:numeric="integer"
253+
android:key="key_imageMean" />
254+
<ch.zhaw.facerecognition.Helpers.EditTextPreference
255+
android:title="Image Std"
256+
android:defaultValue="128"
257+
android:numeric="integer"
258+
android:key="key_imageStd" />
252259
<ch.zhaw.facerecognition.Helpers.EditTextPreference
253260
android:title="Output size"
254-
android:defaultValue="4096"
261+
android:defaultValue="128"
255262
android:numeric="integer"
256263
android:key="key_outputSize"/>
257264
<ch.zhaw.facerecognition.Helpers.EditTextPreference
258265
android:title="Input layer"
259-
android:defaultValue="Placeholder"
266+
android:defaultValue="input"
260267
android:key="key_inputLayer"/>
261268
<ch.zhaw.facerecognition.Helpers.EditTextPreference
262269
android:title="Output layer"
263-
android:defaultValue="fc7/fc7"
270+
android:defaultValue="embeddings"
264271
android:key="key_outputLayer"/>
265272
<ch.zhaw.facerecognition.Helpers.EditTextPreference
266273
android:title="Model file"
267-
android:defaultValue="vgg_faces.pb"
274+
android:defaultValue="optimized_facenet.pb"
268275
android:key="key_modelFileTensorFlow"/>
269276
</PreferenceCategory>
270277
<PreferenceCategory

0 commit comments

Comments
 (0)