I'm writing an Android App, that uses the Camera.FaceDetection
as a trigger to process the image. Its isn't necessary but a 'nice to have' which really improves the usability. It is disabled by default when getMaxNumberDetectedFaces
returns <= 0.
The problem I have is, that there are a number of devices, which return a positive int for getMaxNumberDetectedFaces
but then never bother to actually trigger the onFaceDetection
callback. This causes my app to wait forever on a detected Face.
I would need a definitive method to find out, if the hardware actually supports it.
The only thing I came up with is to wait a period (lets say 10 secs), determine that the camera has seen no face since it started the preview, just to try the software FaceDetection. If I detect a Face there I know that the Camera hardware feature is broken somehow.
But this is really not the route I wanna go: I need to transform a NV21 Picture to Bitmap, rotate it, put it into the FaceDetection and see if there is a face.
If there is "really" no Face seen (ie the user points at something else), I have to repeat and still am clueless if the hardware face detection works.
To make it worse, the process of transforming to Bitmap, rotate and detect a face could take up to 4 Secs on older devices, whereas the hardware detector triggers about every 30ms on a Pixel2.
To test on an Implementation error on my side I installed OpenCamera and watched out for Faces with rectangles... with no success. This app seems to have the same problems .
So I'm wondering if the is there a fast and reliable way to find out if there is hardware support for FaceDetection? A computed List with devices which are known to be broken on that feature would also help
Edit: Due to request I add some code
private static final int FACE_SEEN_THRESHOLD = 200;
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.d(TAG, "onPreviewFrame has " + data.length + " bytes");
if (null == mCamera) return; //prevent race conditions
boolean hasFaceDetection = camera.getParameters().getMaxNumDetectedFaces() > 0;
if (!mFaceDetectionEnabled && hasFaceDetection){
camera.startFaceDetection(this);
mFaceDetectionEnabled = true; //prevent call startFaceDetection twice
}
if ((System.currentTimeMillis() - mLastFaceSeen) < FACE_SEEN_THRESHOLD || !hasFaceDetection){
new PreviewTask().execute(data);
}
}
@Override
public void onFaceDetection(Camera.Face[] faces, Camera camera) {
Log.d(TAG, "onFaceDetection: faces=" + (faces == null ? "null" : faces.length));
if (null != faces && faces.length > 0){
mLastFaceSeen = System.currentTimeMillis();
}
}