weimingfei
2 天以前 542c054c6904021e067364914fbf6b3947c5039b
指纹钥匙柜
已修改6个文件
1041 ■■■■ 文件已修改
keyCabinet-android/app/build.gradle 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/MApplication.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/FaceActivity.java 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWLRActivity.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainActivity.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/datalibrary/src/main/java/com/example/datalibrary/manager/FaceSDKManager.java 966 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keyCabinet-android/app/build.gradle
@@ -26,7 +26,7 @@
        ndk {
            moduleName "facesdk"
            ldLibs "log"
            abiFilters "armeabi-v7a","x86" // "armeabi", "x86", "arm64-v8a"
            abiFilters "arm64-v8a"
        }
        multiDexEnabled true
    }
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/MApplication.java
@@ -9,7 +9,6 @@
import android.widget.ImageView;
import androidx.annotation.Nullable;
import com.doumee.keyCabinet.bean.DevConfigBean;
import com.doumee.keyCabinet.bean.LoginBean;
import com.doumee.keyCabinet.utils.CrashHandler;
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/face/FaceActivity.java
@@ -5,6 +5,7 @@
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Handler;
@@ -15,6 +16,7 @@
import android.text.Spanned;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.format.DateUtils;
import android.text.style.TextAppearanceSpan;
import android.view.View;
import android.view.ViewTreeObserver;
@@ -37,6 +39,7 @@
import com.doumee.keyCabinet.event.TimeClockEvent;
import com.doumee.keyCabinet.ui.keyCabinet.KeyCabinetActivity;
import com.doumee.keyCabinet.utils.BraceletLogUtils;
import com.doumee.keyCabinet.utils.CrashHandler;
import com.doumee.keyCabinet.utils.face.FaceUtils;
import com.doumee.keyCabinet.utils.face.model.SingleBaseConfig;
import com.doumee.keyCabinet.utils.usb.DevComm;
@@ -57,6 +60,7 @@
import com.example.datalibrary.model.LivenessModel;
import com.example.datalibrary.model.User;
import com.example.datalibrary.utils.FaceOnDrawTexturViewUtil;
import com.example.datalibrary.utils.FileUtils;
import com.example.datalibrary.utils.ToastUtils;
import org.greenrobot.eventbus.EventBus;
@@ -64,6 +68,7 @@
import org.greenrobot.eventbus.ThreadMode;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@@ -572,6 +577,9 @@
        @Override
        public void onTip(int code, String msg) {
            if(1==code) {
                SpUtil.saveString(CrashHandler.FILE_NAME + StringUtil.DateToStr(new Date()), msg);
            }
            if(isToChose){
                return;
            }
@@ -728,46 +736,25 @@
                return;
            }
            if (livenessModel == null) {
                if (isCompareCheck) {
                        /*getDB().clFail.setVisibility(View.VISIBLE);
                        getDB().tv4.setText(getString(R.string.face_tip2));
                        handler.sendEmptyMessageDelayed(0,1000);*/
                }
                //System.out.println("======>人脸识别失败");
                return;
            }
            if (livenessModel.isQualityCheck()) {
                //是否通过质量检测
                if (isCompareCheck) {
                        /*getDB().clFail.setVisibility(View.VISIBLE);
                        getDB().tv4.setText(getString(R.string.face_tip2));
                        handler.sendEmptyMessageDelayed(0,1000);*/
                }
            } else {
                User user = livenessModel.getUser();
                if (user == null) {
                    mUser = null;
                    //EventBus.getDefault().post(new HttpEvent("人脸用户检测失败------->"+(status==0?"管理员人脸检测:":"司机人脸检测:")));
                    if (isCompareCheck) {
                            /*getDB().clFail.setVisibility(View.VISIBLE);
                            getDB().tv4.setText(getString(R.string.face_tip2));
                            handler.sendEmptyMessageDelayed(0,1000);*/
                    }
                } else {
                    mUser = user;
                        /*EventBus.getDefault().post(new HttpEvent("人脸用户------->"+(status==0?"管理员人脸检测:":"司机人脸检测:")
                                +(user.getGroupId().equals("0")?"管理员":"司机")));*/
                        //EventBus.getDefault().post(new HttpEvent("人脸用户------->"+(status==0?"管理员人脸检测:":"司机人脸检测:")+(user.getGroupId().equals("0")?"管理员":"司机")));
                    if (isCompareCheck) {
                        getDB().clFail.setVisibility(View.GONE);
                        if (handler.hasMessages(0)) {
                            handler.removeMessages(0);
                        }
                            /*textHuanying.setVisibility(View.GONE);
                            userNameLayout.setVisibility(View.VISIBLE);
                            nameImage.setImageResource(R.mipmap.ic_tips_gate_success);
                            nameText.setTextColor(Color.parseColor("#0dc6ff"));
                            nameText.setText(FileUtils.spotString(user.getUserName()) + " 欢迎您");*/
                    }
                    isToChose = true;
                    //识别成功,跳转
@@ -979,12 +966,7 @@
                    EventBus.getDefault().post(new HttpEvent("连接设备失败3," + mDevComm.Run_GetDeviceInfo(w_strInfo)));
                }
            } else {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        EventBus.getDefault().post(new HttpEvent("连接设备失败4,"+mDevComm.Run_TestConnection()));
                    }
                });
                EventBus.getDefault().post(new HttpEvent("连接设备失败4,"+mDevComm.Run_TestConnection()));
                mDevComm.CloseComm();
            }
        }
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/keyCabinet/ZWLRActivity.java
@@ -256,12 +256,6 @@
        }
    }
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void HttpEvent(HttpEvent e){
        if(!isFinishing()){
            getVM().addInfo(e.getMsg());
        }
    }
    private static DevComm mDevComm;
    //最大指纹数
    private int maxFpCount = 500;
keyCabinet-android/app/src/main/java/com/doumee/keyCabinet/ui/main/MainActivity.java
@@ -135,6 +135,7 @@
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.regex.Matcher;
@@ -229,23 +230,6 @@
        getPermission();
        mXService = new MyService(this);
        //Timber.tag("====>").d(LMobileInfo.getDeviceUniqueId());
        Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
            String time2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            getVM().addInfo("GlobalException线程报错:" + thread.getName());
            try {
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                PrintStream print = new PrintStream(out);
                //导出发生异常的时间
                print.println(time2);
                print.println();
                throwable.printStackTrace(print);
                SpUtil.saveString(CrashHandler.FILE_NAME+time2,new String(out.toByteArray()));
                print.close();
            } catch (Exception e) {
                e.printStackTrace();
                getVM().addInfo("错误日志2"+e.getMessage());
            }
        });
    }
    private void initM(){
@@ -260,6 +244,7 @@
        if((availableMemory<100&&showTime!=null&&(System.currentTimeMillis()-showTime>5000))||
                ("02:00:00".equals(StringUtil.getHM()))){
            //可用内存小于400M,或者每天凌晨2点,重启app
            //ToastView.show(MApplication.mContext,"内存紧张,重新启动");
            restartApp();
        }
    }
@@ -315,7 +300,6 @@
                }
                lastDownTime1 = System.currentTimeMillis();
                downCount1++;
                System.out.println();
                //Timber.tag("==>").d(""+downCount1);
                if(downCount1>4) {
                    downCount1=0;
@@ -342,7 +326,6 @@
                }
            }
        });
        getDB().imgLeft.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v1) {
@@ -585,7 +568,6 @@
    @Subscribe
    public void GetFacesEvent(GetFacesEvent event){
        getVM().addInfo("查询人脸数据======》");
        if(!isFinishing()&&!isUpdatingFace){
            getVM().addInfo("查询人脸数据======》isDBLoad = "+isDBLoad);
            if(isDBLoad){
@@ -1385,7 +1367,7 @@
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void HttpEvent(HttpEvent e){
        if(!isFinishing()){
        if(!isFinishing()&&getVM()!=null){
            getVM().addInfo(e.getMsg());
        }
    }
keyCabinet-android/datalibrary/src/main/java/com/example/datalibrary/manager/FaceSDKManager.java
@@ -565,78 +565,80 @@
                    @Override
                    public void run() {
                        try {
                            // 获取BDFaceCheckConfig配置信息
                            if (bdFaceCheckConfig == null) {
                        // 获取BDFaceCheckConfig配置信息
                        if (bdFaceCheckConfig == null) {
                                return;
                            }
                            onDetect(
                                    bdFaceCheckConfig,
                                    rgbInstance,
                                    fastFaceInfos,
                                    livenessModel,
                                    new DetectListener() {
                            return;
                        }
                        onDetect(
                            bdFaceCheckConfig,
                            rgbInstance,
                            fastFaceInfos,
                            livenessModel,
                            new DetectListener() {
                                        @Override
                                        public void onDetectSuccess(FaceInfo[] faceInfos, BDFaceImageInstance rgbInstance) {
                                @Override
                                public void onDetectSuccess(FaceInfo[] faceInfos, BDFaceImageInstance rgbInstance) {
                                            try {
                                    // 人脸id赋值
                                    if (mLastFaceId != fastFaceInfos[0].faceID) {
                                        mLastFaceId = fastFaceInfos[0].faceID;
                                        mRgbLiveList.clear();
                                        mNirLiveList.clear();
                                    }
                                                // 人脸id赋值
                                                if (mLastFaceId != fastFaceInfos[0].faceID) {
                                                    mLastFaceId = fastFaceInfos[0].faceID;
                                                    mRgbLiveList.clear();
                                                    mNirLiveList.clear();
                                                }
                                    if (bdFaceCheckConfig == null) {
                                                if (bdFaceCheckConfig == null) {
                                        livenessModel.clearIdentifyResults();
                                        if (faceDetectCallBack != null) {
                                            faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                        }
                                        return;
                                    }
                                                    livenessModel.clearIdentifyResults();
                                                    if (faceDetectCallBack != null) {
                                                        faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                                    }
                                                    return;
                                                }
                                    // 最优人脸控制
                                    if (!onBestImageCheck(livenessModel, bdFaceCheckConfig, faceDetectCallBack)) {
                                        livenessModel.setQualityCheck(true);
                                        livenessModel.clearIdentifyResults();
                                                // 最优人脸控制
                                                if (!onBestImageCheck(livenessModel, bdFaceCheckConfig, faceDetectCallBack)) {
                                                    livenessModel.setQualityCheck(true);
                                                    livenessModel.clearIdentifyResults();
                                        if (faceDetectCallBack != null) {
                                            faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                        }
                                        return;
                                    }
                                                    if (faceDetectCallBack != null) {
                                                        faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                                    }
                                                    return;
                                                }
                                    // 质量检测未通过,销毁BDFaceImageInstance,结束函数
                                                // 质量检测未通过,销毁BDFaceImageInstance,结束函数
                                    if (!onQualityCheck(
                                            faceInfos, bdFaceCheckConfig.bdQualityConfig, faceDetectCallBack)) {
                                        livenessModel.setQualityCheck(true);
                                        livenessModel.clearIdentifyResults();
                                                if (!onQualityCheck(
                                                        faceInfos, bdFaceCheckConfig.bdQualityConfig, faceDetectCallBack)) {
                                                    livenessModel.setQualityCheck(true);
                                                    livenessModel.clearIdentifyResults();
                                        if (faceDetectCallBack != null) {
                                            faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                        }
                                        return;
                                    }
                                                    if (faceDetectCallBack != null) {
                                                        faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                                    }
                                                    return;
                                                }
                                    livenessModel.setQualityCheck(false);
                                    // 获取LivenessConfig liveCheckMode 配置选项:【不使用活体:0】;【RGB活体:1】;【RGB+NIR活体:2】;【RGB+Depth活体:3】;【RGB+NIR+Depth活体:4】
                                    // TODO 活体检测
                                    float[] rgbScores = {-1};
                                    BDLiveConfig bdLiveConfig = bdFaceCheckConfig.bdLiveConfig;
                                    boolean isLiveCheck = bdFaceCheckConfig.bdLiveConfig != null;
                                                livenessModel.setQualityCheck(false);
                                                // 获取LivenessConfig liveCheckMode 配置选项:【不使用活体:0】;【RGB活体:1】;【RGB+NIR活体:2】;【RGB+Depth活体:3】;【RGB+NIR+Depth活体:4】
                                                // TODO 活体检测
                                                float[] rgbScores = {-1};
                                                BDLiveConfig bdLiveConfig = bdFaceCheckConfig.bdLiveConfig;
                                                boolean isLiveCheck = bdFaceCheckConfig.bdLiveConfig != null;
                                    if (isLiveCheck) {
                                        long startRgbTime = System.currentTimeMillis();
                                        rgbScores =
                                            silentLives(
                                                rgbInstance,
                                                BDFaceSDKCommon.LiveType.BDFACE_SILENT_LIVE_TYPE_RGB,
                                                faceInfos,
                                                mRgbLiveList,
                                                bdLiveConfig.rgbLiveScore);
                                                if (isLiveCheck) {
                                                    long startRgbTime = System.currentTimeMillis();
                                                    rgbScores =
                                                            silentLives(
                                                                    rgbInstance,
                                                                    BDFaceSDKCommon.LiveType.BDFACE_SILENT_LIVE_TYPE_RGB,
                                                                    faceInfos,
                                                                    mRgbLiveList,
                                                                    bdLiveConfig.rgbLiveScore);
                                        /* if (rgbScores != null){
                                            int size = rgbScores.length;
                                            Log.d("Attend", "score size:" + size);
@@ -645,220 +647,230 @@
                                            }
                                        } */
                                        if (faceInfos.length == 1) {
                                            livenessModel.setRgbLivenessScore(rgbScores[0]);
                                        }
                                        livenessModel.setRgbLivenessScores(rgbScores);
                                        livenessModel.setRgbLivenessDuration(System.currentTimeMillis() - startRgbTime);
                                    }
                                    // TODO nir活体检测
                                    float nirScore = -1;
                                    FaceInfo[] faceInfosIr = null;
                                    BDFaceImageInstance nirInstance = null;
                                    boolean isHaveNirImage = nirBDFaceImageConfig != null && isLiveCheck;
                                    if (isHaveNirImage) {
                                        // 创建检测对象,如果原始数据YUV-IR,转为算法检测的图片BGR
                                        // TODO: 用户调整旋转角度和是否镜像,手机和开发版需要动态适配
                                        long nirInstanceTime = System.currentTimeMillis();
                                        nirInstance = getBdImage(nirBDFaceImageConfig, false);
                                        livenessModel.setBdNirFaceImageInstance(nirInstance.getImage());
                                        livenessModel.setNirInstanceTime(System.currentTimeMillis() - nirInstanceTime);
                                        // 避免RGB检测关键点在IR对齐活体稳定,增加红外检测
                                        long startIrDetectTime = System.currentTimeMillis();
                                        BDFaceDetectListConf bdFaceDetectListConf = new BDFaceDetectListConf();
                                        bdFaceDetectListConf.usingDetect = true;
                                        faceInfosIr =
                                            faceModel
                                                .getFaceNirDetect()
                                                .detect(
                                                    BDFaceSDKCommon.DetectType.DETECT_NIR,
                                                    BDFaceSDKCommon.AlignType.BDFACE_ALIGN_TYPE_NIR_ACCURATE,
                                                    nirInstance,
                                                    null,
                                                    bdFaceDetectListConf);
                                        livenessModel.setIrLivenessDuration(
                                            System.currentTimeMillis() - startIrDetectTime);
                                        //                    LogUtils.e(TIME_TAG, "detect ir time = " + livenessModel.getIrLivenessDuration());
                                        if (faceInfosIr != null && faceInfosIr.length > 0) {
                                            FaceInfo faceInfoIr = faceInfosIr[0];
                                            nirScore =
                                                silentLive(
                                                    nirInstance,
                                                    BDFaceSDKCommon.LiveType.BDFACE_SILENT_LIVE_TYPE_NIR,
                                                    faceInfoIr.landmarks,
                                                    mNirLiveList,
                                                    bdLiveConfig.nirLiveScore);
                                            livenessModel.setIrLivenessScore(nirScore);
                                            //                        LogUtils.e(TIME_TAG, "live ir time = " + livenessModel.getIrLivenessDuration());
                                        }
                                    }
                                    // TODO depth活体检测
                                    float depthScore = -1;
                                    boolean isHaveDepthImage = depthBDFaceImageConfig != null && isLiveCheck;
                                    if (depthBDFaceImageConfig != null) {
                                        // TODO: 用户调整旋转角度和是否镜像,适配Atlas 镜头,目前宽和高400*640,其他摄像头需要动态调整,人脸72 个关键点x 坐标向左移动80个像素点
                                        float[] depthLandmark = new float[faceInfos[0].landmarks.length];
                                        BDFaceImageInstance depthInstance;
                                        if (bdFaceCheckConfig.cameraType == 1) {
                                            System.arraycopy(
                                                faceInfos[0].landmarks,
                                                0,
                                                depthLandmark,
                                                0,
                                                faceInfos[0].landmarks.length);
                                            for (int i = 0; i < 144; i = i + 2) {
                                                depthLandmark[i] -= 80;
                                            }
                                        } else {
                                            depthLandmark = faceInfos[0].landmarks;
                                        }
                                        depthInstance = getBdImage(depthBDFaceImageConfig, false);
                                        livenessModel.setBdDepthFaceImageInstance(depthInstance.getImage());
                                        // 创建检测对象,如果原始数据Depth
                                        long startDepthTime = System.currentTimeMillis();
                                        depthScore =
                                            faceModel
                                                .getFaceLive()
                                                .silentLive(
                                                    BDFaceSDKCommon.LiveType.BDFACE_SILENT_LIVE_TYPE_DEPTH,
                                                    depthInstance,
                                                    depthLandmark);
                                        livenessModel.setDepthLivenessScore(depthScore);
                                        livenessModel.setDepthtLivenessDuration(
                                            System.currentTimeMillis() - startDepthTime);
                                        //                    LogUtils.e(TIME_TAG, "live depth time = " + livenessModel.getDepthtLivenessDuration());
                                        depthInstance.destory();
                                    }
                                    boolean isRgbScoreCheck = false;
                                    boolean isNirScoreCheck = false;
                                    boolean isDepthScoreCheck = false;
                                    if (isLiveCheck) {
                                        int size = rgbScores.length;
                                        for (int i = 0; i < size; i++) {
                                            if (rgbScores[i] > bdLiveConfig.rgbLiveScore) {
                                                isRgbScoreCheck = true;
                                            }
                                        }
                                        // isRgbScoreCheck = true; // liujinhui for test
                                        //   isRgbScoreCheck = (rgbScores[0] > bdLiveConfig.rgbLiveScore);
                                        isNirScoreCheck =
                                            (isHaveNirImage ? nirScore > bdLiveConfig.nirLiveScore : true);
                                        isDepthScoreCheck =
                                            (isHaveDepthImage ? depthScore > bdLiveConfig.depthLiveScore : true);
                                    }
                                    // 如果设置为不进行活体检测
                                    int liveCheckMode = livenessModel.getLiveType();
                                    if (liveCheckMode == 0){
                                        isRgbScoreCheck = true;
                                    }
                                    // TODO 特征提取+人脸检索
                                    if (!isLiveCheck || (isRgbScoreCheck && isNirScoreCheck && isDepthScoreCheck)) {
                                        if (livenessModel != null) {
                                            livenessModel.clearIdentifyResults();
                                            livenessModel.setUser(null);
                                        }
                                        synchronized (faceModel.getFaceSearch()) {
                                            if (faceInfos != null) {
                                                int size = faceInfos.length;
                                                for (int i = 0; i < size; i++) {
                                                    // 特征提取
                                                    // 模糊结果过滤,戴口罩时候,不进行过滤
                                                    if (!checkMouthMask) {
                                                        float blur = faceInfos[i].bluriness;
                                                        BDFaceOcclusion occlusion = faceInfos[i].occlusion;
                                                        float leftEye = occlusion.leftEye;
                                                        // "左眼遮挡"
                                                        float rightEye = occlusion.rightEye;
                                                        // "右眼遮挡"
                                                        float nose = occlusion.nose;
                                                        // "鼻子遮挡置信度"
                                                        float mouth = occlusion.mouth;
                                                        // "嘴巴遮挡置信度"
                                                        float leftCheek = occlusion.leftCheek;
                                                        // "左脸遮挡"
                                                        float rightCheek = occlusion.rightCheek;
                                                        // "右脸遮挡"
                                                        float chin = occlusion.chin;
                                                        // 动态底库限制
                                                        faceModel
                                                                .getFaceSearch()
                                                                .setNeedJoinDB(
                                                                        selectQuality(
                                                                                blur,
                                                                                leftEye,
                                                                                rightEye,
                                                                                nose,
                                                                                mouth,
                                                                                leftCheek,
                                                                                rightCheek,
                                                                                chin));
                                                    if (faceInfos.length == 1) {
                                                        livenessModel.setRgbLivenessScore(rgbScores[0]);
                                                    }
                                                    if (bdLiveConfig != null){
                                                        onFeatureChecks(
                                                                i,
                                                                rgbInstance,
                                                                bdFaceCheckConfig,
                                                                faceInfos,
                                                                faceInfosIr,
                                                                nirInstance,
                                                                livenessModel,
                                                                bdFaceCheckConfig.secondFeature,
                                                                bdFaceCheckConfig.featureCheckMode,
                                                                bdFaceCheckConfig.activeModel,
                                                                rgbScores,
                                                                bdLiveConfig.rgbLiveScore);
                                                    } else{
                                                        onFeatureChecks(
                                                                i,
                                                                rgbInstance,
                                                                bdFaceCheckConfig,
                                                                faceInfos,
                                                                faceInfosIr,
                                                                nirInstance,
                                                                livenessModel,
                                                                bdFaceCheckConfig.secondFeature,
                                                                bdFaceCheckConfig.featureCheckMode,
                                                                bdFaceCheckConfig.activeModel,
                                                                rgbScores,
                                                                -1);
                                                    }
                                                    livenessModel.setRgbLivenessScores(rgbScores);
                                                    livenessModel.setRgbLivenessDuration(System.currentTimeMillis() - startRgbTime);
                                                }
                                                // TODO nir活体检测
                                                float nirScore = -1;
                                                FaceInfo[] faceInfosIr = null;
                                                BDFaceImageInstance nirInstance = null;
                                                boolean isHaveNirImage = nirBDFaceImageConfig != null && isLiveCheck;
                                                if (isHaveNirImage) {
                                                    // 创建检测对象,如果原始数据YUV-IR,转为算法检测的图片BGR
                                                    // TODO: 用户调整旋转角度和是否镜像,手机和开发版需要动态适配
                                                    long nirInstanceTime = System.currentTimeMillis();
                                                    nirInstance = getBdImage(nirBDFaceImageConfig, false);
                                                    livenessModel.setBdNirFaceImageInstance(nirInstance.getImage());
                                                    livenessModel.setNirInstanceTime(System.currentTimeMillis() - nirInstanceTime);
                                                    // 避免RGB检测关键点在IR对齐活体稳定,增加红外检测
                                                    long startIrDetectTime = System.currentTimeMillis();
                                                    BDFaceDetectListConf bdFaceDetectListConf = new BDFaceDetectListConf();
                                                    bdFaceDetectListConf.usingDetect = true;
                                                    faceInfosIr =
                                                            faceModel
                                                                    .getFaceNirDetect()
                                                                    .detect(
                                                                            BDFaceSDKCommon.DetectType.DETECT_NIR,
                                                                            BDFaceSDKCommon.AlignType.BDFACE_ALIGN_TYPE_NIR_ACCURATE,
                                                                            nirInstance,
                                                                            null,
                                                                            bdFaceDetectListConf);
                                                    livenessModel.setIrLivenessDuration(
                                                            System.currentTimeMillis() - startIrDetectTime);
                                                    //                    LogUtils.e(TIME_TAG, "detect ir time = " + livenessModel.getIrLivenessDuration());
                                                    if (faceInfosIr != null && faceInfosIr.length > 0) {
                                                        FaceInfo faceInfoIr = faceInfosIr[0];
                                                        nirScore =
                                                                silentLive(
                                                                        nirInstance,
                                                                        BDFaceSDKCommon.LiveType.BDFACE_SILENT_LIVE_TYPE_NIR,
                                                                        faceInfoIr.landmarks,
                                                                        mNirLiveList,
                                                                        bdLiveConfig.nirLiveScore);
                                                        livenessModel.setIrLivenessScore(nirScore);
                                                        //                        LogUtils.e(TIME_TAG, "live ir time = " + livenessModel.getIrLivenessDuration());
                                                    }
                                                }
                                                // TODO depth活体检测
                                                float depthScore = -1;
                                                boolean isHaveDepthImage = depthBDFaceImageConfig != null && isLiveCheck;
                                                if (depthBDFaceImageConfig != null) {
                                                    // TODO: 用户调整旋转角度和是否镜像,适配Atlas 镜头,目前宽和高400*640,其他摄像头需要动态调整,人脸72 个关键点x 坐标向左移动80个像素点
                                                    float[] depthLandmark = new float[faceInfos[0].landmarks.length];
                                                    BDFaceImageInstance depthInstance;
                                                    if (bdFaceCheckConfig.cameraType == 1) {
                                                        System.arraycopy(
                                                                faceInfos[0].landmarks,
                                                                0,
                                                                depthLandmark,
                                                                0,
                                                                faceInfos[0].landmarks.length);
                                                        for (int i = 0; i < 144; i = i + 2) {
                                                            depthLandmark[i] -= 80;
                                                        }
                                                    } else {
                                                        depthLandmark = faceInfos[0].landmarks;
                                                    }
                                                    depthInstance = getBdImage(depthBDFaceImageConfig, false);
                                                    livenessModel.setBdDepthFaceImageInstance(depthInstance.getImage());
                                                    // 创建检测对象,如果原始数据Depth
                                                    long startDepthTime = System.currentTimeMillis();
                                                    depthScore =
                                                            faceModel
                                                                    .getFaceLive()
                                                                    .silentLive(
                                                                            BDFaceSDKCommon.LiveType.BDFACE_SILENT_LIVE_TYPE_DEPTH,
                                                                            depthInstance,
                                                                            depthLandmark);
                                                    livenessModel.setDepthLivenessScore(depthScore);
                                                    livenessModel.setDepthtLivenessDuration(
                                                            System.currentTimeMillis() - startDepthTime);
                                                    //                    LogUtils.e(TIME_TAG, "live depth time = " + livenessModel.getDepthtLivenessDuration());
                                                    depthInstance.destory();
                                                }
                                                boolean isRgbScoreCheck = false;
                                                boolean isNirScoreCheck = false;
                                                boolean isDepthScoreCheck = false;
                                                if (isLiveCheck) {
                                                    int size = rgbScores.length;
                                                    for (int i = 0; i < size; i++) {
                                                        if (rgbScores[i] > bdLiveConfig.rgbLiveScore) {
                                                            isRgbScoreCheck = true;
                                                        }
                                                    }
                                                    // isRgbScoreCheck = true; // liujinhui for test
                                                    //   isRgbScoreCheck = (rgbScores[0] > bdLiveConfig.rgbLiveScore);
                                                    isNirScoreCheck =
                                                            (isHaveNirImage ? nirScore > bdLiveConfig.nirLiveScore : true);
                                                    isDepthScoreCheck =
                                                            (isHaveDepthImage ? depthScore > bdLiveConfig.depthLiveScore : true);
                                                }
                                                // 如果设置为不进行活体检测
                                                int liveCheckMode = livenessModel.getLiveType();
                                                if (liveCheckMode == 0) {
                                                    isRgbScoreCheck = true;
                                                }
                                                // TODO 特征提取+人脸检索
                                                if (!isLiveCheck || (isRgbScoreCheck && isNirScoreCheck && isDepthScoreCheck)) {
                                                    if (livenessModel != null) {
                                                        livenessModel.clearIdentifyResults();
                                                        livenessModel.setUser(null);
                                                    }
                                                    synchronized (faceModel.getFaceSearch()) {
                                                        if (faceInfos != null) {
                                                            int size = faceInfos.length;
                                                            for (int i = 0; i < size; i++) {
                                                                // 特征提取
                                                                // 模糊结果过滤,戴口罩时候,不进行过滤
                                                                if (!checkMouthMask) {
                                                                    float blur = faceInfos[i].bluriness;
                                                                    BDFaceOcclusion occlusion = faceInfos[i].occlusion;
                                                                    float leftEye = occlusion.leftEye;
                                                                    // "左眼遮挡"
                                                                    float rightEye = occlusion.rightEye;
                                                                    // "右眼遮挡"
                                                                    float nose = occlusion.nose;
                                                                    // "鼻子遮挡置信度"
                                                                    float mouth = occlusion.mouth;
                                                                    // "嘴巴遮挡置信度"
                                                                    float leftCheek = occlusion.leftCheek;
                                                                    // "左脸遮挡"
                                                                    float rightCheek = occlusion.rightCheek;
                                                                    // "右脸遮挡"
                                                                    float chin = occlusion.chin;
                                                                    // 动态底库限制
                                                                    faceModel
                                                                            .getFaceSearch()
                                                                            .setNeedJoinDB(
                                                                                    selectQuality(
                                                                                            blur,
                                                                                            leftEye,
                                                                                            rightEye,
                                                                                            nose,
                                                                                            mouth,
                                                                                            leftCheek,
                                                                                            rightCheek,
                                                                                            chin));
                                                                }
                                                                if (bdLiveConfig != null) {
                                                                    onFeatureChecks(
                                                                            i,
                                                                            rgbInstance,
                                                                            bdFaceCheckConfig,
                                                                            faceInfos,
                                                                            faceInfosIr,
                                                                            nirInstance,
                                                                            livenessModel,
                                                                            bdFaceCheckConfig.secondFeature,
                                                                            bdFaceCheckConfig.featureCheckMode,
                                                                            bdFaceCheckConfig.activeModel,
                                                                            rgbScores,
                                                                            bdLiveConfig.rgbLiveScore);
                                                                } else {
                                                                    onFeatureChecks(
                                                                            i,
                                                                            rgbInstance,
                                                                            bdFaceCheckConfig,
                                                                            faceInfos,
                                                                            faceInfosIr,
                                                                            nirInstance,
                                                                            livenessModel,
                                                                            bdFaceCheckConfig.secondFeature,
                                                                            bdFaceCheckConfig.featureCheckMode,
                                                                            bdFaceCheckConfig.activeModel,
                                                                            rgbScores,
                                                                            -1);
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                                // 流程结束,记录最终时间
                                                livenessModel.setAllDetectDuration(System.currentTimeMillis() - startTime);
                                                //                LogUtils.e(TIME_TAG, "all process time = " + livenessModel.getAllDetectDuration());
                                                // 流程结束销毁图片,开始下一帧图片检测,否着内存泄露
                                                if (nirInstance != null) {
                                                    nirInstance.destory();
                                                }
                                                // 显示最终结果提示
                                                if (faceDetectCallBack != null) {
                                                    faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                                }
                                            }catch (RuntimeException e){
                                                faceDetectCallBack.onTip(1,e.getMessage());
                                            }catch (Exception e){
                                                faceDetectCallBack.onTip(1,e.getMessage());
                                            }
                                        }
                                    }
                                    // 流程结束,记录最终时间
                                    livenessModel.setAllDetectDuration(System.currentTimeMillis() - startTime);
                                    //                LogUtils.e(TIME_TAG, "all process time = " + livenessModel.getAllDetectDuration());
                                    // 流程结束销毁图片,开始下一帧图片检测,否着内存泄露
                                        @Override
                                        public void onDetectFail() {
                                    if (nirInstance != null) {
                                        nirInstance.destory();
                                    }
                                    // 显示最终结果提示
                                    if (faceDetectCallBack != null) {
                                        faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                    }
                                }
                                @Override
                                public void onDetectFail() {
                                    if (faceDetectCallBack != null) {
                                        faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                    }
                                }
                            });
                                            if (faceDetectCallBack != null) {
                                                faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                            }
                                        }
                                    });
                        }catch (RuntimeException e){
                            faceDetectCallBack.onTip(1,e.getMessage());
                        }catch (Exception e){
                            faceDetectCallBack.onTip(1,e.getMessage());
                        }
                    }
                });
    }
@@ -884,82 +896,6 @@
            }
        }
        return isBestImageCheck;
    }
    /**
     * 特征提取-人脸识别比对
     *
     * @param rgbInstance      可见光底层送检对象
     * @param landmark         检测眼睛,嘴巴,鼻子,72个关键点
     * @param faceInfos        nir人脸数据
     * @param nirInstance      nir 图像句柄
     * @param livenessModel    检测结果数据集合
     * @param featureCheckMode 特征抽取模式【不提取特征:1】;【提取特征:2】;【提取特征+1:N检索:3】;
     * @param featureType      特征抽取模态执行 【生活照:1】;【证件照:2】;【混合模态:3】;
     */
    private void onFeatureCheck(
        BDFaceImageInstance rgbInstance,
        BDFaceCheckConfig bdFaceCheckConfig,
        float[] landmark,
        FaceInfo[] faceInfos,
        BDFaceImageInstance nirInstance,
        LivenessModel livenessModel,
        byte[] secondFeature,
        final int featureCheckMode,
        final int featureType) {
        // 如果不抽取特征,直接返回
        if (featureCheckMode == 1) {
            return;
        }
        byte[] feature = new byte[512];
        if (featureType == 3) {
            // todo: 混合模态使用方式是根据图片的曝光来选择需要使用的type,光照的取值范围为:0~1之间
            AtomicInteger atomicInteger = new AtomicInteger();
            FaceSDKManager.getInstance().getImageIllum().imageIllum(rgbInstance, atomicInteger);
            int illumScore = atomicInteger.get();
            BDQualityConfig bdQualityConfig = bdFaceCheckConfig.bdQualityConfig;
            boolean isIllum = bdQualityConfig != null ? illumScore < bdQualityConfig.illum : false;
            BDFaceSDKCommon.FeatureType type =
                isIllum
                    ? BDFaceSDKCommon.FeatureType.BDFACE_FEATURE_TYPE_NIR
                    : BDFaceSDKCommon.FeatureType.BDFACE_FEATURE_TYPE_LIVE_PHOTO;
            BDFaceImageInstance bdFaceImageInstance = isIllum ? nirInstance : rgbInstance;
            float[] landmarks = isIllum ? faceInfos[0].landmarks : landmark;
            long startFeatureTime = System.currentTimeMillis();
            float featureSize = faceModel.getFaceFeature().feature(type, bdFaceImageInstance, landmarks, feature);
            livenessModel.setFeatureDuration(System.currentTimeMillis() - startFeatureTime);
            livenessModel.setFeature(feature);
            // 人脸检索
            featureSearch(
                featureCheckMode,
                livenessModel,
                bdFaceCheckConfig,
                feature,
                secondFeature,
                featureSize,
                BDFaceSDKCommon.FeatureType.BDFACE_FEATURE_TYPE_LIVE_PHOTO);
        } else {
            // 生活照检索
            long startFeatureTime = System.currentTimeMillis();
            float featureSize =
                faceModel
                    .getFaceFeature()
                    .feature(
                        BDFaceSDKCommon.FeatureType.BDFACE_FEATURE_TYPE_LIVE_PHOTO, rgbInstance, landmark, feature);
            livenessModel.setFeatureDuration(System.currentTimeMillis() - startFeatureTime);
            livenessModel.setFeature(feature);
            livenessModel.setFeatureDuration(System.currentTimeMillis() - startFeatureTime);
            // 人脸检索
            featureSearch(
                featureCheckMode,
                livenessModel,
                bdFaceCheckConfig,
                feature,
                secondFeature,
                featureSize,
                BDFaceSDKCommon.FeatureType.BDFACE_FEATURE_TYPE_LIVE_PHOTO);
        }
    }
    /**
@@ -1384,183 +1320,195 @@
                    @Override
                    public void run() {
                        onDetect(
                            bdFaceCheckConfig,
                            rgbInstance,
                            fastFaceInfos,
                            livenessModel,
                            new DetectListener() {
                                @Override
                                public void onDetectSuccess(FaceInfo[] faceInfos, BDFaceImageInstance rgbInstance) {
                                    // 人脸id赋值
                                    if (mLastFaceId != fastFaceInfos[0].faceID) {
                                        mLastFaceId = fastFaceInfos[0].faceID;
                                        mRgbLiveList.clear();
                                        mNirLiveList.clear();
                                    }
                                    if (bdFaceCheckConfig == null) {
                                        if (faceDetectCallBack != null) {
                                            faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                        }
                                        return;
                                    }
                                    // 最优人脸控制
                                    if (!onBestImageCheck(livenessModel, bdFaceCheckConfig, faceDetectCallBack)) {
                                        livenessModel.setQualityCheck(true);
                                        if (faceDetectCallBack != null) {
                                            faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                        }
                                        return;
                                    }
                                    onQualityCheck(
                                        faceInfos,
                                        bdFaceCheckConfig.bdQualityConfig,
                                        faceDetectCallBack,
                                        new QualityListener() {
                                            @Override
                                            public void onQualitySuccess() {
                                                livenessModel.setQualityCheck(false);
                                                // 获取LivenessConfig liveCheckMode 配置选项:【不使用活体:0】;【RGB活体:1】;【RGB+NIR活体:2】;【RGB+Depth活体:3】;【RGB+NIR+Depth活体:4】
                                                // TODO 活体检测
                                                BDLiveConfig bdLiveConfig = bdFaceCheckConfig.bdLiveConfig;
                                                boolean isLiveCheck = bdFaceCheckConfig.bdLiveConfig != null;
                                                if (isLiveCheck) {
                                                    long startRgbTime = System.currentTimeMillis();
                                                    boolean rgbLiveStatus =
                                                        faceModel
                                                            .getFaceLive()
                                                            .strategySilentLive(
                                                                BDFaceSDKCommon.LiveType.BDFACE_SILENT_LIVE_TYPE_RGB,
                                                                rgbInstance,
                                                                faceInfos[0],
                                                                bdLiveConfig.framesThreshold,
                                                                bdLiveConfig.rgbLiveScore);
                                                    livenessModel.setRGBLiveStatus(rgbLiveStatus);
                                                    livenessModel.setRgbLivenessDuration(
                                                        System.currentTimeMillis() - startRgbTime);
                        try {
                            onDetect(
                                    bdFaceCheckConfig,
                                    rgbInstance,
                                    fastFaceInfos,
                                    livenessModel,
                                    new DetectListener() {
                                        @Override
                                        public void onDetectSuccess(FaceInfo[] faceInfos, BDFaceImageInstance rgbInstance) {
                                            try {
                                                // 人脸id赋值
                                                if (mLastFaceId != fastFaceInfos[0].faceID) {
                                                    mLastFaceId = fastFaceInfos[0].faceID;
                                                    mRgbLiveList.clear();
                                                    mNirLiveList.clear();
                                                }
                                                // TODO nir活体检测
                                                BDFaceImageInstance nirInstance = null;
                                                boolean isHaveNirImage = nirBDFaceImageConfig != null && isLiveCheck;
                                                if (isHaveNirImage) {
                                                if (bdFaceCheckConfig == null) {
                                                    // 创建检测对象,如果原始数据YUV-IR,转为算法检测的图片BGR
                                                    // TODO: 用户调整旋转角度和是否镜像,手机和开发版需要动态适配
                                                    nirInstance = getBdImage(nirBDFaceImageConfig, false);
                                                    livenessModel.setBdNirFaceImageInstance(nirInstance.getImage());
                                                    // 避免RGB检测关键点在IR对齐活体稳定,增加红外检测
                                                    long startIrDetectTime = System.currentTimeMillis();
                                                    BDFaceDetectListConf bdFaceDetectListConf =
                                                        new BDFaceDetectListConf();
                                                    bdFaceDetectListConf.usingDetect = true;
                                                    FaceInfo[] faceInfosIr =
                                                        faceModel
                                                            .getFaceNirDetect()
                                                            .detect(
                                                                BDFaceSDKCommon.DetectType.DETECT_NIR,
                                                                BDFaceSDKCommon.AlignType
                                                                    .BDFACE_ALIGN_TYPE_NIR_ACCURATE,
                                                                nirInstance,
                                                                null,
                                                                bdFaceDetectListConf);
                                                    bdFaceDetectListConf.usingDetect = false;
                                                    livenessModel.setIrLivenessDuration(
                                                        System.currentTimeMillis() - startIrDetectTime);
                                                    //                    LogUtils.e(TIME_TAG, "detect ir time = " + livenessModel.getIrLivenessDuration());
                                                    if (faceInfosIr != null && faceInfosIr.length > 0) {
                                                        FaceInfo faceInfoIr = faceInfosIr[0];
                                                        long startNirTime = System.currentTimeMillis();
                                                        boolean nirLiveStatus =
                                                            faceModel
                                                                .getFaceLive()
                                                                .strategySilentLive(
                                                                    BDFaceSDKCommon.LiveType
                                                                        .BDFACE_SILENT_LIVE_TYPE_NIR,
                                                                    nirInstance,
                                                                    faceInfoIr,
                                                                    bdLiveConfig.framesThreshold,
                                                                    bdLiveConfig.nirLiveScore);
                                                        livenessModel.setNIRLiveStatus(nirLiveStatus);
                                                        livenessModel.setIrLivenessDuration(
                                                            System.currentTimeMillis() - startNirTime);
                                                    if (faceDetectCallBack != null) {
                                                        faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                                    }
                                                    nirInstance.destory();
                                                    return;
                                                }
                                                // TODO depth活体检测
                                                if (depthBDFaceImageConfig != null) {
                                                    fastFaceInfos[0].landmarks = faceInfos[0].landmarks;
                                                    // TODO: 用户调整旋转角度和是否镜像,适配Atlas 镜头,目前宽和高400*640,其他摄像头需要动态调整,人脸72 个关键点x 坐标向左移动80个像素点
                                                    float[] depthLandmark = new float[faceInfos[0].landmarks.length];
                                                    BDFaceImageInstance depthInstance;
                                                    if (bdFaceCheckConfig.cameraType == 1) {
                                                        System.arraycopy(
                                                            faceInfos[0].landmarks,
                                                            0,
                                                            depthLandmark,
                                                            0,
                                                            faceInfos[0].landmarks.length);
                                                        for (int i = 0; i < 144; i = i + 2) {
                                                            depthLandmark[i] -= 80;
                                                        }
                                                        fastFaceInfos[0].landmarks = depthLandmark;
                                                // 最优人脸控制
                                                if (!onBestImageCheck(livenessModel, bdFaceCheckConfig, faceDetectCallBack)) {
                                                    livenessModel.setQualityCheck(true);
                                                    if (faceDetectCallBack != null) {
                                                        faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                                    }
                                                    depthInstance = getBdImage(depthBDFaceImageConfig, false);
                                                    livenessModel.setBdDepthFaceImageInstance(depthInstance.getImage());
                                                    // 创建检测对象,如果原始数据Depth
                                                    long startDepthTime = System.currentTimeMillis();
                                                    boolean depthLiveStatus =
                                                        faceModel
                                                            .getFaceLive()
                                                            .strategySilentLive(
                                                                BDFaceSDKCommon.LiveType.BDFACE_SILENT_LIVE_TYPE_DEPTH,
                                                                depthInstance,
                                                                fastFaceInfos[0],
                                                                bdLiveConfig.framesThreshold,
                                                                bdLiveConfig.nirLiveScore);
                                                    livenessModel.setDepthLiveStatus(depthLiveStatus);
                                                    livenessModel.setDepthtLivenessDuration(
                                                        System.currentTimeMillis() - startDepthTime);
                                                    depthInstance.destory();
                                                    return;
                                                }
                                                // 流程结束,记录最终时间
                                                livenessModel.setAllDetectDuration(
                                                    System.currentTimeMillis() - startTime);
                                                //                LogUtils.e(TIME_TAG, "all process time = " + livenessModel.getAllDetectDuration());
                                                // 流程结束销毁图片,开始下一帧图片检测,否着内存泄露
                                                onQualityCheck(
                                                        faceInfos,
                                                        bdFaceCheckConfig.bdQualityConfig,
                                                        faceDetectCallBack,
                                                        new QualityListener() {
                                                            @Override
                                                            public void onQualitySuccess() {
                                                                livenessModel.setQualityCheck(false);
                                                                // 获取LivenessConfig liveCheckMode 配置选项:【不使用活体:0】;【RGB活体:1】;【RGB+NIR活体:2】;【RGB+Depth活体:3】;【RGB+NIR+Depth活体:4】
                                                                // TODO 活体检测
                                                                BDLiveConfig bdLiveConfig = bdFaceCheckConfig.bdLiveConfig;
                                                                boolean isLiveCheck = bdFaceCheckConfig.bdLiveConfig != null;
                                                                if (isLiveCheck) {
                                                                    long startRgbTime = System.currentTimeMillis();
                                                                    boolean rgbLiveStatus =
                                                                            faceModel
                                                                                    .getFaceLive()
                                                                                    .strategySilentLive(
                                                                                            BDFaceSDKCommon.LiveType.BDFACE_SILENT_LIVE_TYPE_RGB,
                                                                                            rgbInstance,
                                                                                            faceInfos[0],
                                                                                            bdLiveConfig.framesThreshold,
                                                                                            bdLiveConfig.rgbLiveScore);
                                                                    livenessModel.setRGBLiveStatus(rgbLiveStatus);
                                                                    livenessModel.setRgbLivenessDuration(
                                                                            System.currentTimeMillis() - startRgbTime);
                                                                }
                                                                // TODO nir活体检测
                                                                BDFaceImageInstance nirInstance = null;
                                                                boolean isHaveNirImage = nirBDFaceImageConfig != null && isLiveCheck;
                                                                if (isHaveNirImage) {
                                                // 显示最终结果提示
                                                if (faceDetectCallBack != null) {
                                                    faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                                }
                                                                    // 创建检测对象,如果原始数据YUV-IR,转为算法检测的图片BGR
                                                                    // TODO: 用户调整旋转角度和是否镜像,手机和开发版需要动态适配
                                                                    nirInstance = getBdImage(nirBDFaceImageConfig, false);
                                                                    livenessModel.setBdNirFaceImageInstance(nirInstance.getImage());
                                                                    // 避免RGB检测关键点在IR对齐活体稳定,增加红外检测
                                                                    long startIrDetectTime = System.currentTimeMillis();
                                                                    BDFaceDetectListConf bdFaceDetectListConf =
                                                                            new BDFaceDetectListConf();
                                                                    bdFaceDetectListConf.usingDetect = true;
                                                                    FaceInfo[] faceInfosIr =
                                                                            faceModel
                                                                                    .getFaceNirDetect()
                                                                                    .detect(
                                                                                            BDFaceSDKCommon.DetectType.DETECT_NIR,
                                                                                            BDFaceSDKCommon.AlignType
                                                                                                    .BDFACE_ALIGN_TYPE_NIR_ACCURATE,
                                                                                            nirInstance,
                                                                                            null,
                                                                                            bdFaceDetectListConf);
                                                                    bdFaceDetectListConf.usingDetect = false;
                                                                    livenessModel.setIrLivenessDuration(
                                                                            System.currentTimeMillis() - startIrDetectTime);
                                                                    //                    LogUtils.e(TIME_TAG, "detect ir time = " + livenessModel.getIrLivenessDuration());
                                                                    if (faceInfosIr != null && faceInfosIr.length > 0) {
                                                                        FaceInfo faceInfoIr = faceInfosIr[0];
                                                                        long startNirTime = System.currentTimeMillis();
                                                                        boolean nirLiveStatus =
                                                                                faceModel
                                                                                        .getFaceLive()
                                                                                        .strategySilentLive(
                                                                                                BDFaceSDKCommon.LiveType
                                                                                                        .BDFACE_SILENT_LIVE_TYPE_NIR,
                                                                                                nirInstance,
                                                                                                faceInfoIr,
                                                                                                bdLiveConfig.framesThreshold,
                                                                                                bdLiveConfig.nirLiveScore);
                                                                        livenessModel.setNIRLiveStatus(nirLiveStatus);
                                                                        livenessModel.setIrLivenessDuration(
                                                                                System.currentTimeMillis() - startNirTime);
                                                                    }
                                                                    nirInstance.destory();
                                                                }
                                                                // TODO depth活体检测
                                                                if (depthBDFaceImageConfig != null) {
                                                                    fastFaceInfos[0].landmarks = faceInfos[0].landmarks;
                                                                    // TODO: 用户调整旋转角度和是否镜像,适配Atlas 镜头,目前宽和高400*640,其他摄像头需要动态调整,人脸72 个关键点x 坐标向左移动80个像素点
                                                                    float[] depthLandmark = new float[faceInfos[0].landmarks.length];
                                                                    BDFaceImageInstance depthInstance;
                                                                    if (bdFaceCheckConfig.cameraType == 1) {
                                                                        System.arraycopy(
                                                                                faceInfos[0].landmarks,
                                                                                0,
                                                                                depthLandmark,
                                                                                0,
                                                                                faceInfos[0].landmarks.length);
                                                                        for (int i = 0; i < 144; i = i + 2) {
                                                                            depthLandmark[i] -= 80;
                                                                        }
                                                                        fastFaceInfos[0].landmarks = depthLandmark;
                                                                    }
                                                                    depthInstance = getBdImage(depthBDFaceImageConfig, false);
                                                                    livenessModel.setBdDepthFaceImageInstance(depthInstance.getImage());
                                                                    // 创建检测对象,如果原始数据Depth
                                                                    long startDepthTime = System.currentTimeMillis();
                                                                    boolean depthLiveStatus =
                                                                            faceModel
                                                                                    .getFaceLive()
                                                                                    .strategySilentLive(
                                                                                            BDFaceSDKCommon.LiveType.BDFACE_SILENT_LIVE_TYPE_DEPTH,
                                                                                            depthInstance,
                                                                                            fastFaceInfos[0],
                                                                                            bdLiveConfig.framesThreshold,
                                                                                            bdLiveConfig.nirLiveScore);
                                                                    livenessModel.setDepthLiveStatus(depthLiveStatus);
                                                                    livenessModel.setDepthtLivenessDuration(
                                                                            System.currentTimeMillis() - startDepthTime);
                                                                    depthInstance.destory();
                                                                }
                                                                // 流程结束,记录最终时间
                                                                livenessModel.setAllDetectDuration(
                                                                        System.currentTimeMillis() - startTime);
                                                                //                LogUtils.e(TIME_TAG, "all process time = " + livenessModel.getAllDetectDuration());
                                                                // 流程结束销毁图片,开始下一帧图片检测,否着内存泄露
                                                                // 显示最终结果提示
                                                                if (faceDetectCallBack != null) {
                                                                    faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                                                }
                                                            }
                                                            @Override
                                                            public void onQualityFail(String detectFail, String occlusionFail) {
                                                                livenessModel.setQualityOcclusion(occlusionFail);
                                                                livenessModel.setQualityDetect(detectFail);
                                                                livenessModel.setQualityCheck(true);
                                                                if (faceDetectCallBack != null) {
                                                                    faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                                                }
                                                            }
                                                        });
                                            }catch (RuntimeException e){
                                                faceDetectCallBack.onTip(1,e.getMessage());
                                            }catch (Exception e){
                                                faceDetectCallBack.onTip(1,e.getMessage());
                                            }
                                        }
                                            @Override
                                            public void onQualityFail(String detectFail, String occlusionFail) {
                                                livenessModel.setQualityOcclusion(occlusionFail);
                                                livenessModel.setQualityDetect(detectFail);
                                                livenessModel.setQualityCheck(true);
                                        @Override
                                        public void onDetectFail() {
                                                if (faceDetectCallBack != null) {
                                                    faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                                }
                                            if (faceDetectCallBack != null) {
                                                faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                            }
                                        });
                                }
                                @Override
                                public void onDetectFail() {
                                    if (faceDetectCallBack != null) {
                                        faceDetectCallBack.onFaceDetectCallback(livenessModel);
                                    }
                                }
                            });
                                        }
                                    });
                        }catch (RuntimeException e){
                            faceDetectCallBack.onTip(1,e.getMessage());
                        }catch (Exception e){
                            faceDetectCallBack.onTip(1,e.getMessage());
                        }
                    }
                });
    }