Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android CameraX analyse image stream

I want to analyse a stream of image frames and do some computation on it. However, with CameraX, the ImageAnalysis implementation class seems to get called only once - on camera bind.

My question is: How do I run the analysis on a continuous stream of images - conceptually akin to a video 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:

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

    }
}
like image 308
DebD Avatar asked Jun 07 '20 18:06

DebD


People also ask

What is CameraX preview?

↳ androidx.camera.core.Preview. A use case that provides a camera preview stream for displaying on-screen. The preview stream is connected to the Surface provided via SurfaceProvider . The application decides how the Surface is shown, and is responsible for managing the Surface lifecycle after providing it.

What is bindToLifecycle?

bindToLifecycle() . That lifecycle then informs CameraX when to configure the camera capture session and ensures camera state changes appropriately to match lifecycle transitions. For implementation steps for each use case, see Implement a preview, Analyze images, Image capture, and Video capture.


1 Answers

I found the problem. At the end of the

  public void analyze(@NonNull ImageProxy image) {}

method, you'd need to call 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. The method must complete analysis or make a copy instead of passing the image reference beyond the analysis method.

like image 161
DebD Avatar answered Oct 05 '22 01:10

DebD