I have created a computer vision app for Android. I use the front camera to capture images on which I apply my algorithms. On my Samsung Galaxy S8, I observed that when I put objects in front of the camera, the focal length changes with the autofocus (it keeps zooming in and out). This is a problem because it creates unwanted changes in the image which temper with my algorithm. How can I determine a reasonable value for the focal length and then force the sensor to keep it fixed without disabling the auto-focus?
Here is my code for setting up the camera acquisition.
private void createCameraPreviewSession() throws CameraAccessException {
mCameraDevice.createCaptureSession(Arrays.asList(mImageReader.getSurface()),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
if (null == mCameraDevice) {
return;
}
mCaptureSession = cameraCaptureSession;
try {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), null, mBackgroundHandler);
} catch (Exception e) {
Log.e(Config.tag, "createCaptureSession failed", e);
}
}
@Override
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
Log.e(Config.tag, "createCameraPreviewSession failed");
}
},
null
);
}
private void createImageReader() throws CameraAccessException
{
mImageReader = ImageReader.newInstance(mFrameSize.getWidth(), mFrameSize.getHeight(),
mPreviewFormat, 2);
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
if (mCaptureSession == null) {
return;
}
Image image = reader.acquireLatestImage();
if (image == null) {
return;
}
//do something with the image
image.close();
}
}, mBackgroundHandler);
Surface surface = mImageReader.getSurface();
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(surface);
}
I figured that using CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE is the mode which tries to constantly keep the image in focus. In my case, on some high-end devices with more than one frontal lenses, this could result in switching between lenses. I just changed the auto-focus mode to CaptureRequest.CONTROL_AF_MODE_AUTO and the auto-focus stopped constantly changing the focus. In addition, I used the CaptureRequest.CONTROL_AE_LOCK option to lock and unlock the auto-exposure at critical moments to avoid unwanted exposure changes.