简体   繁体   English

CameraX Image Analysis (with OUTPUT_IMAGE_FORMAT_RGBA_8888) : maxImages (4) 已经被获取,在获取更多之前调用#close

[英]CameraX Image Analysis (with OUTPUT_IMAGE_FORMAT_RGBA_8888) : maxImages (4) has already been acquired, call #close before acquiring more

I am trying to implement a very basic CameraX Image Analysis use case where I would send the images received by the analyzer to a tflite classifier model.我正在尝试实现一个非常基本的 CameraX 图像分析用例,我会将分析器接收到的图像发送到 tflite 分类器模型。 The model only accepting bitmap as inputs I thought I would set OUTPUT_IMAGE_FORMAT_RGBA_8888 when building the ImageAmalysis.该模型只接受位图作为输入,我以为我会在构建 ImageAmalysis 时设置 OUTPUT_IMAGE_FORMAT_RGBA_8888。 Resulting media images are easier to convert to bitmaps than the standard YUV_420_888 ones.生成的媒体图像比标准的 YUV_420_888 更容易转换为位图。 Problem is I get a error : "java.lang.IllegalStateException: maxImages (4) has already been acquired, call #close before acquiring more."问题是我收到一个错误:“java.lang.IllegalStateException:maxImages (4) 已经被获取,在获取更多之前调用 #close。” Usually it would mean I have forgotten to close the imageProxy but it is not the case so I don't know what is wrong with my code.通常这意味着我忘记关闭 imageProxy 但事实并非如此,所以我不知道我的代码有什么问题。 See below:见下文:

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Bitmap;

import android.media.Image;
import android.os.Bundle;
import android.util.Size;

import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ExperimentalGetImage;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.LifecycleOwner;

import com.google.common.util.concurrent.ListenableFuture;

import java.nio.ByteBuffer;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;


public class MainActivity extends AppCompatActivity {

private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;

private Executor analysisExecutor;

private PreviewView previewView;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    analysisExecutor = Executors.newSingleThreadExecutor();

    setContentView(R.layout.activity_main);
    previewView = findViewById(R.id.viewFinder);

    cameraProviderFuture = ProcessCameraProvider.getInstance(this);       

    cameraProviderFuture.addListener(() -> {
        try {
            ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
            cameraProvider.unbindAll();
            bindUseCases(cameraProvider);
        } catch (ExecutionException | InterruptedException e) {
            // No errors need to be handled for this Future.
            // This should never be reached.
        }
    }, ContextCompat.getMainExecutor(this));

}

void bindUseCases(@NonNull ProcessCameraProvider cameraProvider) {

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

    //Preview
    Preview preview = new Preview.Builder()
            .build();
    preview.setSurfaceProvider(previewView.getSurfaceProvider());

    //ImageAnalysis
    ImageAnalysis imageAnalysis =
            new ImageAnalysis.Builder()
                    .setTargetResolution(new Size(1280, 720))
                    .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
                    .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
                    .build();
    imageAnalysis.setAnalyzer(analysisExecutor, new ImageAnalysis.Analyzer() {
        @Override
        @ExperimentalGetImage
        public void analyze(@NonNull ImageProxy imageProxy) {
            //my code to turn media image into a bitmap
            Image img = imageProxy.getImage();
            Image.Plane[] planes = img.getPlanes();
            ByteBuffer buffer = planes[0].getBuffer();
            int pixelStride = planes[0].getPixelStride();
            int rowStride = planes[0].getRowStride();
            int rowPadding = rowStride - pixelStride * img.getWidth();
            Bitmap bitmap = Bitmap.createBitmap(img.getWidth()+rowPadding/pixelStride, img.getHeight(), Bitmap.Config.ARGB_8888);
            bitmap.copyPixelsFromBuffer(buffer);
            //close img and imageProxy
            img.close();
            imageProxy.close();
        }
    });

    Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, imageAnalysis, preview);
}

} }

And the complete error message:以及完整的错误信息:

E/ImageAnalysisAnalyzer: Failed to acquire image. E/ImageAnalysisAnalyzer:无法获取图像。 java.lang.IllegalStateException: maxImages (4) has already been acquired, call #close before acquiring more. java.lang.IllegalStateException: maxImages (4) 已经被获取,在获取更多之前调用#close。 at android.media.ImageReader.acquireNextImage(ImageReader.java:527) at android.media.ImageReader.acquireLatestImage(ImageReader.java:411) at androidx.camera.core.AndroidImageReaderProxy.acquireLatestImage(AndroidImageReaderProxy.java:56) at androidx.camera.core.SafeCloseImageReaderProxy.acquireLatestImage(SafeCloseImageReaderProxy.java:67) at androidx.camera.core.ImageYuvToRgbConverter.convertYUVToRGB(ImageYuvToRgbConverter.java:83) at androidx.camera.core.ImageAnalysisAbstractAnalyzer.analyzeImage(ImageAnalysisAbstractAnalyzer.java:125) at androidx.camera.core.ImageAnalysisNonBlockingAnalyzer.onValidImageAvailable(ImageAnalysisNonBlockingAnalyzer.java:103) at androidx.camera.core.ImageAnalysisAbstractAnalyzer.onImageAvailable(ImageAnalysisAbstractAnalyzer.java:69) at androidx.camera.core.SafeCloseImageReaderProxy.lambda$setOnImageAvailableListener$1$SafeCloseImageReaderProxy(SafeCloseImageReaderProxy.java:170) at androidx.camera.core.-$$Lambda$SafeCloseImageReaderProxy$vlVuGMKvMVqmwbJ在 android.media.ImageReader.acquireNextImage(ImageReader.java:527) 在 android.media.ImageReader.acquireLatestImage(ImageReader.java:411) 在 androidx.camera.core.AndroidImageReaderProxy.acquireLatestImage(AndroidImageReaderProxy.java:56) 在 androidx。 camera.core.SafeCloseImageReaderProxy.acquireLatestImage(SafeCloseImageReaderProxy.java:67) at androidx.camera.core.ImageYuvToRgbConverter.convertYUVToRGB(ImageYuvToRgbConverter.java:83) at androidx.camera.core.ImageAnalysisAbstractAnalyzer.Analysis.java:67 .camera.core.ImageAnalysisNonBlockingAnalyzer.onValidImageAvailable(ImageAnalysisNonBlockingAnalyzer.java:103) 位于 androidx.camera.core.ImageAnalysisAbstractAnalyzer.onImageAvailable(ImageAnalysisAbstractAnalyzer.java:69) 位于 androidx.camera.core.AvadaSafeCloseImageReader(ImageAnalysisNonBlockingAnalyzer.java:103) java:170) 在 androidx.camera.core.-$$Lambda$SafeCloseImageReaderProxy$vlVuGMKvMVqmwbJ Fm3dTgGgUzu4.onImageAvailable(Unknown Source:4) at androidx.camera.core.AndroidImageReaderProxy.lambda$setOnImageAvailableListener$0$AndroidImageReaderProxy(AndroidImageReaderProxy.java:139) at androidx.camera.core.-$$Lambda$AndroidImageReaderProxy$ydxkGVJ03P0ZMYkq3dfSV-hzi3E.run(Unknown Source:4) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:923) Fm3dTgGgUzu4.onImageAvailable(未知来源:4)在 androidx.camera.core.AndroidImageReaderProxy.lambda$setOnImageAvailableListener$0$AndroidImageReaderProxy(AndroidImageReaderProxy.java:139) 在 androidx.camera.core.-$$Lambda$AndroidImageReaderProxy$ydxkZSVEJ0q3MY (未知来源:4)在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 在 java.lang.Thread.run (线程.java:923)

i think imageProxy.close();我认为 imageProxy.close(); too late before analyze return new ImageProxy.在分析返回新的 ImageProxy 之前为时已晚。 maybe call imageProxy.close() below of imageProxy.getImage();.也许调用 imageProxy.getImage(); 下面的 imageProxy.close();。 hope this help for you希望这对你有帮助

You should close the image right after you got all the needed data from it like this:您应该在从中获取所有需要的数据后立即关闭图像,如下所示:

public void analyze(@NonNull ImageProxy imageProxy) {
    //my code to turn media image into a bitmap
    Image img = imageProxy.getImage();
    Image.Plane[] planes = img.getPlanes();
    ByteBuffer buffer = planes[0].getBuffer();
    int pixelStride = planes[0].getPixelStride();
    int rowStride = planes[0].getRowStride();
    int imgWidth = img.getWidth();
    int imgHeight = img.getHeight();
    //close img and imageProxy
    img.close();
    imageProxy.close();
    int rowPadding = rowStride - pixelStride * img.getWidth();
    Bitmap bitmap = Bitmap.createBitmap(imgWidth + rowPadding / pixelStride, imgHeight, Bitmap.Config.ARGB_8888);
    bitmap.copyPixelsFromBuffer(buffer);
}

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

相关问题 如何从 Android MediaImage 以 OUTPUT_IMAGE_FORMAT_RGBA_8888 格式创建 Bitmap? - How to create Bitmap from Android MediaImage in OUTPUT_IMAGE_FORMAT_RGBA_8888 format? ImageReader maxImages(2)已在后台任务中获取 - ImageReader maxImages (2) has already been acquired in background task LibGDX光标图像像素图不是RGBA8888格式 - LibGDX Cursor image pixmap is not in RGBA8888 format CameraX:如何使用图像调用分析方法 - CameraX: How to call the analyze method with an image 在 android camerax 图像分析中检测文档角的最佳方法是什么? - what is the best way to detect document corners in android camerax Image analysis? IllegalStateException:检索图像时已对此响应调用getOutputStream() - IllegalStateException: getOutputStream() has already been called for this response on retrieving image 如何知道已获取锁 - How to know a lock has been acquired Android CameraX 分析图像 stream - Android CameraX analyse image stream :文件已被移动-上传图像时无法在Spring MVC中再次传输 - : File has already been moved - cannot be transferred again in spring mvc while upload image JSP:“已为此响应调用getOutputStream()”在屏幕上显示图像时获取异常 - JSP: “getOutputStream() has already been called for this response” get exception while display image on screen
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM