Android Camera 2 API , Focus Distance and EV Control query

24 Views Asked by At

I'm developing an Android app that requires taking multiple photos at various focal distances, with each focal distance having a range of exposure values for focus stacking and exposure bracketing, aiming for fully focused HDR images. While I've successfully implemented variable focal distances, I'm encountering issues with exposure bracketing: CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION consistently reports 0, regardless of the set values.

AE lock is confirmed to be false, and AE Mode is set to CONTROL_AE_MODE_ON (value 1), which should be correct. The camera's hardware level is FULL, indicating support for these features.

An additional, possibly related issue is that the focus distance sometimes does not adjust as requested.

Relevant Logs:

12:42:18.767  D  Capture completed. Actual focus distance: 2.1311092, Actual EV: 0
12:42:18.767  D  Taking picture with focus distance: 10.0 and EV: -5
12:42:19.675  D  AE Mode: 1, AE Lock: false
12:42:19.675  D  AE State: 1
12:42:19.675  D  Capture completed. Actual focus distance: 2.0181575, Actual EV: 0
12:42:19.676  D  Taking picture with focus distance: 10.0 and EV: 0
12:42:20.615  D  AE Mode: 1, AE Lock: false
12:42:20.615  D  AE State: 1
12:42:20.615  D  Capture completed. Actual focus distance: 2.049798, Actual EV: 0
12:42:20.615  D  Taking picture with focus distance: 10.0 and EV: 5
12:42:21.541  D  AE Mode: 1, AE Lock: false
12:42:21.541  D  AE State: 1
12:42:21.541  D  Capture completed. Actual focus distance: 2.054317, Actual EV: 0
12:42:21.541  D  All pictures taken.

Relevant Code Snippet

private fun takePictureWithFocusDistance(focusDistance: Float) {
        // Reset EV index for each new focus distance
        currentEVIndex = 0
        takePictureWithEV(focusDistance, evValues[currentEVIndex])
    }

    private fun takePictureWithEV(focusDistance: Float, ev: Int) {
        Log.d(TAG, "Taking picture with focus distance: $focusDistance and EV: $ev")
        try {
            val captureBuilder = cameraDevice!!.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE).apply {
                addTarget(imageReader!!.surface)
                set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF)
                set(CaptureRequest.LENS_FOCUS_DISTANCE, focusDistance)
                set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON)
                set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, ev)
            }

            val captureCallback = object : CameraCaptureSession.CaptureCallback() {
                override fun onCaptureCompleted(session: CameraCaptureSession, request: CaptureRequest, result: TotalCaptureResult) {
                    super.onCaptureCompleted(session, request, result)

                    // Retrieve and log the actual focus distance and EV value from the result
                    val actualFocusDistance = result.get(CaptureResult.LENS_FOCUS_DISTANCE)?:"Unknown"
                    val actualEV = result.get(CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION)?:"Unknown"
                    val aeMode = result.get(CaptureResult.CONTROL_AE_MODE)
                    val aeLock = result.get(CaptureResult.CONTROL_AE_LOCK)
                    Log.d(TAG, "AE Mode: $aeMode, AE Lock: $aeLock")
                    val aeState = result.get(CaptureResult.CONTROL_AE_STATE)
                    Log.d(TAG, "AE State: $aeState")

                    Log.d(TAG, "Capture completed. Actual focus distance: ${actualFocusDistance ?: "Unknown"}, Actual EV: ${actualEV ?: "Unknown"}")

                    if (currentEVIndex < evValues.size - 1) {
                        // Move to next EV value if there are more to capture
                        currentEVIndex++
                        takePictureWithEV(focusDistance, evValues[currentEVIndex])
                    } else {
                        // All EVs captured for this focus distance, move to next focus distance
                        currentFocusDistanceIndex++
                        if (currentFocusDistanceIndex < focusDistances.size) {
                            Handler(backgroundThread!!.looper).post {
                                takeSequentialPictures()
                            }
                        } else {
                            completePictureTakingSequence()
                        }
                    }
                }
            }

            captureSession?.capture(captureBuilder.build(), captureCallback, backgroundHandler)
        } catch (e: CameraAccessException) {
            Log.e(TAG, "Error capturing picture with focus distance: $focusDistance and EV: $ev", e)
        }
    }

Questions:

What might be preventing the exposure compensation from applying as expected? Could the focus inconsistency be related to synchronization issues, and would introducing a delay address it, or is there a better approach? I've tested this on Samsung Galaxy S21 5G, running Android Version 13. Any insights or suggestions on what else to check or how to resolve these issues would be greatly appreciated.

0

There are 0 best solutions below