-
Notifications
You must be signed in to change notification settings - Fork 239
/
NativeMethods.java
153 lines (134 loc) · 5.64 KB
/
NativeMethods.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*******************************************************************************
* Copyright (C) 2016 Kristian Sloth Lauszus. All rights reserved.
*
* This software may be distributed and modified under the terms of the GNU
* General Public License version 2 (GPL2) as published by the Free Software
* Foundation and appearing in the file GPL2.TXT included in the packaging of
* this file. Please note that GPL2 Section 2[b] requires that all works based
* on this software must also be made publicly available under the terms of
* the GPL2 ("Copyleft").
*
* Contact information
* -------------------
*
* Kristian Sloth Lauszus
* Web : http://www.lauszus.com
* e-mail : lauszus@gmail.com
******************************************************************************/
package com.lauszus.facerecognitionapp;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import org.opencv.core.Mat;
// All computations is done in an asynchronous task, so we do not skip any frames
class NativeMethods {
private static final String TAG = FaceRecognitionAppActivity.class.getSimpleName() + "/" + NativeMethods.class.getSimpleName();
static void loadNativeLibraries() {
System.loadLibrary("face-lib");
}
static class TrainFacesTask extends AsyncTask<Void, Void, Boolean> {
private final Mat images, classes;
private final Callback callback;
private Exception error;
interface Callback {
void onTrainFacesComplete(boolean result);
}
/**
* Constructor used for Eigenfaces.
* @param images Matrix containing all images as column vectors.
*/
TrainFacesTask(Mat images, Callback callback) {
this(images, null, callback);
}
/**
* Constructor used for Fisherfaces.
* @param images Matrix containing all images as column vectors.
* @param classes Vector containing classes for each image.
*/
TrainFacesTask(Mat images, Mat classes, Callback callback) {
this.images = images;
this.classes = classes;
this.callback = callback;
}
@Override
protected Boolean doInBackground(Void... params) {
try {
if (classes == null)
TrainFaces(images.getNativeObjAddr(), 0); // Train Eigenfaces
else
TrainFaces(images.getNativeObjAddr(), classes.getNativeObjAddr()); // Train Fisherfaces
return true;
} catch (Exception e) {
error = e;
return false;
}
}
@Override
protected void onPostExecute(Boolean result) {
callback.onTrainFacesComplete(result);
if (result)
Log.i(TAG, "Done training images");
else
Log.e(TAG, error.getMessage());
}
}
static class MeasureDistTask extends AsyncTask<Mat, Void, Bundle> {
static final String MIN_DIST_FLOAT = "minDist";
static final String MIN_DIST_INDEX_INT = "minDistIndex";
static final String DIST_FACE_FLOAT = "distFace";
private final Callback callback;
private final boolean useEigenfaces;
private Exception error;
interface Callback {
void onMeasureDistComplete(Bundle bundle);
}
MeasureDistTask(boolean useEigenfaces, Callback callback) {
this.useEigenfaces = useEigenfaces;
this.callback = callback;
}
@Override
protected Bundle doInBackground(Mat... mat) {
float[] minDist = new float[] { -1 };
int[] minDistIndex = new int[1];
float[] faceDist = new float[1];
try {
MeasureDist(mat[0].getNativeObjAddr(), minDist, minDistIndex, faceDist, useEigenfaces);
} catch (Exception e) {
error = e;
return null;
}
Bundle bundle = new Bundle();
bundle.putFloat(MIN_DIST_FLOAT, minDist[0]);
bundle.putInt(MIN_DIST_INDEX_INT, minDistIndex[0]);
bundle.putFloat(DIST_FACE_FLOAT, faceDist[0]);
return bundle;
}
@Override
protected void onPostExecute(Bundle bundle) {
callback.onMeasureDistComplete(bundle);
if (bundle != null)
Log.i(TAG, "Done measuring distance");
else
Log.e(TAG, error.getMessage());
}
}
/**
* Train faces recognition.
* @param addrImages Address for matrix containing all images as column vectors.
* @param addrClasses Address for vector containing classes for each image.
* This must be a incrementing list starting at 1.
* If set to NULL, then Eigenfaces will be used.
* If this is set, then Fisherfaces will be used.
*/
private static native void TrainFaces(long addrImages, long addrClasses);
/**
* Measure euclidean distance between the weight of the image compared to all weights.
* @param addrImage Vector containing the image.
* @param minDist Returns a list of sorted distances to images
* @param minDistIndex Returns the index of the closest distance
* @param faceDist Retuns the distance to facespace
* @param useEigenfaces Set to true if Eigenfaces are used. If set to false,
* then Fisherfaces will be used.
*/
private static native void MeasureDist(long addrImage, float[] minDist, int[] minDistIndex, float[] faceDist, boolean useEigenfaces);
}