【问题标题】:How can I detect when the camera has finished initialising its exposure?如何检测相机何时完成初始化曝光?
【发布时间】:2014-12-10 10:23:52
【问题描述】:

背景

当我启动相机预览时,尤其是在室内时,使用takePicture 拍摄的预览帧和照片最初是黑暗的。在下一秒,相机的曝光会自动调整,直到曝光达到最佳。当我在手机上打开相机应用程序时也会出现这种情况。

问题

一旦曝光合适,我会尽快拍照。最好我可以注册一个回调,以便在曝光良好时调用。我该怎么做?

我尝试过的

  • 将相机的曝光补偿配置为最大值。 (没有帮助;在预览开始后,相机仍然需要大约一秒钟才能正确曝光。)
  • 自动对焦 API,但由于相机不支持自动对焦,因此它们不起作用。
  • 硬编码延迟一秒以等待曝光。这是次优的,因为在室外日光下,不需要这么多时间。

【问题讨论】:

  • 我自己没试过,但是从getExposureCompensation获取值呢?如果仍为 0,则可能尚未执行曝光调整。 (如果默认情况下不需要进行曝光调整,这将无济于事,因此您需要对此进行另一次检查。)这只是来自阅读文档,而不是实际经验,所以我只是把它扔了在那里。
  • @JASONGPETERSON,是的;我不久前尝试过,getExposure* 方法返回0,不管相机使用的曝光(或曝光补偿)如何。

标签: android camera android-camera


【解决方案1】:

旧相机 API

很遗憾,带有旧版相机驱动程序的设备似乎不支持这一点。所以最好的选择似乎是开始预览,然后等待大约一秒钟。

camera2API

使用camera2 API,您可以通过检查CaptureResult.CONTROL_AE_STATE 的值来检查自动曝光状态。

示例代码

首先开始捕获:

// Auto-exposure only seems to start after the first picture has been taken
// And on the Pixel 3 XL, it finishes fastest when you make a lot of captures
captureSession.setRepeatingRequest(request, captureCallback, null);

并使用此样板代码来监控自动曝光:

private CaptureResult firstResult;

private final CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {

    @Override
    public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
        super.onCaptureCompleted(session, request, result);

        if (firstResult == null)
            firstResult = result;

        boolean aeAcquired;
        Integer aeState = lastResult.get(CaptureResult.CONTROL_AE_STATE);
        if (aeState == null) {
            // This camera doesn't support monitoring of auto-exposure, so we'll just have to wait a bit and then assume it's adjusted.
            long nanosSinceFirstResult = result.get(CaptureResult.SENSOR_TIMESTAMP) - firstResult.get(CaptureResult.SENSOR_TIMESTAMP);
            long millisSinceFirstResult = nanosSinceFirstResult / 1000 / 1000;
            aeAcquired = millisSinceFirstResult >= 750;
        } else {
            aeAcquired = aeState == CameraMetadata.CONTROL_AE_STATE_CONVERGED || aeState == CameraMetadata.CONTROL_AE_STATE_FLASH_REQUIRED;
        }

        if (aeAcquired) {
            // Auto-exposure has finished
        }   
    }

};

【讨论】:

    猜你喜欢
    • 2016-01-06
    • 2020-07-24
    • 1970-01-01
    • 1970-01-01
    • 2018-09-16
    • 1970-01-01
    • 2020-11-01
    • 2014-09-24
    • 1970-01-01
    相关资源
    最近更新 更多