Android CameraX 分析图像流

8
我想分析一系列图像帧并进行一些计算。然而,使用CameraX时,ImageAnalysis实现类似乎只在相机绑定时调用一次。
我的问题是:我如何在连续的图像流上运行分析 - 概念上类似于视频流?
以下是我的相机、预览和分析设置代码:
private void setPreview() {
    ListenableFuture<ProcessCameraProvider> instance = ProcessCameraProvider.getInstance(this);

    Activity self = this;
    instance.addListener(() -> {

        try {
            ProcessCameraProvider cameraProvider = instance.get();
            Preview preview = new Preview.Builder().build();


            ImageAnalysis imageAnalysis = new ImageAnalysis.Builder().build();
            imageAnalysis.setAnalyzer(Executors.newFixedThreadPool(1),
                                                    new ImageAnalyser(new CameraLogListener() {
                                                        @Override
                                                        public void log(String msg) {
                                                            Log.e("Camera log", msg);
                                                        }
                                                    }));

            CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();

            cameraProvider.unbindAll();
            Camera camera = cameraProvider.bindToLifecycle(((LifecycleOwner)self), cameraSelector, preview, imageAnalysis);

            preview.setSurfaceProvider(
                    ((PreviewView)findViewById(R.id.cameraTextureView)).createSurfaceProvider(camera.getCameraInfo()));

        } catch (ExecutionException e) {
            e.printStackTrace();
            Log.e("TAG", "Use case binding failed", e);
        } catch (InterruptedException e) {
            e.printStackTrace();
            Log.e("TAG", "Use case binding failed", e);
        }

    }, ContextCompat.getMainExecutor(this));

}

以下是我的ImageAnalysis实现类:
private class ImageAnalyser implements ImageAnalysis.Analyzer {

    CameraLogListener listener;
    public ImageAnalyser(CameraLogListener listener) {
        this.listener = listener;
    }

    @Override
    public void analyze(@NonNull ImageProxy image) {
        ByteBuffer imageBuffer = image.getPlanes()[0].getBuffer();
        StringBuilder sb = new StringBuilder();
        sb.append("format:" + image.getFormat()).append("\n")
            .append(image.getWidth() + " x " + image.getHeight()).append("\n\n");

        for (int i=0; i<image.getPlanes().length; i++) {
            sb.append("pixel stride:").append(image.getPlanes()[i].getPixelStride())
                .append("\nrow stride:").append(image.getPlanes()[i].getRowStride())
                .append("\n");
        }

        listener.log(sb.toString());

    }
}

你在分析后是否获得了适当的FPS,没有任何掉帧?@DebD - Balasubramanian
2个回答

11
我找到了问题。在

的结尾。
  public void analyze(@NonNull ImageProxy image) {}

如果你使用的是该方法,你需要调用image.close()。引用自文档

在从analyze()返回之前,通过调用image.close()关闭图像引用,以避免阻塞进一步图像的生产(导致预览停顿)并避免可能丢失图像。该方法必须完成分析或复制而不是将图像引用传递到分析方法之外。


它运行正常!谢谢。Alpha和beta版本是完全不同的实现。 - Balasubramanian

1

根据图像分析文档所述,关闭ImageProxy对象而不是图像本身。

通过调用ImageProxy.close()将ImageProxy释放给CameraX。请注意,不应调用包装的Media.Image的close函数(Media.Image.close())。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接