将 CameraX ImageAnalysis 的启动与其他代码同步

问题描述

问题

是否有任何优雅的方式将 CameraX 的 ImageAnalysis 用例的开始与其他代码同步?请参阅下面的详细信息,了解我如何定义“优雅”。

问题

ImageAnalyzer.setAnalyzer()调用analyzer() 的第一次调用之间似乎有很长的启动时间。从快速浏览源代码来看,这似乎是在为目标 SDK 选择合适的相机硬件等。

我有其他“分析器”在不同的声音线程和其他传感器中运行,我正在尝试同步它们,以便在所有“分析器”准备好提供数据之前我不会开始记录数据。就我而言,相机数据在前几个时间步长始终为空,而其他传感器已准备就绪并提供数据。所以理想情况下,我想要一种在记录来自其他传感器的数据之前等待 analyzer() 的第一次调用方法。我已经为其他传感器很好地实现了这一点,但找不到一种优雅的方式来指示何时调用analyze() 方法。请参阅下面的“尝试的解决方案”部分,了解我认为我目前的尝试不够优雅。

尝试的解决方

我首先查看了 ImageAnalysis ClassImageAnalysis.Builder ClassImageAnalysis.Analyzer Interface 的相关文档,以了解某种回调函数,这表明它已准备好在设置所有相机后盖后进行分析-结束的东西,但我没有找到任何相关的东西。我正在寻找可以在 analyze() 上的第一次调用之前直接调用的东西。

我试图让它与 CountDownLatch 一起工作,因为这是我用来同步其他传感器的东西,但找不到关于在哪里调用 countDown() 方法的令人满意的解决方案.

有关代码片段,请参阅下面的示例部分。我想在 countDown()调用 analyze() 但后来我必须将它放在 if 语句中并测试它是否是每次分析图像时对 analyze() 的第一次调用。我需要进行测试以验证这一说法,但我认为这不会非常有效,尤其是在我所处的低延迟用例中。

如果我忽略了一个 if 语句,而仅仅依赖于 countDown() 方法在计数已经为零的情况下“什么都不做”的能力,那么可能会出现两个问题:

1.) analyze() 方法可以被多次调用,因此 countDown() 方法在我的其他传感器调用 countDown() 之前,我可以过早地开始记录其他传感器。 2.) CountDownLatch 在使用完毕后将无法被垃圾回收。 (我确定这不是一个巨大的内存问题,但只是认为保持对象的时间超过我需要的时间并不是一个好习惯)。

示例

public class ImageDataGatherer implements ImageAnalysis.Analyzer{

    private final timestepDataBuffer timestepDataBuffer;
    private final YuvToRgbConverter yuvToRgbConverter;
    private CountDownLatch countDownLatch;
    private boolean firstCall = true;

    public ImageDataGatherer(Context context,timestepDataBuffer timestepDataBuffer,CountDownLatch countDownLatch){
        this.timestepDataBuffer = timestepDataBuffer;
        yuvToRgbConverter = new YuvToRgbConverter(context);
        this.countDownLatch = countDownLatch;
    }

    @androidx.camera.core.ExperimentalGetimage
    public void analyze(@NonNull ImageProxy imageProxy) {
        Image image = imageProxy.getimage();
        if (image != null) {
            // This if statement doesn't seem like the best way of doing this. 
            if (firstCall){
                firstCall = false;
                countDownLatch.countDown();
            }
            int width = image.getWidth();
            int height = image.getHeight();
            long timestamp = image.getTimestamp();

            Bitmap bitmap = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
            yuvToRgbConverter.yuvToRgb(image,bitmap);

            ByteArrayOutputStream webpByteArrayOutputStream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.WEBP,webpByteArrayOutputStream);
            byte[] webpBytes = webpByteArrayOutputStream.toByteArray();
            Bitmap webpBitMap = ImageOps.generateBitmap(webpBytes);

            timestepDataBuffer.getWriteData().getimageData().add(timestamp,width,webpBitMap,webpBytes);
        }
        imageProxy.close();
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)