I need a simple way of detecting faces in my Camera app. All I care about is a callback saying that a face was detected in certain place or with coordinates where it was detected on the preview. I've noticed that there seem to be several face detection APIs - in Google Play services and in both legacy and camera2 APIs. Which one should I use for the simple requirement described above?
1 Answers
The legacy version is older, and has much lower accuracy than the new Google Play services API.
The camera2 API depends upon face detection capabilities built into the camera hardware, so it isn't necessarily available on all devices. I have not done an exhaustive comparison, but I think that the accuracy is also lower than that of the new Google Play services API.
See this tutorial for using the Google Play services API for tracking faces in the camera preview:
https://developers.google.com/vision/face-tracker-tutorial
The callback that you'd define would be a subclass of Tracker, similar to the GraphicFaceTracker in the tutorial.
If you don't need to track faces or you have other code that manages the camera, you can call the face detector directly like this:
Frame frame = Frame.Builder().setBitmap(myBitmap).build();
SparseArray<Face> faces = faceDetector.detect(frame);
See for information here:
https://developers.google.com/android/reference/com/google/android/gms/vision/package-summary

- 2,862
- 14
- 16
-
Thanks. Had a look at both Play and legacy APIs and using the Play one is really not straight forward especially if you have your own camera controller class and don't use CameraSource. Tried implementing same logic as the open source CameraSource for my code but there seems to be a bug in it.. After a few hours ended up using legacy APIs anyway.. – vkislicins Feb 02 '16 at 09:26
-
I added more information above on how to call the face detector directly. Was there anything in particular that you found not straight forward about the API? – pm0733464 Feb 02 '16 at 15:14
-
The problem I'm getting is from using the same logic in my camera controller as the one in CameraSource (https://github.com/googlesamples/android-vision/blob/master/visionSamples/barcode-reader/app/src/main/java/com/google/android/gms/samples/vision/barcodereader/ui/camera/CameraSource.java). There's a map for holding frames and retrieving from it always gives null (line 1124 in the source above). There is an issue raised on the sample code which is related: https://github.com/googlesamples/android-vision/issues/60 – vkislicins Feb 02 '16 at 17:47
-
I'd suggest trying the workaround that I suggested on github. For that case, I believe this was a temporary effect of receiving old image buffers for the first few frames when the camera source is restarted. In your case, I'd guess that it could be the same issue, it could be that the map wasn't populated, or it could be that the buffers weren't ever registered with the camera. – pm0733464 Feb 02 '16 at 21:17
-
Thanks, I'll revisit it. I got the impression that the workaround was only to prevent the crash with NullPointer, but the data is always null and therefore the code sits in the while loop and doesn't leak to the area where it null points, however no data is ever gathered and therefore passed down to the detector. From debugging I could see the map was populated however get was not finding the same frame... Will have another look. – vkislicins Feb 03 '16 at 11:50