如何用Android CameraX ImageAnalysis提高帧率?

12 人关注

我正在调查新的CameraX API,以了解从我们目前的Camera2系统转换过来的可行性。

在我们的Camera2系统中,我们使用OpenGL表面来捕捉PreviewCaptureSession中的帧,我们在大多数设备上都达到了一致的30fps的图像处理速度,有些设备在启用自动曝光设置后可以达到60fps。

CameraX没有提供任何接近这个速度的东西,我不知道是不是我在设置中遗漏了什么。

我已经为CameraX和ImageAnalysis设置了测试实例,但我得到的是锁定帧率的图像数量。

例如,我可以将分辨率设置为低至320x240,高至1920x960,都会以16fps的速度出来(似乎有上限)。

当我添加一个预览用例来运行它,并设置启用Torch(true),ImageAnalysis用例将突然开始得到更多的像20fps,它偶尔会达到30左右的峰值。

显然,预览的用例改变了相机的一些自动曝光状态?

这是我目前设置的一个片段......

 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)

有没有办法改变CameraX中围绕ImageAnalysis的相机设置,以获得更高的帧率?

事实上,是否有办法改变诸如传感器持续时间、ISO、曝光之类的东西?

android
android-camera
android-camerax
Iain Stanford
Iain Stanford
发布于 2019-08-14
4 个回答
Iain Stanford
Iain Stanford
发布于 2021-08-02
已采纳
0 人赞同

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

事实证明,ImageAnalysisConfig是不可扩展的,所以当你只使用其中一个时,你不能改变相机配置,所以将使用默认的相机设置,在我的手机上,我认为这导致AE被打开,并达到16左右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)

因此,这在ImageAnalyser中开始打出30fps的好成绩。

如果我想打60分,我可以设定...

.setCaptureRequestOption(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF)
.setCaptureRequestOption(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, Range(60,60))

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

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

我到底要在哪里添加这个?我想我们需要通过调用将初始化的camera2Extender对象传递给其他函数/构件?
另外,我假设这只是增强了预览面的帧率,而不是图像分析的情况,因为这将直接取决于我们在分析器的分析覆盖方法中手动进行的处理量。你怎么能说它开始反映你在这里设置的帧率?
另外,我在最新的版本中看不到 Extender 的同伴; 1.1.0-beta01 是我正在使用的,它不是最新的,但足够接近。
Miramur
Miramur
发布于 2021-08-02
0 人赞同

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

根据Ian对CameraX最新版本的回答,你现在可以直接扩展ImageAnalysis。请看 CameraX相当于Camera2的CaptureRequest

因此,为了获得60FPS,我们可以使用这个修改后的代码(以Java和Kotlin为例)。

// Java

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();

// Kotlin

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()
    
在三星Galaxy S8的自拍相机中试了一下,没有成功,只要我添加这些参数,预览就会变成黑色,分析似乎不再真正获得帧,即使我允许一个较低的范围(例如10到60而不是60到60)。
GTnik
GTnik
发布于 2021-08-02
0 人赞同

不幸的是,Iain Stanford的回答并没有帮助我。我的应用程序在向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)

I got this error:

IllegalArgumentException: Unsupported session configuration combination

但是,幸运的是,我找到了在Pixel 2 XL上获得60 FPS的另一种方法。我把一些代码从here.不幸的是,只有当我把预览画成TextureView时它才起作用。如果我不使用AutoFitPreviewBuilder函数,不把预览画成TextureView,所有的Extender设置都会被忽略。

So, my code:

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)

其中AutoFitPreviewBuilder是函数来自android repo的例子 and viewFinder is TextureView, imageAnalysis is ImageAnalysisConfig.Builder().build and createImagePreviewConfig() returns PreviewConfig.Builder(). Btw, do not forget to set max resolution for camera in ImageAnalysisConfig & PreviewConfig:

.setMaxResolution(Size(800, 800))

Hope, it will help you.