Skip to content

Commit 081986f

Browse files
author
Vladimir Kocheryzhkin
committed
try to move all logic into FaceRecognizer
1 parent fb12260 commit 081986f

File tree

6 files changed

+184
-130
lines changed

6 files changed

+184
-130
lines changed

visionSamples/FaceTracker/app/src/androidTest/java/com/google/android/gms/samples/vision/face/facetracker/ExampleInstrumentedTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public void useAppContext() throws Exception {
2626
@Test
2727
public void callAddContext() {
2828
FaceTrackerActivity activity = activityRule.getActivity();
29-
int res = activity.nativeAdd(1,2);
30-
assertEquals(3, res);
29+
// int res = activity.nativeAdd(1,2);
30+
// assertEquals(3, res);
3131
}
3232
}

visionSamples/FaceTracker/app/src/androidTest/java/dlib/android/FaceRecognizerTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ public class FaceRecognizerTest {
88
@Test
99
public void RecognizeTest() {
1010
FaceRecognizer fr = new FaceRecognizer();
11-
String res = fr.Recognize();
12-
assertEquals("Unknown", res);
11+
fr.loadNative();
12+
// String res = fr.recognize();
13+
// assertEquals("Unknown", res);
1314
}
1415
}

visionSamples/FaceTracker/app/src/main/cpp/native-lib.cpp

Lines changed: 150 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -70,93 +70,6 @@ typedef struct
7070

7171
float FACE_RECOGNIZE_THRESH = 0.55;
7272

73-
extern "C"
74-
{
75-
JNIEXPORT jstring JNICALL
76-
Java_com_google_android_gms_samples_vision_face_facetracker_CustomDetector_test(JNIEnv *env,
77-
jobject instance,
78-
jobject bmp) {
79-
AndroidBitmapInfo infocolor;
80-
void *pixelscolor;
81-
int y;
82-
int x;
83-
int ret;
84-
array2d<rgb_pixel> img;
85-
if ((ret = AndroidBitmap_getInfo(env, bmp, &infocolor)) < 0) {
86-
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
87-
return env->NewStringUTF("Image broken");
88-
}
89-
LOGI("color image :: width is %d; height is %d; stride is %d; format is %d;flags is %d",
90-
infocolor.width, infocolor.height, infocolor.stride, infocolor.format, infocolor.flags);
91-
92-
if (infocolor.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
93-
LOGE("Bitmap format is not RGBA_8888 !");
94-
return env->NewStringUTF("Image broken 2");
95-
}
96-
97-
if ((ret = AndroidBitmap_lockPixels(env, bmp, &pixelscolor)) < 0) {
98-
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
99-
}
100-
101-
img.set_size(infocolor.height, infocolor.width);
102-
for (y = 0; y < infocolor.height; y++) { //todo: performance
103-
argb *line = (argb *) pixelscolor;
104-
for (x = 0; x < infocolor.width; ++x) {
105-
rgb_pixel p(line[x].alpha, line[x].red, line[x].green);
106-
img[y][x] = p;
107-
}
108-
pixelscolor = (char *) pixelscolor + infocolor.stride;
109-
}
110-
111-
//todo: smth wrong with colors
112-
//dlib::save_bmp(img, "/storage/emulated/0/Download/test.bmp");
113-
114-
std::vector<dlib::rectangle> dets = detector(img);
115-
LOGI("detected size %d", dets.size());
116-
117-
float min_dist = 0.0;
118-
if(dets.size() > 0 ){
119-
auto face = dets.front();
120-
std::vector<matrix<rgb_pixel>> faces;
121-
int x = face.left();
122-
int y = face.top();
123-
int width = face.width();
124-
int height = face.height();
125-
126-
auto shape = sp(img, face);
127-
matrix<rgb_pixel> face_chip;
128-
extract_image_chip(img, get_face_chip_details(shape, 150, 0.25), face_chip);
129-
faces.push_back(move(face_chip));
130-
131-
std::vector<matrix<float, 0, 1>> face_descriptors = net(faces);
132-
133-
if (face_descriptors.size() > 0)
134-
{
135-
matrix<float, 0, 1> face_desc = face_descriptors[0];
136-
for (auto& i : known_faces) {
137-
float dist = length(face_desc - i.second );
138-
if (dist < min_dist){
139-
min_dist = dist;
140-
}
141-
if( dist < FACE_RECOGNIZE_THRESH) //todo: extract thresh
142-
{
143-
LOGI("recognized");
144-
return env->NewStringUTF(i.first.c_str());
145-
}
146-
}
147-
}
148-
LOGI("not recognized, max dist %0.2f", min_dist);
149-
}
150-
151-
LOGI("unlocking pixels");
152-
AndroidBitmap_unlockPixels(env, bmp);
153-
154-
//std::string returnValue = "Unknown" + std::to_string(min_dist);
155-
std::string returnValue = "Unknown";
156-
return env->NewStringUTF(returnValue.c_str());
157-
}
158-
}
159-
16073
extern "C"
16174
JNIEXPORT jint JNICALL
16275
Java_com_google_android_gms_samples_vision_face_facetracker_FaceTrackerActivity_loadResources(
@@ -217,9 +130,81 @@ Java_com_google_android_gms_samples_vision_face_facetracker_FaceTrackerActivity_
217130

218131
return 0;
219132
}extern "C"
133+
JNIEXPORT jint JNICALL
134+
Java_dlib_android_FaceRecognizer_loadResourcesPart1(JNIEnv *env, jobject instance) {
135+
136+
LOGI("load resource part1");
137+
FILE *file1 = fopen("/storage/emulated/0/Download/shape_predictor_5_face_landmarks.dat", "r+");
138+
FILE *file2 = fopen("/storage/emulated/0/Download/dlib_face_recognition_resnet_model_v1.dat",
139+
"r+");
140+
141+
if (file1 != NULL && file2 != NULL ) {
142+
fclose(file1);
143+
fclose(file2);
144+
dlib::deserialize("/storage/emulated/0/Download/shape_predictor_5_face_landmarks.dat")
145+
>> sp;
146+
dlib::deserialize("/storage/emulated/0/Download/dlib_face_recognition_resnet_model_v1.dat")
147+
>> net;
148+
149+
DIR *d;
150+
char *p1,*p2;
151+
int ret;
152+
struct dirent *dir;
153+
d = opendir("/storage/emulated/0/Download");
154+
if (d)
155+
{
156+
LOGI("Loading feature vectors using *.vec", p1);
157+
while ((dir = readdir(d)) != NULL)
158+
{
159+
p1=strtok(dir->d_name,".");
160+
p2=strtok(NULL,".");
161+
if(p2!=NULL)
162+
{
163+
ret=strcmp(p2,"vec");
164+
if(ret==0)
165+
{
166+
std::string name = std::string(p1);
167+
std::string file = name + ".vec";
168+
matrix<float, 0, 1> face_vector;
169+
dlib::deserialize("/storage/emulated/0/Download/" + file) >> face_vector;
170+
known_faces.insert({name, face_vector});
171+
}
172+
}
173+
174+
}
175+
closedir(d);
176+
}
177+
} else {
178+
return -1; //failed
179+
}
180+
181+
return 0;
182+
183+
}extern "C"
184+
JNIEXPORT jint JNICALL
185+
Java_dlib_android_FaceRecognizer_loadResourcesPart2(JNIEnv *env, jobject instance) {
186+
187+
LOGI("load resource part2");
188+
FILE *file1 = fopen("/storage/emulated/0/Download/shape_predictor_5_face_landmarks.dat", "r+");
189+
FILE *file2 = fopen("/storage/emulated/0/Download/dlib_face_recognition_resnet_model_v1.dat",
190+
"r+");
191+
192+
if (file1 != NULL && file2 != NULL ) {
193+
fclose(file1);
194+
fclose(file2);
195+
dlib::deserialize("/storage/emulated/0/Download/shape_predictor_5_face_landmarks.dat")
196+
>> sp1;
197+
dlib::deserialize("/storage/emulated/0/Download/dlib_face_recognition_resnet_model_v1.dat")
198+
>> net1;
199+
} else{
200+
return -1;
201+
}
202+
return 0;
203+
}extern "C"
220204
JNIEXPORT jstring JNICALL
221-
Java_com_google_android_gms_samples_vision_face_facetracker_FaceTrackerActivity_recognizeFromImage(
222-
JNIEnv *env, jobject instance, jobject bmp) {
205+
Java_dlib_android_FaceRecognizer_recognizeNative1(JNIEnv *env,
206+
jobject instance,
207+
jobject bmp) {
223208

224209
AndroidBitmapInfo infocolor;
225210
void *pixelscolor;
@@ -288,16 +273,85 @@ Java_com_google_android_gms_samples_vision_face_facetracker_FaceTrackerActivity_
288273
AndroidBitmap_unlockPixels(env, bmp);
289274
return env->NewStringUTF(returnValue.c_str());
290275
}extern "C"
291-
JNIEXPORT jint JNICALL
292-
Java_com_google_android_gms_samples_vision_face_facetracker_FaceTrackerActivity_nativeAdd(
293-
JNIEnv *env, jobject instance, jint a, jint b) {
276+
JNIEXPORT jstring JNICALL
277+
Java_dlib_android_FaceRecognizer_recognizeNative2(JNIEnv *env, jobject instance, jobject bmp) {
294278

295-
return a + b;
279+
AndroidBitmapInfo infocolor;
280+
void *pixelscolor;
281+
int y;
282+
int x;
283+
int ret;
284+
array2d<rgb_pixel> img;
285+
if ((ret = AndroidBitmap_getInfo(env, bmp, &infocolor)) < 0) {
286+
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
287+
return env->NewStringUTF("Image broken");
288+
}
289+
LOGI("color image :: width is %d; height is %d; stride is %d; format is %d;flags is %d",
290+
infocolor.width, infocolor.height, infocolor.stride, infocolor.format, infocolor.flags);
296291

297-
}extern "C"
298-
JNIEXPORT jstring JNICALL
299-
Java_dlib_android_FaceRecognizer_recognizeNative(JNIEnv *env, jobject instance) {
292+
if (infocolor.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
293+
LOGE("Bitmap format is not RGBA_8888 !");
294+
return env->NewStringUTF("Image broken 2");
295+
}
296+
297+
if ((ret = AndroidBitmap_lockPixels(env, bmp, &pixelscolor)) < 0) {
298+
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
299+
}
300+
301+
img.set_size(infocolor.height, infocolor.width);
302+
for (y = 0; y < infocolor.height; y++) { //todo: performance
303+
argb *line = (argb *) pixelscolor;
304+
for (x = 0; x < infocolor.width; ++x) {
305+
rgb_pixel p(line[x].alpha, line[x].red, line[x].green);
306+
img[y][x] = p;
307+
}
308+
pixelscolor = (char *) pixelscolor + infocolor.stride;
309+
}
310+
311+
//todo: smth wrong with colors
312+
//dlib::save_bmp(img, "/storage/emulated/0/Download/test.bmp");
313+
314+
std::vector<dlib::rectangle> dets = detector(img);
315+
LOGI("detected size %d", dets.size());
316+
317+
float min_dist = 0.0;
318+
if(dets.size() > 0 ){
319+
auto face = dets.front();
320+
std::vector<matrix<rgb_pixel>> faces;
321+
int x = face.left();
322+
int y = face.top();
323+
int width = face.width();
324+
int height = face.height();
325+
326+
auto shape = sp(img, face);
327+
matrix<rgb_pixel> face_chip;
328+
extract_image_chip(img, get_face_chip_details(shape, 150, 0.25), face_chip);
329+
faces.push_back(move(face_chip));
330+
331+
std::vector<matrix<float, 0, 1>> face_descriptors = net(faces);
332+
333+
if (face_descriptors.size() > 0)
334+
{
335+
matrix<float, 0, 1> face_desc = face_descriptors[0];
336+
for (auto& i : known_faces) {
337+
float dist = length(face_desc - i.second );
338+
if (dist < min_dist){
339+
min_dist = dist;
340+
}
341+
if( dist < FACE_RECOGNIZE_THRESH) //todo: extract thresh
342+
{
343+
LOGI("recognized");
344+
return env->NewStringUTF(i.first.c_str());
345+
}
346+
}
347+
}
348+
LOGI("not recognized, max dist %0.2f", min_dist);
349+
}
350+
351+
LOGI("unlocking pixels");
352+
AndroidBitmap_unlockPixels(env, bmp);
300353

354+
//std::string returnValue = "Unknown" + std::to_string(min_dist);
301355
std::string returnValue = "Unknown";
302356
return env->NewStringUTF(returnValue.c_str());
303357
}

visionSamples/FaceTracker/app/src/main/java/com/google/android/gms/samples/vision/face/facetracker/CustomDetector.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import java.io.FileWriter;
2020
import java.io.IOException;
2121

22+
import dlib.android.FaceRecognizer;
23+
2224
import static android.os.Environment.getExternalStorageDirectory;
2325

2426
interface RecognitionInterface
@@ -31,6 +33,7 @@ public class CustomDetector extends Detector<Face> {
3133
private Detector<Face> mDelegate;
3234
public RecognitionInterface recognitionHandler;
3335
public Frame mFrame;
36+
FaceRecognizer mFaceRecognizer; //came from face tracker activity
3437
public Bitmap tmpBitmap;
3538

3639

@@ -42,9 +45,10 @@ public class CustomDetector extends Detector<Face> {
4245
private int faceid;
4346
private int x, y, w, h;
4447

45-
CustomDetector(Detector<Face> delegate)
48+
CustomDetector(Detector<Face> delegate, FaceRecognizer faceRecognizer)
4649
{
4750
mDelegate = delegate;
51+
mFaceRecognizer = faceRecognizer; //loadNative should be already called
4852
}
4953

5054
void startRecognition(int faceId, int _x, int _y, int _w, int _h) {
@@ -94,7 +98,7 @@ public SparseArray<Face> detect(Frame frame) {
9498
mT = new Thread(new Runnable() {
9599
@Override
96100
public void run() {
97-
String res = test(cropped);
101+
String res = mFaceRecognizer.recognizeNative2(cropped);
98102
recognitionHandler.onRecognized(res);
99103
}
100104
});
@@ -116,7 +120,4 @@ public boolean isOperational() {
116120
public boolean setFocus(int id) {
117121
return mDelegate.setFocus(id);
118122
}
119-
120-
121-
public native String test(Bitmap bmp);
122123
}

0 commit comments

Comments
 (0)