为啥人脸识别要用彩灯

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥人脸识别要用彩灯相关的知识,希望对你有一定的参考价值。

参考技术A 活体检测一种。
离线3D结构光活体检测 --> 基于3D结构光成像原理,通过人脸表面反射光线构建深度图像,判断目标是否为活体,可强效防御图片、视频、屏幕、模具等攻击。
3D结构光成像是将图案投影到三维空间物体表面上,使用另外一个相机观察在三维物理表面成像的畸变情况。

为啥 Google 的 ML 人脸检测工具包在 .process() 上崩溃

【中文标题】为啥 Google 的 ML 人脸检测工具包在 .process() 上崩溃【英文标题】:Why is Google's ML Face Detection Kit crashing on .process()为什么 Google 的 ML 人脸检测工具包在 .process() 上崩溃 【发布时间】:2021-07-16 22:07:25 【问题描述】:

我正在创建一个面部检测器应用程序,它将实时检测面部并识别面部上的地标。人脸的地标工作得很好,但是我的实时人脸检测根本没有工作。

我按照 Google 的 ML Kit(https://developers.google.com/ml-kit/vision/face-detection/android) 中的说明进行操作,但我真的很难获得实时人脸检测的功能。

在我的调试器中,代码在facedetector.process(image).addOnSuccessListener() 崩溃,而是进入onFailure()

这是我的实时人脸检测部分的代码(我已经评论了一些部分+减少了冗余)。

@Override
    //process method to detect frame by frame in real time face detection
    public void process(@NonNull Frame frame) 
        int width = frame.getSize().getWidth();
        int height = frame.getSize().getHeight();


        InputImage image = InputImage.fromByteArray(
                frame.getData(),
                /* image width */width,
                /* image height */height,
                 //if camera is facing front rotate image 90, else 270 degrees
                (cameraFacing != Facing.FRONT) ? 90 : 270,
                InputImage.IMAGE_FORMAT_YUV_420_888 // or IMAGE_FORMAT_YV12
        );

        FaceDetectorOptions faceDetectorOptions = new FaceDetectorOptions.Builder()
                .setContourMode(FaceDetectorOptions.CONTOUR_MODE_ALL)
                //setting contour mode to detect all facial contours in real time
                .build();

        FaceDetector faceDetector = FaceDetection.getClient(faceDetectorOptions);
        faceDetector.process(image).addOnSuccessListener(new OnSuccessListener<List<Face>>() 
            @Override
            public void onSuccess(@NonNull List<Face> faces) 

                imageView.setImageBitmap(null);

                Bitmap bitmap = Bitmap.createBitmap(height, width, Bitmap.Config.ARGB_8888);
                Canvas canvas = new Canvas(bitmap);

                Paint dotPaint = new Paint();
                dotPaint.setColor(Color.YELLOW);
                dotPaint.setStyle(Paint.Style.FILL);
                dotPaint.setStrokeWidth(6f);

                Paint linePaint = new Paint();
                linePaint.setColor(Color.GREEN);
                linePaint.setStyle(Paint.Style.STROKE);
                linePaint.setStrokeWidth(4f);
                //looping through each face to detect each contour
                for (Face face : faces) 


                    List<PointF> faceContours = face.getContour(
                            FaceContour.FACE
                    ).getPoints();

                    for (int i = 0; i < faceContours.size(); i++) 
                        PointF faceContour = null;
                        if (i != (faceContours.size() - 1)) 
                            faceContour = faceContours.get(i);
                            canvas.drawLine(
                                    faceContour.x, faceContour.y, faceContours.get(i + 1).x, faceContours.get(i + 1).y, linePaint
                            );
                         else //if at the last point, draw to the first point
                            canvas.drawLine(faceContour.x, faceContour.y, faceContours.get(0).x, faceContours.get(0).y, linePaint);
                        
                        canvas.drawCircle(faceContour.x, faceContour.y, 4f, dotPaint);
                    //end inner loop


                    List<PointF> leftEyebrowTopCountours = face.getContour(
                            FaceContour.LEFT_EYEBROW_TOP).getPoints();
                    for (int i = 0; i < leftEyebrowTopCountours.size(); i++) 
                        PointF leftEyebrowTopContour = leftEyebrowTopCountours.get(i);
                        if (i != (leftEyebrowTopCountours.size() - 1))
                            canvas.drawLine(leftEyebrowTopContour.x, leftEyebrowTopContour.y, leftEyebrowTopCountours.get(i + 1).x, leftEyebrowTopCountours.get(i + 1).y, linePaint);
                        canvas.drawCircle(leftEyebrowTopContour.x, leftEyebrowTopContour.y, 4f, dotPaint);

                    
                
              

旁注:我在模拟器中使用 Pixel 2 API 29。因为我只是通过轮廓,所以我省略了重复的代码

完整代码供参考:

import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.mlkit.vision.common.InputImage;
import com.google.mlkit.vision.face.Face;
import com.google.mlkit.vision.face.FaceContour;
import com.google.mlkit.vision.face.FaceDetection;
import com.google.mlkit.vision.face.FaceDetector;
import com.google.mlkit.vision.face.FaceDetectorOptions;
import com.google.mlkit.vision.face.FaceLandmark;
import com.otaliastudios.cameraview.CameraView;
import com.otaliastudios.cameraview.controls.Facing;
import com.otaliastudios.cameraview.frame.Frame;
import com.otaliastudios.cameraview.frame.FrameProcessor;
import com.theartofdev.edmodo.cropper.CropImage;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class MainActivity extends AppCompatActivity implements FrameProcessor 
    private Facing cameraFacing = Facing.FRONT;
    private ImageView imageView;
    private CameraView faceDetectionCameraView;
    private RecyclerView bottomSheetRecyclerView;
    private BottomSheetBehavior bottomSheetBehavior;
    private ArrayList<FaceDetectionModel> faceDetectionModels;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        faceDetectionModels = new ArrayList<>();
        bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.bottom_sheet));

        imageView = findViewById(R.id.face_detection_image_view);
        faceDetectionCameraView = findViewById(R.id.face_detection_camera_view);

        Button toggle = findViewById(R.id.face_detection_cam_toggle_button);
        FrameLayout bottomSheetButton = findViewById(R.id.bottom_sheet_button);
        bottomSheetRecyclerView = findViewById(R.id.bottom_sheet_recycler_view);

        faceDetectionCameraView.setFacing(cameraFacing);
        faceDetectionCameraView.setLifecycleOwner(MainActivity.this);
        faceDetectionCameraView.addFrameProcessor(MainActivity.this);



        toggle.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                cameraFacing = (cameraFacing == Facing.FRONT) ? Facing.BACK : Facing.FRONT;
                faceDetectionCameraView.setFacing(cameraFacing);
            
        );

        bottomSheetButton.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                    CropImage.activity().start(MainActivity.this);

            
        );


        bottomSheetRecyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
        bottomSheetRecyclerView.setAdapter(new FaceDetectionAdapter(faceDetectionModels, MainActivity.this));

    


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) 
        super.onActivityResult(requestCode, resultCode, data);


        if(requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE)
            CropImage.ActivityResult result = CropImage.getActivityResult(data);

            if(resultCode == RESULT_OK)
                Uri imageUri =  result.getUri();
                try 
                    analyseImage(MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri));
                 catch (IOException e) 
                    e.printStackTrace();
                
            
        
    

    private void analyseImage(Bitmap bitmap) 
        if(bitmap == null)
            Toast.makeText(this, "There was an error", Toast.LENGTH_SHORT).show();
        
        //imageView.setImageBitmap(null);
        faceDetectionModels.clear();

        Objects.requireNonNull(bottomSheetRecyclerView.getAdapter()).notifyDataSetChanged();
        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);

        showProgress();
        InputImage firebaseInputImage = InputImage.fromBitmap(bitmap, 0);
        FaceDetectorOptions options =
                new FaceDetectorOptions.Builder()
                .setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_ACCURATE)
                .setLandmarkMode(FaceDetectorOptions.LANDMARK_MODE_ALL)
                .setClassificationMode(FaceDetectorOptions.CLASSIFICATION_MODE_ALL)
                .build();

        FaceDetector faceDetector = FaceDetection.getClient(options);

        faceDetector.process(firebaseInputImage)
                .addOnSuccessListener(new OnSuccessListener<List<Face>>() 
                    @Override
                    public void onSuccess(@NonNull List<Face> faces) 
                        Bitmap mutableImage = bitmap.copy(Bitmap.Config.ARGB_8888, true);

                        detectFaces(faces, mutableImage);
                        imageView.setImageBitmap(mutableImage);
                        hideProgress();
                        bottomSheetRecyclerView.getAdapter().notifyDataSetChanged();
                        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);


                    
                )
                .addOnFailureListener(new OnFailureListener() 
                    @Override
                    public void onFailure(@NonNull Exception e) 
                        Toast.makeText(MainActivity.this, "There was an error", Toast.LENGTH_SHORT).show();
                        hideProgress();

                    
                );

    

    private void detectFaces(List<Face> faces, Bitmap bitmap) 
        if(faces == null || bitmap == null) 
            Toast.makeText(this, "There was an error", Toast.LENGTH_SHORT).show();
            return;
        

        Canvas canvas = new Canvas(bitmap);
        Paint facePaint = new Paint();
        facePaint.setColor(Color.GREEN);
        facePaint.setStyle(Paint.Style.STROKE);
        facePaint.setStrokeWidth(5f);

        Paint faceTextPaint = new Paint();
        faceTextPaint.setColor(Color.BLUE);
        faceTextPaint.setTextSize(30f);
        faceTextPaint.setTypeface(Typeface.SANS_SERIF);


        Paint landmarkPaint = new Paint();
        landmarkPaint.setColor(Color.YELLOW);
        landmarkPaint.setStyle(Paint.Style.FILL);
        landmarkPaint.setStrokeWidth(8f);

        for(int i = 0; i < faces.size(); i++)
            canvas.drawRect(faces.get(i).getBoundingBox(), facePaint);
            canvas.drawText("Face" + i,
                    (faces.get(i).getBoundingBox().centerX()
                    -(faces.get(i).getBoundingBox().width() >> 1) + 8f),
                    (faces.get(i).getBoundingBox().centerY() + (faces.get(i).getBoundingBox().height() >> 1) - 8f), facePaint);

            Face face = faces.get(i); //get one face


            if(face.getLandmark(FaceLandmark.LEFT_EYE) != null)
                FaceLandmark leftEye = face.getLandmark(FaceLandmark.LEFT_EYE);
                //Now we have our left eye, we draw a little circle
                canvas.drawCircle(leftEye.getPosition().x, leftEye.getPosition().y, 8f, landmarkPaint);
            
            if(face.getLandmark(FaceLandmark.RIGHT_EYE) != null)
                FaceLandmark rightEye = face.getLandmark(FaceLandmark.RIGHT_EYE);
                //Now we have our left eye, we draw a little circle
                canvas.drawCircle(rightEye.getPosition().x, rightEye.getPosition().y, 8f, landmarkPaint);
            
            if(face.getLandmark(FaceLandmark.NOSE_BASE) != null)
                FaceLandmark noseBase = face.getLandmark(FaceLandmark.NOSE_BASE);
                //Now we have our left eye, we draw a little circle
                canvas.drawCircle(noseBase.getPosition().x, noseBase.getPosition().y, 8f, landmarkPaint);
            
            if(face.getLandmark(FaceLandmark.LEFT_EAR) != null)
                FaceLandmark leftEar = face.getLandmark(FaceLandmark.LEFT_EAR);
                //Now we have our left eye, we draw a little circle
                canvas.drawCircle(leftEar.getPosition().x, leftEar.getPosition().y, 8f, landmarkPaint);
            
            if(face.getLandmark(FaceLandmark.RIGHT_EAR) != null)
                FaceLandmark rightEar = face.getLandmark(FaceLandmark.RIGHT_EAR);
                //Now we have our left eye, we draw a little circle
                canvas.drawCircle(rightEar.getPosition().x, rightEar.getPosition().y, 8f, landmarkPaint);
            
            if(face.getLandmark(FaceLandmark.MOUTH_LEFT) != null && face.getLandmark(FaceLandmark.MOUTH_BOTTOM) != null && face.getLandmark(FaceLandmark.MOUTH_RIGHT) != null)
                FaceLandmark mouthLeft = face.getLandmark(FaceLandmark.MOUTH_LEFT);
                FaceLandmark mouthRight = face.getLandmark(FaceLandmark.MOUTH_RIGHT);
                FaceLandmark mouthBottom = face.getLandmark(FaceLandmark.MOUTH_BOTTOM);
                //Now we have our left eye, we draw a little circle
                canvas.drawLine(mouthLeft.getPosition().x, mouthLeft.getPosition().y, mouthBottom.getPosition().x, mouthBottom.getPosition().y, landmarkPaint);
                canvas.drawLine(mouthBottom.getPosition().x, mouthBottom.getPosition().y, mouthRight.getPosition().x, mouthRight.getPosition().y, landmarkPaint);
            

            faceDetectionModels.add(new FaceDetectionModel(i, "Smiling probability"
            + face.getSmilingProbability()));

            faceDetectionModels.add(new FaceDetectionModel(i, "Left eye open probability"
                    + face.getLeftEyeOpenProbability()));

            faceDetectionModels.add(new FaceDetectionModel(i, "Right eye open probability"
                    + face.getRightEyeOpenProbability()));



        
    

    private void showProgress() 
        findViewById(R.id.bottom_sheet_button_img).setVisibility(View.GONE);
        findViewById(R.id.bottom_sheet_butotn_progress_bar).setVisibility(View.VISIBLE);
    

    private void hideProgress() 
        findViewById(R.id.bottom_sheet_button_img).setVisibility(View.VISIBLE);
        findViewById(R.id.bottom_sheet_butotn_progress_bar).setVisibility(View.GONE);
    

    //real-time detection starts HERE

    @Override
    public void process(@NonNull Frame frame) 
        //setting up width and frame height
        int width = frame.getSize().getWidth();
        int height = frame.getSize().getHeight();

        byte[] byteArray = frame.getData();
        InputImage image = InputImage.fromByteArray(
                //frame.getData()
                byteArray,
                width,
                height,
                //rotation
                (cameraFacing == Facing.FRONT) ? 90 : 270,
                //image format
                InputImage.IMAGE_FORMAT_YV12 // or IMAGE_FORMAT_YV12
        );

        //Contour mode all is real time contour detection
        FaceDetectorOptions realTimeOpts = new FaceDetectorOptions.Builder()
                .setContourMode(FaceDetectorOptions.CONTOUR_MODE_ALL)
                .build();

        FaceDetector faceDetector = FaceDetection.getClient(realTimeOpts);
        faceDetector.process(image).addOnSuccessListener(new OnSuccessListener<List<Face>>() 

    @Override
    public void onSuccess(@NonNull List<Face> faces) 

        //don't have image yet set to null first
        imageView.setImageBitmap(null);

        //bitmap stores pixels of image

        Bitmap bitmap = Bitmap.createBitmap(height, width, Bitmap.Config.ARGB_8888);

        //canvas hold the draw calls -- write into the bitmap
        Canvas canvas = new Canvas(bitmap);

        //paint specifies what the canvas should draw
        Paint dotPaint = new Paint();
        dotPaint.setColor(Color.YELLOW);
        dotPaint.setStyle(Paint.Style.FILL);
        dotPaint.setStrokeWidth(6f);

        Paint linePaint = new Paint();
        linePaint.setColor(Color.GREEN);
        linePaint.setStyle(Paint.Style.STROKE);
        linePaint.setStrokeWidth(4f);

        for (Face face : faces) 


            //fetching contours
                List<PointF> faceContours = face.getContour(
                        FaceContour.FACE
                ).getPoints();

                for (int i = 0; i < faceContours.size(); i++) 
                    PointF faceContour = faceContours.get(i);
                    if (i != (faceContours.size() - 1)) 
                        canvas.drawLine(
                                //if not at last index, continue drawing to next index
                                faceContour.x, faceContour.y, faceContours.get(i + 1).x, faceContours.get(i + 1).y, linePaint
                        );
                     else 
                        return;
                    
                    //always draw circle
                    canvas.drawCircle(faceContour.x, faceContour.y, 4f, dotPaint);
                //end inner loop


                List<PointF> leftEyebrowTopCountours = face.getContour(
                        FaceContour.LEFT_EYEBROW_TOP).getPoints();
                for (int i = 0; i < leftEyebrowTopCountours.size(); i++) 
                    PointF leftEyebrowTopContour = leftEyebrowTopCountours.get(i);
                    if (i != (leftEyebrowTopCountours.size() - 1)) 
                        canvas.drawLine(leftEyebrowTopContour.x, leftEyebrowTopContour.y, leftEyebrowTopCountours.get(i + 1).x, leftEyebrowTopCountours.get(i + 1).y, linePaint);
                    else
                        return;
                    
                    canvas.drawCircle(leftEyebrowTopContour.x, leftEyebrowTopContour.y, 4f, dotPaint);

                

                List<PointF> rightEyebrowTopCountours = face.getContour(
                        FaceContour.RIGHT_EYEBROW_TOP).getPoints();
                for (int i = 0; i < rightEyebrowTopCountours.size(); i++) 
                    PointF rightEyebrowContour = rightEyebrowTopCountours.get(i);
                    if (i != (rightEyebrowTopCountours.size() - 1)) 
                        canvas.drawLine(rightEyebrowContour.x, rightEyebrowContour.y, rightEyebrowTopCountours.get(i + 1).x, rightEyebrowTopCountours.get(i + 1).y, linePaint);
                    else
                        return;

                    
                    canvas.drawCircle(rightEyebrowContour.x, rightEyebrowContour.y, 4f, dotPaint);

                

                List<PointF> rightEyebrowBottomCountours = face.getContour(
                        FaceContour.RIGHT_EYEBROW_BOTTOM).getPoints();
                for (int i = 0; i < rightEyebrowBottomCountours.size(); i++) 
                    PointF rightEyebrowBottomContour = rightEyebrowBottomCountours.get(i);
                    if (i != (rightEyebrowBottomCountours.size() - 1)) 
                        canvas.drawLine(rightEyebrowBottomContour.x, rightEyebrowBottomContour.y, rightEyebrowBottomCountours.get(i + 1).x, rightEyebrowBottomCountours.get(i + 1).y, linePaint);
                    else
                        return;
                    
                    canvas.drawCircle(rightEyebrowBottomContour.x, rightEyebrowBottomContour.y, 4f, dotPaint);

                

                List<PointF> leftEyeContours = face.getContour(
                        FaceContour.LEFT_EYE).getPoints();
                for (int i = 0; i < leftEyeContours.size(); i++) 
                    PointF leftEyeContour = leftEyeContours.get(i);
                    if (i != (leftEyeContours.size() - 1)) 
                        canvas.drawLine(leftEyeContour.x, leftEyeContour.y, leftEyeContours.get(i + 1).x, leftEyeContours.get(i + 1).y, linePaint);

                     else 
                        return;
                    
                    canvas.drawCircle(leftEyeContour.x, leftEyeContour.y, 4f, dotPaint);


                

                List<PointF> rightEyeContours = face.getContour(
                        FaceContour.RIGHT_EYE).getPoints();
                for (int i = 0; i < rightEyeContours.size(); i++) 
                    PointF rightEyeContour = rightEyeContours.get(i);
                    if (i != (rightEyeContours.size() - 1)) 
                        canvas.drawLine(rightEyeContour.x, rightEyeContour.y, rightEyeContours.get(i + 1).x, rightEyeContours.get(i + 1).y, linePaint);

                     else 
                        return;
                    
                    canvas.drawCircle(rightEyeContour.x, rightEyeContour.y, 4f, dotPaint);


                

                List<PointF> upperLipTopContour = face.getContour(
                        FaceContour.UPPER_LIP_TOP).getPoints();
                for (int i = 0; i < upperLipTopContour.size(); i++) 
                    PointF upperLipContour = upperLipTopContour.get(i);
                    if (i != (upperLipTopContour.size() - 1)) 
                        canvas.drawLine(upperLipContour.x, upperLipContour.y,
                                upperLipTopContour.get(i + 1).x,
                                upperLipTopContour.get(i + 1).y, linePaint);
                    else
                        return;

                    
                    canvas.drawCircle(upperLipContour.x, upperLipContour.y, 4f, dotPaint);

                

                List<PointF> upperLipBottomContour = face.getContour(
                        FaceContour.UPPER_LIP_BOTTOM).getPoints();
                for (int i = 0; i < upperLipBottomContour.size(); i++) 
                    PointF upBottom = upperLipBottomContour.get(i);
                    if (i != (upperLipBottomContour.size() - 1)) 
                        canvas.drawLine(upBottom.x, upBottom.y, upperLipBottomContour.get(i + 1).x, upperLipBottomContour.get(i + 1).y, linePaint);
                    else
                        return;

                    
                    canvas.drawCircle(upBottom.x, upBottom.y, 4f, dotPaint);

                
                List<PointF> lowerLipTopContour = face.getContour(
                        FaceContour.LOWER_LIP_TOP).getPoints();
                for (int i = 0; i < lowerLipTopContour.size(); i++) 
                    PointF lowerTop = lowerLipTopContour.get(i);
                    if (i != (lowerLipTopContour.size() - 1)) 
                        canvas.drawLine(lowerTop.x, lowerTop.y, lowerLipTopContour.get(i + 1).x, lowerLipTopContour.get(i + 1).y, linePaint);
                    
                    else
                        return;

                    
                    canvas.drawCircle(lowerTop.x, lowerTop.y, 4f, dotPaint);

                
                List<PointF> lowerLipBottomContour = face.getContour(
                        FaceContour.LOWER_LIP_BOTTOM).getPoints();
                for (int i = 0; i < lowerLipBottomContour.size(); i++) 
                    PointF lowerBottom = lowerLipBottomContour.get(i);
                    if (i != (lowerLipBottomContour.size() - 1)) 
                        canvas.drawLine(lowerBottom.x, lowerBottom.y, lowerLipBottomContour.get(i + 1).x, lowerLipBottomContour.get(i + 1).y, linePaint);
                    else
                        return;
                    
                    canvas.drawCircle(lowerBottom.x, lowerBottom.y, 4f, dotPaint);

                

                List<PointF> noseBridgeContours = face.getContour(
                        FaceContour.NOSE_BRIDGE).getPoints();
                for (int i = 0; i < noseBridgeContours.size(); i++) 
                    PointF noseBridge = noseBridgeContours.get(i);
                    if (i != (noseBridgeContours.size() - 1)) 
                        canvas.drawLine(noseBridge.x, noseBridge.y, noseBridgeContours.get(i + 1).x, noseBridgeContours.get(i + 1).y, linePaint);
                    else
                        return;

                    
                    canvas.drawCircle(noseBridge.x, noseBridge.y, 4f, dotPaint);

                

                List<PointF> noseBottomContours = face.getContour(
                        FaceContour.NOSE_BOTTOM).getPoints();
                for (int i = 0; i < noseBottomContours.size(); i++) 
                    PointF noseBottom = noseBottomContours.get(i);
                    if (i != (noseBottomContours.size() - 1)) 
                        canvas.drawLine(noseBottom.x, noseBottom.y, noseBottomContours.get(i + 1).x, noseBottomContours.get(i + 1).y, linePaint);
                    else
                        return;

                    
                    canvas.drawCircle(noseBottom.x, noseBottom.y, 4f, dotPaint);


                    //facing front flip image
                    if (cameraFacing == Facing.FRONT) 
                        //Flip image!
                        Matrix matrix = new Matrix();
                        matrix.preScale(-1f, 1f);
                        Bitmap flippedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                                bitmap.getWidth(), bitmap.getHeight(),
                                matrix, true);
                        imageView.setImageBitmap(flippedBitmap);
                     else 
                        imageView.setImageBitmap(bitmap);
                    


                //end outer loop
                canvas.save();

        
    
    ).addOnFailureListener(new OnFailureListener() 
            @Override
            public void onFailure (@NonNull Exception e)
                imageView.setImageBitmap(null);
            


        );
    





编辑:我收到此错误

Getting this error now: 2021-04-27 19:12:05.335 538-1065/system_process E/JavaBinder: *** Uncaught remote exception!  (Exceptions are not yet supported across processes.)
java.lang.RuntimeException: android.os.RemoteException: Couldn't get ApplicationInfo for package android.frameworks.sensorservice@1.0::ISensorManager
    at android.os.Parcel.writeException(Parcel.java:2158)
    at android.os.Binder.execTransactInternal(Binder.java:1178)
    at android.os.Binder.execTransact(Binder.java:1123)
 Caused by: android.os.RemoteException: Couldn't get ApplicationInfo for package android.frameworks.sensorservice@1.0::ISensorManager
    at com.android.server.pm.PackageManagerService$PackageManagerNative.getTargetSdkVersionForPackage(PackageManagerService.java:23957)
    at android.content.pm.IPackageManagerNative$Stub.onTransact(IPackageManagerNative.java:255)
    at android.os.Binder.execTransactInternal(Binder.java:1159)
    at android.os.Binder.execTransact(Binder.java:1123) 

非常感谢!!

【问题讨论】:

您遇到的错误是什么? 嗨,我得到的错误是:2021-04-25 22:19:55.448 17489-19142/? W/android.os.Debug: failed to get memory consumption info: -1,我猜这是因为我使用了几个位图。但是,我需要这些位图用于翻转图像、检测照片中的特征以及实时人脸检测。知道如何避免这个错误吗?谢谢。 这只是一个警告。请发布您的完整 logcat 问题。 嗨,我没有任何错误。我的应用程序没有崩溃,只是实时人脸检测功能不起作用。照片的人脸检测工作正常。在 logcat 的错误下我发现了这个:2021-04-25 23:02:07.186 19552-19552/? E/sh.facedetecto: Unknown bits set in runtime_flags: 0x8000 2021-04-25 23:02:08.165 19552-19602/com.krish.facedetector E/EGL_emulation: eglQueryContext 32c0 EGL_BAD_ATTRIBUTE 2021-04-25 23:02:08.165 19552-19602/com.krish.facedetector E/EGL_emulation: tid 19602: eglQueryContext(1902): error 0x3004 (EGL_BAD_ATTRIBUTE) 另外,我将其添加到问题中。谢谢。 【参考方案1】:

如果您想通过 MLKit 使用相机流输出,您可以使用 CameraX ImageAnalysis 用例。生成YUV_420_888格式的android.media.Image,可以直接转换成mlkit InputImage。

或者,您也可以使用 ML Kit 刚刚发布的 CameraXSource 库。示例代码为here。这消除了您设置 camerax 用例的样板代码,并在内部从 cameraX 输出为您创建 MLKit 输入。请注意,这仍然是一个测试版 SDK。我们期待您的反馈。

为了使用 API,您需要在您的应用中添加以下依赖项:

实现 'com.google.mlkit:camera:16.0.0-beta1'

【讨论】:

您好,我添加了依赖项,但仍然无法正常工作。谢谢。 我把新的错误放在我原来的帖子里。这似乎是一个线程错误:***.com/questions/24429174/…。虽然不知道如何解决它 您好,您不应该在主线程之外进行任何 ui 修改。您可以改用:myAcitity.runOnUiThread(new Runnable() public void run() //在此处更新您的 UI 元素 ); 请更具体。我应该在其中输入哪段代码?谢谢。

以上是关于为啥人脸识别要用彩灯的主要内容,如果未能解决你的问题,请参考以下文章

为啥打开人脸识别时说摄相头禁止使用了?

百度网盘人脸识别,为啥只能显示12个人物?不能识别更多人脸吗?

为啥人脸识别一直失败

如何添加家人人脸识别?

新一代iPad也要用全面屏+人脸识别,苹果表示我们好着呢

人脸识别为啥用python开发