Search code examples
javaandroidandroid-cameraandroid-camera2

How to trigger manual autofocus in camera2 API?


The deprecated camera API offered for the Camera object the function autofocus() with which we could increase the focus of the preview/capture after detecting that the frames/images we got are blurry.

Now we updated our app to use the camera2 API and still trying to figure out how we could manually trigger the camera to autofocus. For initialization of the preview we are using the following code:

// When the session is ready, we start displaying the preview.
mCaptureSession = cameraCaptureSession;
try {
    // Auto focus should be continuous for camera preview.
    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
            CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
    // Flash is automatically enabled when necessary.
    setAutoFlash(mPreviewRequestBuilder);

    // Finally, we start displaying the camera preview.
    mPreviewRequest = mPreviewRequestBuilder.build();
    mCaptureSession.setRepeatingRequest(mPreviewRequest,
            mCaptureCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
    e.printStackTrace();
}

Later when accessing the capture frames whe analyse the image quality and if its too blurry we would like to trigger the autofocus again to increase the result quality:

private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
        = new ImageReader.OnImageAvailableListener() {

    @Override
    public void onImageAvailable(ImageReader reader) {
        Log.e(TAG, "Image captured!");
        Image image = reader.acquireLatestImage();
        float focusScore = analyseImage(image);
        if(focusScore < 10) {
          // Here we would like to trigger some focus functionality
        } else {
          // Take the result frame as good enough and proceed
        }

        image.close();
    }
};


Update: The following answer also helped me implementing a solution for this problem: link


Solution

  • Set the CONTROL_AF_TRIGGER capture request field to START for one request to trigger autofocus action.

    What that action is depends on the AF mode; for continuous picture mode, AF generally is locked if it believes to be in focus already. If AF isn't converged, it will try to converge quickly and then lock AF. The lock persists until AF_TRIGGER is set to CANCEL for one request (or the AF mode is changed).

    So if you want to trigger a full AF sweep, you might want to switch to AF_MODE_AUTO and then trigger, since continuous focus trigger doesn't necessarily rescan the scene.