0

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();
    }
}
Rafael T
  • 15,401
  • 15
  • 83
  • 144

0 Answers0