图片分析

图片分析用例为您的应用提供可供 CPU 访问的图片来执行图片处理、计算机视觉或机器学习推断。应用会实现对每个帧运行的 analyze() 方法。

实现

通过将执行图片分析的执行程序和 ImageAnalysis.Analyzer 参数传递到 setAnalyzer() 方法来处理图片。不管任何时候,您只能注册一个分析器:注册新的分析器会替换现有分析器。

本主题中的代码示例展示了如何执行此操作,以及如何将图片分析用例和预览用例绑定到 LifecycleOwner。如需了解如何创建预览用例,请参阅实现预览

图片分析可以分为两种模式:阻塞模式和非阻塞模式。通过使用 STRATEGY_BLOCK_PRODUCER 调用 setBackpressureStrategy() 可以启用阻塞模式。在此模式下,执行器会依序从相应相机接收帧;这意味着,如果 analyze() 方法所用的时间超过单帧在当前帧速率下的延迟时间,所接收的帧便可能不再是最新的帧,因为在该方法返回之前,新帧会被阻止进入流水线。

通过使用 STRATEGY_KEEP_ONLY_LATEST 调用 setBackpressureStrategy() 可以启用非阻塞模式。在此模式下,执行程序在调用 analyze() 方法时会从相机接收最新的可用帧。如果此方法所用的时间超过单帧在当前帧速率下的延迟时间,它可能会跳过某些帧,以便 analyze() 在下一次接收数据时获取相机流水线中的最新可用帧。

analyze() 返回前,请通过调用 image.close() 关闭图像引用,以避免阻塞其他图像的生成(导致预览停顿)并避免可能出现的图像丢失。此方法必须完成分析或创建副本,而不是超出分析方法之外传递图像引用。

Kotlin

val imageAnalysis = ImageAnalysis.Builder()
    .setTargetResolution(Size(1280, 720))
    .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
    .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
    .build()

imageAnalysis.setAnalyzer(executor, ImageAnalysis.Analyzer { image ->
    val rotationDegrees = image.imageInfo.rotationDegrees
    // insert your code here.
})

cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, imageAnalysis, preview)

Java

ImageAnalysis imageAnalysis =
    new ImageAnalysis.Builder()
        .setTargetResolution(new Size(1280, 720))
        .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
        .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
        .build();

imageAnalysis.setAnalyzer(executor, new ImageAnalysis.Analyzer() {
    @Override
    public void analyze(@NonNull ImageProxy image) {
        int rotationDegrees = image.getImageInfo().getRotationDegrees();
            // insert your code here.
        }
    });

cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, imageAnalysis, preview);

默认情况下,CameraX 会采用 OUTPUT_IMAGE_FORMAT_YUV_420_888 格式设置图片。

应用可以使用 ImageProxy::getFormat() 函数检查由 CameraX 传入的 ImageProxy 的颜色空间。如果返回 ImageFormat.YUV_420_888,则表示该图片采用 YUV 颜色空间。如果返回 PixelFormat.RGBA_8888,则表示该图片采用 RGBA 颜色空间。

YUV 输出格式适用于所有 camera-core 版本。RGBA 输出格式适用于 camera-core:1.1.0-alpha09 及更高版本,仅适用于图片分析用例。

设置 RGBA 输出格式时,CameraX 会在内部将图片从 YUV 空间转换为 RGBA 空间,并将图片位存储在 ImageProxy 第一个平面(其他平面未使用)的 ByteBuffer中,序列如下:

ImageProxy::planes[0].buffer[0]: alpha
ImageProxy::planes[1].buffer[1]: red
ImageProxy::planes[2].buffer[2]: green
ImageProxy::planes[3].buffer[3]: blue
...

颜色转换是 YUV 输出格式的附加步骤,转换时间会计入图片分析总时间。执行实时分析时,应用的每帧处理时间将减少。在应用需要 RGBA 输出时,您应使用颜色转换步骤。

其他资源

要详细了解 CameraX,请参阅下面列出的其他资源。

Codelab

  • CameraX 使用入门
  • 代码示例

  • 官方 CameraX 示例应用