【问题标题】:ImageAnalysis usecase CameraX FacedetectionImageAnalysis 用例 CameraX 人脸检测
【发布时间】:2021-07-23 14:57:12
【问题描述】:

我正在尝试开发一款使用 CameraXMLKit Facedetecion API 分析相机实时帧的应用。它在预览用例中工作正常,但图像分析用例根本不起作用。

我不明白为什么,因为我正在关注最新的官方文档。我的代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    previewView = findViewById(R.id.previewView);
    if (previewView == null) {
        Toast.makeText(this,
            "PreviewView not found",
            Toast.LENGTH_SHORT).show();
    }
    iv = findViewById(R.id.face_image_view);
    if (iv == null) {
        Toast.makeText(this,
            "ImageView not found",
            Toast.LENGTH_SHORT).show();
    }

    cameraProviderFuture = ProcessCameraProvider.getInstance(this);

    cameraProviderFuture.addListener(() - > {
        try {
            ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
            if (allPermissionsGranted()) {
                bindPreview(cameraProvider);
                Log.i(TAG, "here1");
            } else {
                ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSION);
            }


        } catch (ExecutionException | InterruptedException e) {
            // No errors need to be handled for this Future.
            // This should never be reached.
        }
    }, ContextCompat.getMainExecutor(this));
}

void bindPreview(@NonNull ProcessCameraProvider cameraProvider) {
    cameraProvider.unbindAll();

    //bind preview
    Preview preview = new Preview.Builder()
        .build();

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

    preview.setSurfaceProvider(previewView.getSurfaceProvider());

    //bind image analysis
    ImageAnalysis imageAnalysis =
        new ImageAnalysis.Builder()
        .setTargetResolution(new Size(previewView.getWidth(), previewView.getHeight()))
        .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
        .build();

    imageAnalysis.setAnalyzer(executor, new ImageAnalysis.Analyzer() {
        @Override
        public void analyze(@NonNull ImageProxy imageProxy) {

            int rotationDegrees = imageProxy.getImageInfo().getRotationDegrees();

            Log.i(TAG, "here analyzer");
            @SuppressLint("UnsafeOptInUsageError") Image mediaImage = imageProxy.getImage();
            if (mediaImage != null) {
                InputImage image =
                    InputImage.fromMediaImage(mediaImage, rotationDegrees);

                initDrawingUtils(image);

                //START configuration of the facedetector
                FaceDetectorOptions realTimeOpts =
                    new FaceDetectorOptions.Builder()
                    .setContourMode(FaceDetectorOptions.CONTOUR_MODE_ALL)
                    .build();

                FaceDetector detector = FaceDetection.getClient(realTimeOpts);
                //END of configuration of face detector

                // START detector
                detector.process(image)
                    .addOnSuccessListener(
                        new OnSuccessListener < List < Face >> () {
                            @Override
                            public void onSuccess(List < Face > faces) {
                                if (!faces.isEmpty()) {
                                    //Get information about detected faces
                                    processFaces(faces);
                                } else {
                                    canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.MULTIPLY);
                                    Log.i(TAG, "vuoto");
                                }
                            }
                        })
                    .addOnFailureListener(
                        e - > {
                            e.printStackTrace();
                        });
            }
        }
    });

    Log.i(TAG, "here4");

    //add preview and analysis to the lifecycle
    cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, preview, imageAnalysis);

    Log.i(TAG, "here5");
}

代码永远不会到达分析器,因此不会处理实时帧。有人可以帮帮我吗?

【问题讨论】:

  • 代码对我来说看起来是正确的。如果你能创建一个最小的可重现示例并将其放在 GitHub 上,我可以帮你调试。
  • 我在 imageAnalysis.setAnalyzer 中使用“Runnable::run”而不是“executor”解决了

标签: java android face-detection android-camerax google-mlkit


【解决方案1】:

不确定这是否是主要问题,但您似乎在处理图像后忘记关闭 ImageProxy。尝试将此侦听器添加到 process 方法返回的值:

.addOnCompleteListener(task -> imageProxy.close());

来自文档:

如果您正在使用 CameraX API,请确保在使用完 ImageProxy 后关闭它,例如,通过将 OnCompleteListener 添加到从 process 方法返回的 Task 中。有关示例,请参见快速入门示例应用中的 VisionProcessorBase 类。

【讨论】:

  • 感谢您的回答,但无论如何都不起作用
【解决方案2】:

回答有点晚,反正我今天也遇到并解决了同样的问题。

您应该在analyze 方法的末尾调用ImageProxy.close(),这将允许传送下一张图像进行分析:

imageAnalysis.setAnalyzer(executor, new ImageAnalysis.Analyzer() {
    @Override
    public void analyze(@NonNull ImageProxy imageProxy) {
        int rotationDegrees = imageProxy.getImageInfo().getRotationDegrees();

        @SuppressLint("UnsafeOptInUsageError") 
        Image mediaImage = imageProxy.getImage();
        if (mediaImage != null) {
            ...
        }

        imageProxy.close() // <-- Add this line
    }
}

【讨论】:

    猜你喜欢
    • 2019-11-18
    • 2013-07-03
    • 2013-09-24
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    • 2017-06-01
    • 2012-04-17
    • 1970-01-01
    相关资源
    最近更新 更多