簡體   English   中英

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

[英]How to increase frame rate with Android CameraX ImageAnalysis?

我正在研究新的 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)
}

無論如何,是否可以在 ImageAnalysis 周圍更改 CameraX 中的相機設置以獲得更高的幀速率?

無論如何,實際上是否可以改變諸如傳感器持續時間、ISO、曝光之類的東西?

所以我花了更多的時間進行調查,我想我現在已經想出了一個解決方案。

事實證明,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)

所以這開始在 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 范圍。

所以看起來完整的 Camera2 邏輯在 CameraX 中仍然可用,只是有點笨拙,它有點隱藏在 Camera2Config 擴展器中,這僅適用於預覽用例。

好吧,這讓我瘋狂了幾個小時。

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

// 科特林

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

不幸的是,伊恩斯坦福的回答沒有幫助我。 將這些行中的任何一行添加到 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)

我收到此錯誤:

IllegalArgumentException: Unsupported session configuration combination

但是,幸運的是,我找到了一種在 Pixel 2 XL 上以另一種方式獲得 60 FPS 的方法。 這里拿了一些代碼。 不幸的是,它僅在我將預覽繪制為 TextureView 時才有效。 如果我不使用 AutoFitPreviewBuilder 函數並且不將預覽繪制為 TextureView,則所有 Extender 設置都將被忽略。

所以,我的代碼:

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 示例的函數,viewFinder 是 TextureView,imageAnalysis 是 ImageAnalysisConfig.Builder().build 和 createImagePreviewConfig() 返回 PreviewConfig.Builder()。 順便說一句,不要忘記在 ImageAnalysisConfig 和 PreviewConfig 中為相機設置最大分辨率:

.setMaxResolution(Size(800, 800))

希望,它會幫助你。

我遇到了同樣的問題,我所做的只是在以下行中添加了 .setTargetResolution(Size(1280, 720)) :- val imageAnalyzer = ImageAnalysis.Builder().setTargetResolution(Size(1280, 720)) .build() .also { it.setAnalyzer(cameraExecutor, LuminosityAnalyzer { luma> Log.d(TAG, "Average luminosity: $luma") }) }參考:- https://developer.android.com/training/camerax/configuration

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM