Android CameraX 分析图像流

Deb*_*ebD 4 java android android-camera kotlin android-camerax

我想分析图像帧流并对其进行一些计算。但是,对于 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));

}
Run Code Online (Sandbox Code Playgroud)

以下是我的 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());

    }
}
Run Code Online (Sandbox Code Playgroud)

Deb*_*ebD 8

我发现了问题。在结束时

  public void analyze(@NonNull ImageProxy image) {}
Run Code Online (Sandbox Code Playgroud)

方法,你需要调用 image.close()。从文档中引用:

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