如何使用 Android CameraX ImageAnalysis 提高帧率?

Iai*_*ord 8 android android-camera android-camerax

我正在研究新的 CameraX API,以了解从我们当前的 Camera2 系统切换的可行性。

在我们的 Camera2 系统中,我们使用 OpenGL 表面从 PreviewCaptureSession 捕获帧,并且我们在大多数设备上达到一致的 30fps 图像处理速度,有些能够在启用 AutoExposure 设置的情况下达到 60fps。

CameraX 没有提供接近该速度的任何东西,我不确定它是否是我在设置中遗漏的东西。

我已经为 CameraX 和 ImageAnalysis 设置了测试示例,但是我正在锁定通过图像数量的帧速率。

例如,我可以将分辨率设置为低至 320x240 到 1920x960,并且两者都会以(看似上限)16fps 的速度出现。

当我添加一个预览用例与它一起运行并设置 enableTorch(true) 时,ImageAnalysis 用例将突然开始变得更像 20fps,它偶尔会达到 30ish。

显然预览用例改变了相机的一些 AutoExposure 状态?

这是我当前设置的狙击手......

 private fun startCameraAnalysis() {
        val metrics = DisplayMetrics().also { viewFinder.display.getRealMetrics(it) }
        var resolution = Size(metrics.widthPixels, metrics.heightPixels)
        resolution = Size(640, 480) //set to fixed size for testing

        val aspectRatio = Rational(resolution.width, resolution.height)
        val rotation = viewFinder.display.rotation

        // Setup image analysis pipeline
        val analyzerConfig = ImageAnalysisConfig.Builder().apply {
            val analyzerThread = HandlerThread(
                "LuminosityAnalysis").apply { start() }
            setCallbackHandler(Handler(analyzerThread.looper))
     setImageReaderMode(ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE)
            setTargetRotation(rotation)
            setTargetAspectRatio(aspectRatio)
            setTargetResolution(resolution)
        }.build()

        // Setup preview pipeline
        val previewConfig = PreviewConfig.Builder().apply {
            setTargetRotation(rotation)
            setTargetAspectRatio(aspectRatio)
            setTargetResolution(resolution)
        }.build()

        // Build Preview useCase
        val preview = Preview(previewConfig)
        preview.enableTorch(true)

        // Build Analysis useCase
        val analyzer = ImageAnalysis(analyzerConfig)
        analyzer.analyzer = LuminosityAnalyzer()

        CameraX.bindToLifecycle(this, preview, analyzer )
        preview.enableTorch(true)
}
Run Code Online (Sandbox Code Playgroud)

无论如何,是否可以在 ImageAnalysis 周围更改 CameraX 中的相机设置以获得更高的帧速率?

无论如何,实际上是否可以改变诸如传感器持续时间、ISO、曝光之类的东西?

Iai*_*ord 10

所以我花了更多的时间进行调查,我想我现在已经想出了一个解决方案。

事实证明,ImageAnalysisConfig 不可扩展,因此仅使用其中之一时您无法更改相机配置,因此将使用默认相机设置,我认为这会在我的手机上导致 AE 开启并达到 16ish FPS。

如果您同时启动一个 PreviewConfig 以与它一起运行,那么您可以使用 Camera2Config.Extender 扩展它并直接更改 camera2 属性。这可以提高相机预览帧速率,并且分析器也将开始以相同的速率获取帧。

例如,我将它添加到我的 PreviewConfig 中...

    // Create Camera2 extender
    var camera2Extender = Camera2Config.Extender(previewConfig)
        .setCaptureRequestOption(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF)
        .setCaptureRequestOption(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF)
        .setCaptureRequestOption(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF)
        .setCaptureRequestOption(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_OFF)
        .setCaptureRequestOption(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH)
        .setCaptureRequestOption(CaptureRequest.SENSOR_SENSITIVITY, 100)
        .setCaptureRequestOption(CaptureRequest.SENSOR_FRAME_DURATION, 16666666)
        .setCaptureRequestOption(CaptureRequest.SENSOR_EXPOSURE_TIME, 20400000)
Run Code Online (Sandbox Code Playgroud)

所以这开始在 ImageAnalyser 中达到 30fps。

如果我想打到60,我可以设置...

.setCaptureRequestOption(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF)
.setCaptureRequestOption(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, Range(60,60))
Run Code Online (Sandbox Code Playgroud)

显然假设设备支持 (60,60) 目标 FPS 范围。

所以看起来完整的 Camera2 逻辑在 CameraX 中仍然可用,只是有点笨拙,它有点隐藏在 Camera2Config 扩展器中,这仅适用于预览用例。


GTn*_*nik 5

不幸的是,伊恩·斯坦福的回答对我没有帮助。将以下任何行添加到 Camera2Config.Extender 后,我的应用程序崩溃了:

.setCaptureRequestOption(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF)
.setCaptureRequestOption(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF)
.setCaptureRequestOption(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF)
.setCaptureRequestOption(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_OFF)
Run Code Online (Sandbox Code Playgroud)

我收到这个错误:

IllegalArgumentException: Unsupported session configuration combination
Run Code Online (Sandbox Code Playgroud)

但幸运的是,我找到了一种在 Pixel 2 XL 上以另一种方式获得 60 FPS 的方法。从这里获取了一些代码。不幸的是,只有当我将预览绘制为TextureView时它才有效。如果我不使用 AutoFitPreviewBuilder 函数并且不将预览绘制为TextureView,则所有扩展器设置都将被忽略。

所以,我的代码:

imageAnalysis = ImageAnalysis(createImageAnalysisConfig())

val previewConfig  = createImagePreviewConfig()
Camera2Config.Extender(previewConfig)
    .setCaptureRequestOption(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, Range(60, 60))             
    .setCaptureRequestOption(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 1)

val preview = AutoFitPreviewBuilder.build(previewConfig.build(), viewFinder)

CameraX.bindToLifecycle(lifecycleOwner, imageAnalysis, preview)
preview.enableTorch(true)
Run Code Online (Sandbox Code Playgroud)

其中 AutoFitPreviewBuilder 是android repo 示例中的函数,viewFinder 是 TextureView,imageAnalysis 是 ImageAnalysisConfig.Builder().build,createImagePreviewConfig() 返回 PreviewConfig.Builder()。顺便说一句,不要忘记在 ImageAnalysisConfig 和 PreviewConfig 中设置相机的最大分辨率:

.setMaxResolution(Size(800, 800))
Run Code Online (Sandbox Code Playgroud)

希望,它会对你有所帮助。


小智 5

好吧,这让我疯狂了几个小时。

扩展 Ian 对最新版本 CameraX 的回答,您现在可以直接扩展 ImageAnalysis。请参阅CameraX 等效于 Camera2 的 CaptureRequest

所以为了获得 60FPS,我们可以使用这个修改后的代码(Java 和 Kotlin 中的示例):

// 爪哇

ImageAnalysis.Builder builder = new ImageAnalysis.Builder();
Camera2Interop.Extender ext = new Camera2Interop.Extender<>(builder);
ext.setCaptureRequestOption(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
ext.setCaptureRequestOption(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, new Range<Integer>(60, 60));
ImageAnalysis imageAnalysis = builder.build();
Run Code Online (Sandbox Code Playgroud)

// 科特林

val builder = ImageAnalysis.Builder()
val ext: Camera2Interop.Extender<*> = Camera2Interop.Extender(builder)
ext.setCaptureRequestOption(
                CaptureRequest.CONTROL_AE_MODE,
                CaptureRequest.CONTROL_AE_MODE_OFF
            )
ext.setCaptureRequestOption(
                CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,
                Range<Int>(60, 60)
            )
val imageAnalysis = builder.build()
Run Code Online (Sandbox Code Playgroud)

  • 在三星 Galaxy S8 自拍相机中尝试过此操作,但不起作用,一旦我添加这些参数,预览就会变黑,并且分析似乎实际上不再获得帧,即使我允许较低的范围(例如10 到 60 而不是 60 到 60) (3认同)