美文网首页安卓
Android 人脸识别

Android 人脸识别

作者: 程序员Android1 | 来源:发表于2021-08-24 09:25 被阅读0次

    和你一起终身学习,这里是程序员 Android

    经典好文推荐,通过阅读本文,您将收获以下知识点:

    一、实现思路与步骤
    二、创建布局文件
    三、获取相机信息
    四、申请Camera 权限
    五、获取相机参数
    六、开始相机配流
    七、创建Capture 请求
    八、实现预览回调
    九、Demo 所有代码

    一、实现思路与步骤

    最近项目需求是统计当前摄像头中的人脸个数,安卓有提供现成的Api,最终实现效果如下图。

    1.1 分析思路和步奏:

    主要使用到的类:SurfaceView、CameraManager、CameraDevice.StateCallback、CameraCaptureSession.StateCallback。

    1.通过SurfaceView展示预览区。
    2.在SurfaceView创建成功后通过CameraManager获取当前设备可用的摄像头。
    3.检测摄像头权限。
    4.通过CameraManager打开摄像头。
    5.在打开成功的回调中通过CameraDevice创建会话。
    6.在会话创建成功的回调方法中创建预览请求。
    7.在预览请求的回调方法onCaptureCompleted()方法中获取预览界面中返回的人脸数。

    以下是实现步奏:

    二、创建布局文件

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical">
    
        <SurfaceView
            android:id="@+id/sv"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
    </LinearLayout>
    
    
    

    java

    cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
            surfaceHolder = sv.getHolder();
            surface = surfaceHolder.getSurface();
    
    

    三、获取相机信息

     //获取可用的相机列表
                        String[] cameraIdList = cameraManager.getCameraIdList();
    

    四、申请Camera 权限

    if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                            // TODO: Consider calling
                            //    Activity#requestPermissions
                            // here to request the missing permissions, and then overriding
                            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                            //                                          int[] grantResults)
                            // to handle the case where the user grants the permission. See the documentation
                            // for Activity#requestPermissions for more details.
                            return;
                        }
    
    

    五、获取相机参数

    //获取开启相机的相关参数
                        CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraIdList[1]);
                        //可用于判断是否支持人脸检测,以及支持到哪种程度
                        faceDetectModes = characteristics.get(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES);//支持的人脸检测模式
                        cameraManager.openCamera(cameraIdList[1], mStateCallback, null);
    
    

    六、开始相机配流

    camera.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
                        @Override
                        public void onConfigured(@NonNull CameraCaptureSession session) {
                         
                        }
    
                        @Override
                        public void onConfigureFailed(@NonNull CameraCaptureSession session) {
    
                        }
                    }, new Handler());
    
    

    七、创建Capture 请求

    CaptureRequest.Builder captureRequest = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                                captureRequest.addTarget(surface);
                                captureRequest.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
                                captureRequest.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, getFaceDetectMode());
                                session.setRepeatingRequest(captureRequest.build(),captureCallback,new Handler());
    
    

    八、实现预览回调

     /**
         * 预览回调
         */
        private CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
            @Override
            public void onCaptureStarted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber) {
                super.onCaptureStarted(session, request, timestamp, frameNumber);
            }
    
            @Override
            public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
                super.onCaptureProgressed(session, request, partialResult);
            }
    
            @Override
            public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                super.onCaptureCompleted(session, request, result);
                Face faces[] = result.get(CaptureResult.STATISTICS_FACES);
                if (faces.length != face) {
                    Log.e("lee", faces.length + "张脸");
                }
            }
    
            @Override
            public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
                super.onCaptureFailed(session, request, failure);
            }
    
            @Override
            public void onCaptureSequenceCompleted(@NonNull CameraCaptureSession session, int sequenceId, long frameNumber) {
                super.onCaptureSequenceCompleted(session, sequenceId, frameNumber);
            }
    
            @Override
            public void onCaptureSequenceAborted(@NonNull CameraCaptureSession session, int sequenceId) {
                super.onCaptureSequenceAborted(session, sequenceId);
            }
    
            @Override
            public void onCaptureBufferLost(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull Surface target, long frameNumber) {
                super.onCaptureBufferLost(session, request, target, frameNumber);
            }
        };
    
    

    九、Demo 所有代码

    MainActivity.java

    package com.zg.lcddemo;
    
    import android.Manifest;
    import android.content.ContentValues;
    import android.content.Context;
    import android.content.pm.PackageManager;
    import android.content.res.Configuration;
    import android.database.Cursor;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.ImageFormat;
    import android.graphics.Rect;
    import android.graphics.SurfaceTexture;
    import android.hardware.Camera;
    import android.hardware.camera2.CameraAccessException;
    import android.hardware.camera2.CameraCaptureSession;
    import android.hardware.camera2.CameraCharacteristics;
    import android.hardware.camera2.CameraDevice;
    import android.hardware.camera2.CameraManager;
    import android.hardware.camera2.CameraMetadata;
    import android.hardware.camera2.CaptureFailure;
    import android.hardware.camera2.CaptureRequest;
    import android.hardware.camera2.CaptureResult;
    import android.hardware.camera2.TotalCaptureResult;
    import android.hardware.camera2.params.Face;
    import android.hardware.camera2.params.SessionConfiguration;
    import android.hardware.camera2.params.StreamConfigurationMap;
    import android.media.FaceDetector;
    import android.media.ImageReader;
    import android.net.Uri;
    import android.os.Build;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.HandlerThread;
    import android.os.Message;
    import android.provider.MediaStore;
    import android.util.Log;
    import android.util.Size;
    import android.view.Surface;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ImageView;
    import android.widget.Toast;
    
    import androidx.annotation.NonNull;
    import androidx.annotation.RequiresApi;
    import androidx.appcompat.app.AppCompatActivity;
    
    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.List;
    import java.util.concurrent.Semaphore;
    
    public class MainActivity extends AppCompatActivity {
        private SurfaceView sv;
        private SurfaceHolder surfaceHolder;
        private CameraManager cameraManager;
        private Surface surface;
        int[] faceDetectModes;
        int face;
        List<Bitmap> bitmaps = new ArrayList<>();
    
        /**
         * 获取支持的最高人脸检测级别
         *
         * @return
         */
        private int getFaceDetectMode() {
            if (faceDetectModes == null) {
                return CaptureRequest.STATISTICS_FACE_DETECT_MODE_FULL;
            } else {
                return faceDetectModes[faceDetectModes.length - 1];
            }
        }
    
        @RequiresApi(api = Build.VERSION_CODES.M)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            sv = findViewById(R.id.sv);
            cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
            surfaceHolder = sv.getHolder();
            surface = surfaceHolder.getSurface();
            surfaceHolder.addCallback(new SurfaceHolder.Callback() {
                @RequiresApi(api = Build.VERSION_CODES.M)
                @Override
                public void surfaceCreated(SurfaceHolder holder) {
                    try {
                        //获取可用的相机列表
                        String[] cameraIdList = cameraManager.getCameraIdList();
                        if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                            // TODO: Consider calling
                            //    Activity#requestPermissions
                            // here to request the missing permissions, and then overriding
                            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                            //                                          int[] grantResults)
                            // to handle the case where the user grants the permission. See the documentation
                            // for Activity#requestPermissions for more details.
                            return;
                        }
                        //获取开启相机的相关参数
                        CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraIdList[1]);
                        //可用于判断是否支持人脸检测,以及支持到哪种程度
                        faceDetectModes = characteristics.get(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES);//支持的人脸检测模式
                        cameraManager.openCamera(cameraIdList[1], mStateCallback, null);
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                }
    
                @Override
                public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    
                }
    
                @Override
                public void surfaceDestroyed(SurfaceHolder holder) {
    
                }
            });
    
        }
    
        /**
         * 相机状态回调
         */
        private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
            @Override
            public void onOpened(@NonNull final CameraDevice camera) {
                //打开成功,可以获取CameraDevice对象
                try {
                    camera.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
                        @Override
                        public void onConfigured(@NonNull CameraCaptureSession session) {
                            try {
                                CaptureRequest.Builder captureRequest = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                                captureRequest.addTarget(surface);
                                captureRequest.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
                                captureRequest.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, getFaceDetectMode());
                                session.setRepeatingRequest(captureRequest.build(),captureCallback,new Handler());
                            } catch (CameraAccessException e) {
                                e.printStackTrace();
                            }
                        }
    
                        @Override
                        public void onConfigureFailed(@NonNull CameraCaptureSession session) {
    
                        }
                    }, new Handler());
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
    
            }
    
            @Override
            public void onDisconnected(@NonNull CameraDevice camera) {
                //断开连接
                Toast.makeText(MainActivity.this, "onDisconnected", Toast.LENGTH_SHORT).show();
            }
    
            @Override
            public void onError(@NonNull CameraDevice camera, final int error) {
                //发生异常
                Toast.makeText(MainActivity.this, "onError", Toast.LENGTH_SHORT).show();
            }
        };
    
    
        /**
         * 预览回调
         */
        private CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
            @Override
            public void onCaptureStarted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber) {
                super.onCaptureStarted(session, request, timestamp, frameNumber);
            }
    
            @Override
            public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
                super.onCaptureProgressed(session, request, partialResult);
            }
    
            @Override
            public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                super.onCaptureCompleted(session, request, result);
                Face faces[] = result.get(CaptureResult.STATISTICS_FACES);
                if (faces.length != face) {
                    Log.e("lee", faces.length + "张脸");
                    face = faces.length;        
                }
            }
    
            @Override
            public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
                super.onCaptureFailed(session, request, failure);
            }
    
            @Override
            public void onCaptureSequenceCompleted(@NonNull CameraCaptureSession session, int sequenceId, long frameNumber) {
                super.onCaptureSequenceCompleted(session, sequenceId, frameNumber);
            }
    
            @Override
            public void onCaptureSequenceAborted(@NonNull CameraCaptureSession session, int sequenceId) {
                super.onCaptureSequenceAborted(session, sequenceId);
            }
    
            @Override
            public void onCaptureBufferLost(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull Surface target, long frameNumber) {
                super.onCaptureBufferLost(session, request, target, frameNumber);
            }
        };
    }
    
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical">
    
        <SurfaceView
            android:id="@+id/sv"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
    </LinearLayout>
    
    

    以上就能实现统计当前摄像头下有多少个人脸。

    原文链接:https://blog.csdn.net/qq77485042/article/details/109176683

    至此,本篇已结束。转载网络的文章,小编觉得很优秀,欢迎点击阅读原文,支持原创作者,如有侵权,恳请联系小编删除,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!

    相关文章

      网友评论

        本文标题:Android 人脸识别

        本文链接:https://www.haomeiwen.com/subject/citdiltx.html