Search code examples
androidface-detection

Capturing camera frame in android after face detection


I am working with face detection in Android and I want achieve the following:
1. Use face detection listener in Android for detecting faces on camera frame.
2. If a face is detected on the camera frame, then extract the face and save it to external storage.

After surfing through existing questions, I have found that there is no direct way to convert detected face to bitmap and store it on the disk. So now I want to capture and save the entire camera frame in which the face has been detected and I have not been able to do so.

The current code structure is as follows:

FaceDetectionListener faceDetectionListener = new FaceDetectionListener() {

    @Override
    public void onFaceDetection(Face[] faces, Camera camera) {

        if (faces.length == 0) {
        } else {
            displayMessage("Face detected!");   
            // CODE TO SAVE CURRENT FRAME AS IMAGE
            finish();
        }
    }
};

I tried to achieve this by calling takePicture in the above method but I was unable to save the frame using that approach. Kindly suggest a way in which I can save the camera frame.


Solution

  • I could not figure out a direct way to save the camera frame within FaceDetectionListener. Therefore, for my application, I changed the way in which I was handling the camera preview data. I used the PreviewCallback interface of Camera class and implemented the logic in onPreviewFrame method of the interface. The outline of implementation is as follows:

    class SaveFaceFrames extends Activity implements Camera.PreviewCallback, Camera.FaceDetectionListener {
    
        boolean lock = false; 
    
        public void onPreviewFrame(byte[] data, Camera camera) {
            ...
            if(lock) {
                Camera.Parameters parameters = camera.getParameters();
                Camera.Size size = parameters.getPreviewSize();
                YuvImage image = new YuvImage(data, parameters.getPreviewFormat(), size.width, size.height, null);
                ByteArrayOutputStream outstr = new ByteArrayOutputStream();
                image.compressToJpeg(new Rect(0, 0, image.getWidth(), image.getHeight()), 100, outstr);
                Bitmap bmp = BitmapFactory.decodeByteArray(outstr.toByteArray(), 0, outstr.size());
                lock = false;
            }
        }
    
        public void onFaceDetection(Camera.Face[] faces, Camera camera) {
            ...
            if(!lock) {
                if(faces.length() != 0) lock = true;
            }
        }
    }
    

    This is not an ideal solution, but it worked in my case. There are third party libraries which can be used in these scenarios. One library which I have used and works very well is Qualcomm's Snapdragon SDK. I hope someone finds this useful.