Android CameraX 分析图像流

Posted

技术标签:

【中文标题】Android CameraX 分析图像流【英文标题】:Android CameraX analyse image stream 【发布时间】:2020-09-26 16:46:26 【问题描述】:

我想分析图像帧流并对其进行一些计算。但是,对于 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 【参考方案1】:

我发现了问题。 在结束时

  public void analyze(@NonNull ImageProxy image) 

方法,你需要调用 image.close()。引用自documentation:

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

【讨论】:

有效!谢谢。 Alpha 和 Beta 版本是完全不同的实现。

以上是关于Android CameraX 分析图像流的主要内容,如果未能解决你的问题,请参考以下文章

Android CameraX 图像旋转

Camerax 图像分析:将图像转换为 bytearray 或 ByteBuffer

Android CameraX使用,预览拍照获取静态图像

Android实战图像识别:Compose + MLKit + CameraX

Android CameraX 多个分析器

Android 使用CameraX实现预览/拍照/录制视频/图片分析/对焦/缩放/切换摄像头等操作