首页 > 解决方案 > ImageAnalysis 用例 CameraX 人脸检测

问题描述

我正在尝试开发一个应用程序,使用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");
}

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

标签: javaandroidface-detectionandroid-cameraxgoogle-mlkit

解决方案


迟到的答案,无论如何我今天遇到并解决了同样的问题。

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

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
    }
}

推荐阅读