简体   繁体   English

Android CameraX 分析图像 stream

[英]Android CameraX analyse image stream

I want to analyse a stream of image frames and do some computation on it.我想分析 stream 图像帧并对其进行一些计算。 However, with CameraX, the ImageAnalysis implementation class seems to get called only once - on camera bind.但是,对于 CameraX,ImageAnalysis 实现 class 似乎只被调用一次 - 在相机绑定时。

My question is: How do I run the analysis on a continuous stream of images - conceptually akin to a video stream?我的问题是:如何对连续的 stream 图像运行分析 - 在概念上类似于视频 stream?

Following is my camera, preview and analysis setup code:以下是我的相机、预览和分析设置代码:

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

}

Following is my ImageAnalysis implementation class:以下是我的 ImageAnalysis 实现 class:

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

    }
}

I found the problem.我发现了问题。 At the end of the在结束时

  public void analyze(@NonNull ImageProxy image) {}

method, you'd need to call image.close().方法,你需要调用 image.close()。 Quoting from the documentation :引用文档

Before returning from analyze(), close the image reference by calling image.close() to avoid blocking the production of further images (causing the preview to stall) and to avoid potentially dropping images.在从 analyze() 返回之前,通过调用 image.close() 来关闭图像引用以避免阻止更多图像的生成(导致预览停止)并避免潜在的图像丢失。 The method must complete analysis or make a copy instead of passing the image reference beyond the analysis method.该方法必须完成分析或制作副本,而不是将图像参考传递到分析方法之外。

Close the ImageProxy object, not the image, as stated on the Image analysis Doc关闭ImageProxy object,而不是图像,如图像分析文档中所述

Release the ImageProxy to CameraX by calling ImageProxy.close().通过调用 ImageProxy.close() 将 ImageProxy 释放到 CameraX。 Note that you shouldn't call the wrapped Media.Image's close function (Media.Image.close()).请注意,您不应调用包装的 Media.Image 的关闭 function (Media.Image.close())。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM