• 脸识别


    人脸识别

    最近在做一款商户入网的应用,为防止不法商户对公司渠道的接入,公司加大了对商户的审核,人脸识别就是其中的一项。人脸识别的第一步是检测商户的张嘴动作,通过之后采集照片,上传到服务器。第二步是检测商户的摇头动作,通过之后采集照片,上传到服务器。至此完成人脸识别。下面我对主干代码进行分析:

    首先导入jar包Msc(讯飞)。检测人脸关键部位的坐标

    复制代码
    private void setFaceDetection() {
            mThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    List<Object> previewDate = CameraInterface.getInstance()
                            .getPreviewDate();
                    buffer = (byte[]) previewDate.get(0);
                    nv21 = (byte[]) previewDate.get(1);
                    while (!mStopTrack) {
                        if (null == nv21) {
                            continue;
                        }
                        synchronized (nv21) {
                            System.arraycopy(nv21, 0, buffer, 0, nv21.length);
                        }
                        // 获取手机朝向,返回值0,1,2,3分别表示0,90,180和270度
                        int direction = Accelerometer.getDirection();
                        boolean frontCamera = (Camera.CameraInfo.CAMERA_FACING_FRONT == mCameraId);
                        // 前置摄像头预览显示的是镜像,需要将手机朝向换算成摄相头视角下的朝向。
                        // 转换公式:a' = (360 - a)%360,a为人眼视角下的朝向(单位:角度)
                        if (frontCamera) {
                            // SDK中使用0,1,2,3,4分别表示0,90,180,270和360度
                            direction = (4 - direction) % 4;
                        }
                        if (mFaceDetector == null) {
                            /**
                             * 离线视频流检测功能需要单独下载支持离线人脸的SDK 请开发者前往语音云官网下载对应SDK
                             */
                            ShowToast.showToast(getActivity(), "本SDK不支持离线视频流检测");
                            break;
                        }
    
                        String result = mFaceDetector.trackNV21(buffer,
                                PREVIEW_WIDTH, PREVIEW_HEIGHT, isAlign, direction);
    
                        FaceRect[] faces = ParseResult.parseResult(result);
    
                        drawRect(frontCamera, faces);
    
                    }
                }
    复制代码

    对人脸动作的检测

    复制代码
    if (isFace) {
                            // 进行活体检测
                            if (rectLength >= 160 && rectLength < 180) {
                                // 判断张嘴后进行拍照
                                if (mouth_bt >= 40 && !isOpenMouth) {
                                    isOpenMouth = true;
                                    isShakeHead = true;
                                    mHandler.sendEmptyMessageDelayed(
                                            StaticArguments.FACE_OPEN_MOUTH, 1000);
                                }
                                // 进行摇头判断
                                if (eyebrow_mlr_y < 79 && eyebrow_mlr_y >= 0
                                        && isShakeHead) {
                                    isOpenMouth = true;
    
                                    countHead++;
                                    if (countHead % 2 == 0) {
                                        mHandler.sendEmptyMessageDelayed(
                                                StaticArguments.FACE_SHAKE_HEAD,
                                                3000);
                                    }
                                }
    
                            } else if (rectLength >= 180 && rectLength < 200) {
                                // 判断张嘴后进行拍照
                                if (mouth_bt >= 45 && !isOpenMouth) {
                                    isShakeHead = true;
                                    isOpenMouth = true;
                                    mHandler.sendEmptyMessageDelayed(
                                            StaticArguments.FACE_OPEN_MOUTH, 1000);
                                }
                                // 进行摇头判断
                                if (eyebrow_mlr_y < 89 && eyebrow_mlr_y >= 0
                                        && isShakeHead) {
                                    isOpenMouth = true;
    
                                    countHead++;
                                    if (countHead % 2 == 0) {
                                        mHandler.sendEmptyMessageDelayed(
                                                StaticArguments.FACE_SHAKE_HEAD,
                                                1000);
                                    }
                                }
                            } else if (rectLength >= 200 && rectLength < 340) {
                                // 判断张嘴后进行拍照
                                if (mouth_bt >= 50 && !isOpenMouth) {
                                    isShakeHead = true;
                                    isOpenMouth = true;
                                    mHandler.sendEmptyMessageDelayed(
                                            StaticArguments.FACE_OPEN_MOUTH, 500);
                                }
                                // 进行摇头判断
                                if (eyebrow_mlr_y < 95 && eyebrow_mlr_y >= 0
                                        && isShakeHead) {
                                    isOpenMouth = true;
    
                                    countHead++;
                                    if (countHead % 2 == 0) {
                                        mHandler.sendEmptyMessageDelayed(
                                                StaticArguments.FACE_SHAKE_HEAD,
                                                1000);
                                    }
                                }
                            } else if (rectLength < 160) {// 检测脸部离手机太远
                                mHandler.sendEmptyMessage(StaticArguments.FACE_LENGTH_LONG);
                            } else if (rectLength >= 340 && rectLength >= 0) {// 检测脸部离手机太近
                                mHandler.sendEmptyMessage(StaticArguments.FACE_LENGTH_NEAR);
                            }
    }
    复制代码

    人脸张嘴或者摇头的动作后捕获视频的帧数据

    复制代码
    public void doStartPreview(SurfaceHolder holder, float previewRate) {
    
            if (isPreview) {
                mCamera.stopPreview();
                return;
            }
    
            if (mCamera != null) {
                mParams = mCamera.getParameters();
                mParams.setPictureFormat(PixelFormat.JPEG);// 设置拍照后存储的图片格式
                // 设置PreviewSize和PictureSize
                mParams.setPreviewFormat(ImageFormat.NV21);
                mParams.setPreviewSize(PREVIEW_WIDTH, PREVIEW_HEIGHT);
                mCamera.setParameters(mParams);
                mCamera.setDisplayOrientation(90);
                List<String> focusModes = mParams.getSupportedFocusModes();
                if (focusModes.contains("continuous-video")) {
                    mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
                }
                mCamera.setPreviewCallback(new PreviewCallback() {
                    @Override
                    public void onPreviewFrame(byte[] data, Camera camera) {
                        System.arraycopy(data, 0, nv21, 0, data.length);
                        if (takePictureFlag == 1) {
                            Bitmap mBitmap = null;
                            Camera.Parameters parameters = camera.getParameters();
                            int format = parameters.getPreviewFormat();
                            if (format == PixelFormat.YCbCr_420_SP
                                    || format == PixelFormat.YCbCr_422_I) {
                                int w = parameters.getPreviewSize().width;
                                int h = parameters.getPreviewSize().height;
                                int[] i = new int[data.length];
                                decodeYUV420SP(i, data, w, h);
                                mBitmap = Bitmap.createBitmap(i, w, h,
                                        Bitmap.Config.RGB_565);
                            } else if (format == PixelFormat.JPEG
                                    || format == PixelFormat.RGB_565) {
                                mBitmap = BitmapFactory.decodeByteArray(data, 0,
                                        data.length);
                            }
                            if (null != mBitmap) {
                                if (takePictureFlag == 1) {
                                    takePictureFlag++;
                                } else {
                                    return;
                                }
                                // 设置FOCUS_MODE_CONTINUOUS_VIDEO)之后,myParam.set("rotation",
                                // 90)失效。
                                // 图片竟然不能旋转了,故这里要旋转下
                                Bitmap rotateImage = FaceUtil.rotateImage(270,
                                        mBitmap);
    
                                if (mListener != null) {
                                    mListener.onTakePictuerResult(rotateImage);
                                }
                            }
                        }
                    }
                });
    
                try {
                    mCamera.setPreviewDisplay(holder);
                    mCamera.startPreview();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                isPreview = true;
            }
    
        }
    复制代码

    源码下载地址:

    https://github.com/reachchen/FaceRecognition

  • 相关阅读:
    数据结构小总结(成都磨子桥技工学校数据结构前12题)
    Scrum 冲刺博客第二篇
    Scrum 冲刺博客第一篇
    centos部署keepalived服务
    第四周作业
    Svelte 中怎样做双向数据绑定
    Svelte 中多层组件事件转发
    Svelte 中的事件修饰符
    怎样在 Svelte 中设置自定义事件
    怎样使用 Svelte 中的异步块
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/5602454.html
Copyright © 2020-2023  润新知