如何使用 Android CameraX ImageAnalysis 提高帧率?
How to increase frame rate with Android CameraX ImageAnalysis?
我正在研究新的 CameraX API,了解从我们当前的 Camera2 系统切换过来的可行性。
在我们的 Camera2 系统中,我们使用 OpenGL 表面从 PreviewCaptureSession 捕获帧,并且我们在大多数设备上达到一致的 30fps 图像处理速度,有些设备在启用自动曝光设置的情况下能够达到 60fps。
CameraX 没有提供接近该速度的任何东西,我不确定它是否是我在设置中遗漏的东西。
我已经为 CameraX 和 ImageAnalysis 设置了测试示例,但是对于通过的图像数量,我得到了锁定的帧速率。
例如,我可以将分辨率设置为低至 320x240 到 1920x960,两者都将以(看似上限)16fps 的速度出现。
当我将预览用例添加到 运行 并设置 enableTorch(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)
}
是否可以围绕 ImageAnalysis 更改 CameraX 中的相机设置以获得更高的帧速率?
实际上有没有办法改变传感器持续时间、ISO、曝光等东西?
所以我花了更多时间进行调查,我想我现在已经想出了一个解决方案。
事实证明,ImageAnalysisConfig 是不可扩展的,因此您不能在仅使用其中一个时更改相机配置,因此将使用默认相机设置,这在我的 phone 我认为是这样的结果在 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 扩展程序中,并且这仅适用于预览用例。
不幸的是,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)
我收到这个错误:
IllegalArgumentException: Unsupported session configuration combination
但是,幸运的是,我找到了一种在 Pixel 2 XL 上以另一种方式获得 60 FPS 的方法。从 here 中获取了一些代码。不幸的是,只有当我将 Preview 绘制为 TextureView 时它才有效。如果我使用不使用 AutoFitPreviewBuilder 函数并且不将 Preview 绘制为 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 是 function from android repo examples,viewFinder 是 TextureView,imageAnalysis 是 ImageAnalysisConfig.Builder().build 和 createImagePreviewConfig() returns PreviewConfig.Builder()。顺便说一句,不要忘记在 ImageAnalysisConfig 和 PreviewConfig 中为相机设置最大分辨率:
.setMaxResolution(Size(800, 800))
希望对你有所帮助
好吧,这让我发疯了几个小时。
扩展 Ian 对最新版本 CameraX 的回答,您现在可以直接扩展 ImageAnalysis。参见
因此,为了获得 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();
//科特林
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()
我遇到了同样的问题我只是添加了
.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
我正在研究新的 CameraX API,了解从我们当前的 Camera2 系统切换过来的可行性。
在我们的 Camera2 系统中,我们使用 OpenGL 表面从 PreviewCaptureSession 捕获帧,并且我们在大多数设备上达到一致的 30fps 图像处理速度,有些设备在启用自动曝光设置的情况下能够达到 60fps。
CameraX 没有提供接近该速度的任何东西,我不确定它是否是我在设置中遗漏的东西。
我已经为 CameraX 和 ImageAnalysis 设置了测试示例,但是对于通过的图像数量,我得到了锁定的帧速率。
例如,我可以将分辨率设置为低至 320x240 到 1920x960,两者都将以(看似上限)16fps 的速度出现。
当我将预览用例添加到 运行 并设置 enableTorch(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)
}
是否可以围绕 ImageAnalysis 更改 CameraX 中的相机设置以获得更高的帧速率?
实际上有没有办法改变传感器持续时间、ISO、曝光等东西?
所以我花了更多时间进行调查,我想我现在已经想出了一个解决方案。
事实证明,ImageAnalysisConfig 是不可扩展的,因此您不能在仅使用其中一个时更改相机配置,因此将使用默认相机设置,这在我的 phone 我认为是这样的结果在 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 扩展程序中,并且这仅适用于预览用例。
不幸的是,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)
我收到这个错误:
IllegalArgumentException: Unsupported session configuration combination
但是,幸运的是,我找到了一种在 Pixel 2 XL 上以另一种方式获得 60 FPS 的方法。从 here 中获取了一些代码。不幸的是,只有当我将 Preview 绘制为 TextureView 时它才有效。如果我使用不使用 AutoFitPreviewBuilder 函数并且不将 Preview 绘制为 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 是 function from android repo examples,viewFinder 是 TextureView,imageAnalysis 是 ImageAnalysisConfig.Builder().build 和 createImagePreviewConfig() returns PreviewConfig.Builder()。顺便说一句,不要忘记在 ImageAnalysisConfig 和 PreviewConfig 中为相机设置最大分辨率:
.setMaxResolution(Size(800, 800))
希望对你有所帮助
好吧,这让我发疯了几个小时。
扩展 Ian 对最新版本 CameraX 的回答,您现在可以直接扩展 ImageAnalysis。参见
因此,为了获得 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();
//科特林
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()
我遇到了同样的问题我只是添加了
.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