From 3a154bdb0a5aaa2c0ac3eac95a6ba747068bd454 Mon Sep 17 00:00:00 2001
From: MrShi <1878285526@qq.com>
Date: 星期二, 13 一月 2026 10:00:37 +0800
Subject: [PATCH] 优化
---
keyCabinet-android/datalibrary/src/main/java/com/example/datalibrary/manager/FaceSDKManager.java | 1994 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 1,994 insertions(+), 0 deletions(-)
diff --git a/keyCabinet-android/datalibrary/src/main/java/com/example/datalibrary/manager/FaceSDKManager.java b/keyCabinet-android/datalibrary/src/main/java/com/example/datalibrary/manager/FaceSDKManager.java
new file mode 100644
index 0000000..fe9db72
--- /dev/null
+++ b/keyCabinet-android/datalibrary/src/main/java/com/example/datalibrary/manager/FaceSDKManager.java
@@ -0,0 +1,1994 @@
+package com.example.datalibrary.manager;
+
+import static com.example.datalibrary.model.GlobalSet.FEATURE_SIZE;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.os.Debug;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.baidu.idl.main.facesdk.FaceAuth;
+import com.baidu.idl.main.facesdk.FaceCrop;
+import com.baidu.idl.main.facesdk.FaceDetect;
+import com.baidu.idl.main.facesdk.FaceFeature;
+import com.baidu.idl.main.facesdk.FaceInfo;
+import com.baidu.idl.main.facesdk.FaceMouthMask;
+import com.baidu.idl.main.facesdk.ImageIllum;
+import com.baidu.idl.main.facesdk.model.BDFaceDetectListConf;
+import com.baidu.idl.main.facesdk.model.BDFaceImageInstance;
+import com.baidu.idl.main.facesdk.model.BDFaceOcclusion;
+import com.baidu.idl.main.facesdk.model.BDFaceSDKCommon;
+import com.baidu.idl.main.facesdk.model.BDFaceSDKConfig;
+import com.baidu.idl.main.facesdk.model.Feature;
+import com.example.datalibrary.api.FaceApi;
+import com.example.datalibrary.callback.FaceDetectCallBack;
+import com.example.datalibrary.callback.FaceQualityBack;
+import com.example.datalibrary.db.DBManager;
+import com.example.datalibrary.listener.DetectListener;
+import com.example.datalibrary.listener.QualityListener;
+import com.example.datalibrary.listener.SdkInitListener;
+import com.example.datalibrary.model.BDFaceCheckConfig;
+import com.example.datalibrary.model.BDFaceImageConfig;
+import com.example.datalibrary.model.BDLiveConfig;
+import com.example.datalibrary.model.BDQualityConfig;
+import com.example.datalibrary.model.LivenessModel;
+import com.example.datalibrary.model.User;
+import com.example.datalibrary.utils.ToastUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class FaceSDKManager {
+
+ public static final int SDK_MODEL_LOAD_SUCCESS = 0;
+ public static final int SDK_UNACTIVATION = 1;
+ private static final String TAG = "FaceSDKManager";
+
+ private List<Boolean> mRgbLiveList = new ArrayList<>();
+ private List<Boolean> mNirLiveList = new ArrayList<>();
+ private int mLastFaceId;
+
+ private float threholdScore;
+
+ public static volatile int initStatus = SDK_UNACTIVATION;
+ public static volatile boolean initModelSuccess = false;
+ private FaceAuth faceAuth;
+
+ private ExecutorService es = Executors.newSingleThreadExecutor();
+ private Future future;
+ private ExecutorService es2 = Executors.newSingleThreadExecutor();
+ private Future future2;
+ private ExecutorService es3 = Executors.newSingleThreadExecutor();
+ private Future future3;
+
+ private float[] scores;
+ private ImageIllum imageIllum;
+ private long startInitModelTime;
+
+ private static int failNumber = 0;
+ private static int faceId = 0;
+ private static int lastFaceId = 0;
+ private static LivenessModel faceAdoptModel;
+ private boolean isFail = false;
+ private long trackTime;
+ private FaceModel faceModel;
+
+ private boolean checkMouthMask = false;
+ private boolean isMultiIdentify = false;
+
+ private FaceSDKManager() {
+ faceAuth = new FaceAuth();
+ faceAuth.setCoreConfigure(BDFaceSDKCommon.BDFaceCoreRunMode.BDFACE_LITE_POWER_NO_BIND, 2);
+ }
+
+ public void setActiveLog(boolean isLog) {
+ if (faceAuth != null) {
+ if (isLog) {
+ faceAuth.setActiveLog(BDFaceSDKCommon.BDFaceLogInfo.BDFACE_LOG_TYPE_ALL, 1);
+ } else {
+ faceAuth.setActiveLog(BDFaceSDKCommon.BDFaceLogInfo.BDFACE_LOG_TYPE_ALL, 0);
+ }
+ }
+ }
+
+ public void setCheckMouthMask(boolean checkMouthMask) {
+ this.checkMouthMask = checkMouthMask;
+ }
+
+ public void setMultiIdentify(boolean isMultiFaceIdentify) {
+ this.isMultiIdentify = isMultiFaceIdentify;
+ }
+
+ private static class HolderClass {
+ private static final FaceSDKManager INSTANCE = new FaceSDKManager();
+ }
+
+ public static FaceSDKManager getInstance() {
+ return HolderClass.INSTANCE;
+ }
+
+ public ImageIllum getImageIllum() {
+ return imageIllum;
+ }
+
+ public void initModel(
+ final Context context, BDFaceSDKConfig config, boolean isLog, final SdkInitListener listener) {
+ setActiveLog(isLog);
+ initModel(context, config, listener);
+ }
+
+ /**
+ * 鍒濆鍖栨ā鍨嬶紝鐩墠鍖呭惈妫�鏌ワ紝娲讳綋锛岃瘑鍒ā鍨嬶紱鍥犱负鍒濆鍖栨槸椤哄簭鎵ц锛屽彲浠ュ湪鏈�濂藉垵濮嬪寲鍥炴帀涓繑鍥炵姸鎬佺粨鏋�
+ *
+ * @param context
+ */
+ public void initModel(final Context context, BDFaceSDKConfig config, final SdkInitListener listener) {
+ // 鏇濆厜
+ if (imageIllum == null) {
+ imageIllum = new ImageIllum();
+ }
+ // 鍏朵粬妯″瀷鍒濆鍖�
+ if (faceModel == null) {
+ faceModel = new FaceModel(checkMouthMask);
+ }
+ faceModel.setListener(listener);
+
+ faceModel.init(config, context);
+
+ startInitModelTime = System.currentTimeMillis();
+ }
+
+ public void destroy(){
+ if(rgbInstance!=null){
+ rgbInstance = null;
+ }
+ }
+
+ public FaceCrop getFaceCrop() {
+ return faceModel.getFaceCrop();
+ }
+
+ public FaceDetect getFaceDetectPerson() {
+ return faceModel.getFaceDetectPerson();
+ }
+
+ public FaceFeature getFacePersonFeature() {
+ return faceModel.getFacePersonFeature();
+ }
+
+ public FaceMouthMask getFaceMouthMask() {
+ return faceModel.getFaceMoutMask();
+ }
+
+ public void initDataBases(Context context) {
+ if (FaceApi.getInstance().getmUserNum() != 0) {
+ //ToastUtils.toast(context, "浜鸿劯搴撳姞杞戒腑");
+ }
+ emptyFrame();
+ // 鍒濆鍖栨暟鎹簱
+ DBManager.getInstance().init(context);
+ // 鏁版嵁鍙樺寲锛屾洿鏂板唴瀛�
+ initPush(context);
+ }
+
+ /**
+ * 鏁版嵁搴撳彂鐜板彉鍖栨椂鍊欙紝閲嶆柊鎶婃暟鎹簱涓殑浜鸿劯淇℃伅娣诲姞鍒板唴瀛樹腑锛宨d+feature
+ */
+ public void initPush(final Context context) {
+
+ if (future3 != null && !future3.isDone()) {
+ future3.cancel(true);
+ }
+
+ future3 =
+ es3.submit(
+ new Runnable() {
+ @Override
+ public void run() {
+ faceModel.getFaceSearch().featureClear();
+ synchronized (faceModel.getFaceSearch()) {
+ List<User> users = FaceApi.getInstance().getAllUserList();
+ for (int i = 0; i < users.size(); i++) {
+ User user = users.get(i);
+ faceModel.getFaceSearch().pushPersonById(user.getId(), user.getFeature());
+ }
+ if (FaceApi.getInstance().getmUserNum() != 0) {
+ //ToastUtils.toast(context, "浜鸿劯搴撳姞杞芥垚鍔�");
+ }
+ }
+ }
+ });
+ }
+
+ private void setFail(LivenessModel livenessModel) {
+ Log.e("faceId", livenessModel.getFaceInfo().faceID + "");
+ if (failNumber >= 2) {
+ faceId = livenessModel.getFaceInfo().faceID;
+ faceAdoptModel = livenessModel;
+ trackTime = System.currentTimeMillis();
+ isFail = false;
+ faceAdoptModel.setMultiFrame(true);
+ } else {
+ failNumber += 1;
+ faceId = 0;
+ faceAdoptModel = null;
+ isFail = true;
+ livenessModel.setMultiFrame(true);
+ }
+ }
+
+ public void emptyFrame() {
+ failNumber = 0;
+ faceId = 0;
+ isFail = false;
+ trackTime = 0;
+ faceAdoptModel = null;
+ }
+
+ private FaceInfo[] getTrackCheck(BDFaceImageInstance rgbInstance) {
+
+ // 蹇�熸娴嬭幏鍙栦汉鑴镐俊鎭紝浠呯敤浜庣粯鍒朵汉鑴告锛岃缁嗕汉鑴告暟鎹悗缁幏鍙�
+ FaceInfo[] faceInfos =
+ faceModel
+ .getFaceTrack()
+ .track(
+ BDFaceSDKCommon.DetectType.DETECT_VIS,
+ BDFaceSDKCommon.AlignType.BDFACE_ALIGN_TYPE_RGB_FAST,
+ rgbInstance);
+ return faceInfos;
+ }
+
+
+ private FaceInfo[] getDetectCheck(BDFaceImageInstance rgbInstance) {
+
+ // 蹇�熸娴嬭幏鍙栦汉鑴镐俊鎭紝浠呯敤浜庣粯鍒朵汉鑴告锛岃缁嗕汉鑴告暟鎹悗缁幏鍙�
+ FaceInfo[] faceInfos = faceModel.getFaceDetect().detect(BDFaceSDKCommon.DetectType.DETECT_VIS, rgbInstance);
+ return faceInfos;
+ }
+
+ private BDFaceImageInstance getBdImage(BDFaceImageConfig bdFaceImageConfig, boolean darkEnhance) {
+ BDFaceImageInstance rgbInstance =
+ new BDFaceImageInstance(
+ bdFaceImageConfig.data,
+ bdFaceImageConfig.srcHeight,
+ bdFaceImageConfig.srcWidth,
+ bdFaceImageConfig.bdFaceImageType,
+ bdFaceImageConfig.direction,
+ bdFaceImageConfig.mirror);
+ BDFaceImageInstance rgbInstanceOne;
+ // 鍒ゆ柇鏆楀厜鎭㈠
+ if (darkEnhance) {
+ rgbInstanceOne = faceModel.getDark().faceDarkEnhance(rgbInstance);
+
+ } else {
+ rgbInstanceOne = rgbInstance;
+ }
+ return rgbInstanceOne;
+ }
+
+ private boolean frameSelect(FaceInfo faceInfo) {
+ if (lastFaceId != faceInfo.faceID) {
+ lastFaceId = faceInfo.faceID;
+ }
+
+ if (System.currentTimeMillis() - trackTime < 0 && faceId == faceInfo.faceID) {
+ faceAdoptModel.setMultiFrame(true);
+
+ return false;
+ }
+ if (faceAdoptModel != null) {
+ faceAdoptModel.setMultiFrame(false);
+ }
+ faceId = 0;
+ faceAdoptModel = null;
+ if (!isFail /*&& failNumber != 0*/) {
+ failNumber = 0;
+ }
+ return true;
+ }
+
+ public BDFaceImageInstance getCopeFace(Bitmap bitmap, float[] landmarks, int initialValue) {
+ if (faceModel == null || faceModel.getFaceCrop() == null) {
+ return null;
+ }
+ BDFaceImageInstance imageInstance = new BDFaceImageInstance(bitmap);
+ if (!bitmap.isRecycled()) {
+ bitmap.recycle();
+ }
+ AtomicInteger isOutoBoundary = new AtomicInteger();
+ BDFaceImageInstance cropInstance =
+ faceModel.getFaceCrop().cropFaceByLandmark(imageInstance, landmarks, 2.0f, false, isOutoBoundary);
+ return cropInstance;
+ }
+
+ private static BDFaceImageInstance rgbInstance =null;
+ private LivenessModel livenessModel;
+ private String groupId;
+
+ /**
+ * 0:绠$悊鍛橈紝1锛氱敤鎴�
+ * @param groupId
+ */
+ public void setGroupId(String groupId){
+ this.groupId = groupId;
+ }
+ /**
+ * 妫�娴�-娲讳綋-鐗瑰緛-浜鸿劯妫�绱㈡祦绋�
+ *
+ * @param bdFaceImageConfig 鍙鍏塝UV 鏁版嵁娴�
+ * @param bdNirFaceImageConfig 绾㈠YUV 鏁版嵁娴�
+ * @param bdDepthFaceImageConfig 娣卞害depth 鏁版嵁娴�
+ * @param bdFaceCheckConfig 璇嗗埆鍙傛暟
+ * @param faceDetectCallBack
+ */
+ public void onDetectCheck(
+ final BDFaceImageConfig bdFaceImageConfig,
+ final BDFaceImageConfig bdNirFaceImageConfig,
+ final BDFaceImageConfig bdDepthFaceImageConfig,
+ final BDFaceCheckConfig bdFaceCheckConfig,
+ final FaceDetectCallBack faceDetectCallBack) {
+ if (!FaceSDKManager.initModelSuccess) {
+ return;
+ }
+ long startTime = System.currentTimeMillis();
+ // 鍒涘缓妫�娴嬬粨鏋滃瓨鍌ㄦ暟鎹�
+ livenessModel = new LivenessModel();
+ // 鍒涘缓妫�娴嬪璞★紝濡傛灉鍘熷鏁版嵁YUV锛岃浆涓虹畻娉曟娴嬬殑鍥剧墖BGR
+ // TODO: 鐢ㄦ埛璋冩暣鏃嬭浆瑙掑害鍜屾槸鍚﹂暅鍍忥紝鎵嬫満鍜屽紑鍙戠増闇�瑕佸姩鎬侀�傞厤
+ //System.out.println("==rgbInstance==>鍒濆鍖�");
+ if(rgbInstance!=null){
+ rgbInstance.destory();
+ }
+ rgbInstance = getBdImage(bdFaceImageConfig, bdFaceCheckConfig.darkEnhance);
+ livenessModel.setTestBDFaceImageInstanceDuration(System.currentTimeMillis() - startTime);
+ onTrack(
+ rgbInstance,
+ livenessModel,
+ new DetectListener() {
+ @Override
+ public void onDetectSuccess(FaceInfo[] faceInfos, BDFaceImageInstance rgbInstance) {
+ // 澶氬抚鍒ゆ柇
+ if (!frameSelect(faceInfos[0])) {
+ livenessModel.setBdFaceImageInstance(rgbInstance.getImage());
+ if (faceDetectCallBack != null && faceAdoptModel != null) {
+ //System.out.println("==isOk==>澶氬抚鍒ゆ柇");
+ faceDetectCallBack.onFaceDetectDarwCallback(livenessModel);
+ faceDetectCallBack.onFaceDetectCallback(faceAdoptModel);
+ }
+
+ return;
+ }
+ // 淇濆瓨浜鸿劯鐗瑰緛鐐�
+ livenessModel.setLandmarks(faceInfos[0].landmarks);
+ // 淇濆瓨浜鸿劯鍥剧墖
+ livenessModel.setBdFaceImageInstance(rgbInstance.getImage());
+ // 鍙g僵妫�娴嬫暟鎹�
+ if (checkMouthMask) {
+ FaceMouthMask mouthMask = getFaceMouthMask();
+ if (mouthMask != null) {
+ float[] maskScores = mouthMask.checkMask(rgbInstance, faceInfos);
+ if (maskScores != null && maskScores.length > 0) {
+ float maskResult = maskScores[0];
+ Log.d("mouth_mask", "mask_score:" + maskResult);
+ if (livenessModel != null) {
+ livenessModel.setMouthMaskArray(maskScores);
+ }
+ }
+ }
+ }
+
+ // 璋冪敤缁樺埗浜鸿劯妗嗘帴鍙�
+ if (faceDetectCallBack != null) {
+ faceDetectCallBack.onFaceDetectDarwCallback(livenessModel);
+ }
+
+ // 閫佹璇嗗埆
+ onLivenessCheck(
+ rgbInstance,
+ bdNirFaceImageConfig,
+ bdDepthFaceImageConfig,
+ bdFaceCheckConfig,
+ livenessModel,
+ startTime,
+ faceDetectCallBack,
+ faceInfos);
+ }
+
+ @Override
+ public void onDetectFail() {
+
+ emptyFrame();
+ // 娴佺▼缁撴潫閿�姣佸浘鐗囷紝寮�濮嬩笅涓�甯у浘鐗囨娴嬶紝鍚︾潃鍐呭瓨娉勯湶
+ if (faceDetectCallBack != null) {
+ faceDetectCallBack.onFaceDetectCallback(null);
+ livenessModel.setBdFaceImageInstance(rgbInstance.getImage());
+ //System.out.println("==isOk==>娴佺▼缁撴潫");
+// SaveImageManager.getInstance().saveImage(livenessModel, bdFaceCheckConfig.bdLiveConfig);
+ faceDetectCallBack.onFaceDetectDarwCallback(livenessModel);
+ faceDetectCallBack.onTip(0, "鏈娴嬪埌浜鸿劯");
+ }
+ }
+ });
+ }
+
+ private float silentLive(
+ BDFaceImageInstance rgbInstance,
+ BDFaceSDKCommon.LiveType type,
+ float[] landmarks,
+ List<Boolean> list,
+ float liveScore) {
+ float score = 0;
+ if (landmarks != null) {
+ synchronized (faceModel.getFaceLive()) {
+ Log.e("test_camera", rgbInstance.getImage().data.length + "寮�濮�");
+ score = faceModel.getFaceLive().silentLive(type, rgbInstance, landmarks, liveScore);
+ Log.e("test_camera", "娲讳綋缁撴潫");
+ }
+ list.add(score > liveScore);
+ }
+ while (list.size() > 6) {
+ list.remove(0);
+ }
+ if (list.size() > 2) {
+ int rgbSum = 0;
+ for (Boolean b : list) {
+ if (b) {
+ rgbSum++;
+ }
+ }
+ if (1.0 * rgbSum / list.size() > 0.6) {
+ if (score < liveScore) {
+ score = liveScore + (1 - liveScore) * new Random().nextFloat();
+ }
+ } else {
+ if (score > liveScore) {
+ score = new Random().nextFloat() * liveScore;
+ }
+ }
+ }
+ return score;
+ }
+
+ /**
+ * 娲讳綋妫�娴�
+ * @param rgbInstance
+ * @param type
+ * @param faceInfos
+ * @param list
+ * @param liveScore
+ * @return
+ */
+ private float[] silentLives(
+ BDFaceImageInstance rgbInstance,
+ BDFaceSDKCommon.LiveType type,
+ FaceInfo[] faceInfos,
+ List<Boolean> list,
+ float liveScore) {
+ float[] scores = {0, 0, 0}; // 鏈�澶氭娴�3涓汉鑴�
+ if (faceInfos != null) {
+ synchronized (faceModel.getFaceLive()) {
+ Log.e("test_camera", rgbInstance.getImage().data.length + "寮�濮�");
+ int size = faceInfos.length;
+
+ for (int i = 0; i < size; i++) {
+ scores[i] =
+ faceModel.getFaceLive().silentLive(type, rgbInstance, faceInfos[i].landmarks, liveScore);
+ }
+ }
+ }
+ return scores;
+ }
+
+ private void onDetect(
+ BDFaceCheckConfig bdFaceCheckConfig,
+ BDFaceImageInstance rgbInstance,
+ FaceInfo[] fastFaceInfos,
+ LivenessModel livenessModel,
+ DetectListener detectListener) {
+
+ long accurateTime = System.currentTimeMillis();
+ FaceInfo[] faceInfos;
+
+ if (bdFaceCheckConfig != null) {
+ bdFaceCheckConfig.bdFaceDetectListConfig.usingQuality = true;
+ faceInfos =
+ faceModel
+ .getFaceDetect()
+ .detect(
+ BDFaceSDKCommon.DetectType.DETECT_VIS,
+ BDFaceSDKCommon.AlignType.BDFACE_ALIGN_TYPE_RGB_ACCURATE,
+ rgbInstance,
+ fastFaceInfos,
+ bdFaceCheckConfig.bdFaceDetectListConfig);
+
+ } else {
+ faceInfos = faceModel.getFaceDetect().detect(BDFaceSDKCommon.DetectType.DETECT_VIS, rgbInstance);
+ }
+
+ livenessModel.setAccurateTime(System.currentTimeMillis() - accurateTime);
+
+ if (faceInfos == null || faceInfos.length <= 0) {
+
+ detectListener.onDetectFail();
+ return;
+ }
+
+ // 閲嶆柊璧嬩簣璇︾粏浜鸿劯淇℃伅
+ if (livenessModel.getFaceInfo() != null) {
+ faceInfos[0].faceID = livenessModel.getFaceInfo().faceID;
+ }
+
+ livenessModel.setFaceInfos(faceInfos);
+ livenessModel.setFaceInfo(faceInfos[0]);
+ livenessModel.setTrackStatus(2);
+ // 淇濆瓨浜鸿劯鍏抽敭鐐�
+ livenessModel.setLandmarks(faceInfos[0].landmarks);
+ detectListener.onDetectSuccess(faceInfos, rgbInstance);
+ }
+
+ /**
+ * 娲讳綋-鐗瑰緛-浜鸿劯妫�绱㈠叏娴佺▼
+ *
+ * @param rgbInstance 鍙鍏夊簳灞傞�佹瀵硅薄
+ * @param nirBDFaceImageConfig 绾㈠YUV 鏁版嵁娴�
+ * @param depthBDFaceImageConfig 娣卞害depth 鏁版嵁娴�
+ * @param livenessModel 妫�娴嬬粨鏋滄暟鎹泦鍚�
+ * @param startTime 寮�濮嬫娴嬫椂闂�
+ * @param faceDetectCallBack
+ */
+ public void onLivenessCheck(
+ final BDFaceImageInstance rgbInstance,
+ final BDFaceImageConfig nirBDFaceImageConfig,
+ final BDFaceImageConfig depthBDFaceImageConfig,
+ final BDFaceCheckConfig bdFaceCheckConfig,
+ final LivenessModel livenessModel,
+ final long startTime,
+ final FaceDetectCallBack faceDetectCallBack,
+ final FaceInfo[] fastFaceInfos) {
+ if (future2 != null && !future2.isDone()) {
+ // 娴佺▼缁撴潫閿�姣佸浘鐗囷紝寮�濮嬩笅涓�甯у浘鐗囨娴嬶紝鍚︾潃鍐呭瓨娉勯湶
+ //future2.cancel(true);
+
+ //System.out.println("==isOk==>涔嬪墠娌$粨鏉�");
+ return;
+ }
+
+ future2 =
+ es2.submit(
+ new Runnable() {
+
+ @Override
+ public void run() {
+
+ // 鑾峰彇BDFaceCheckConfig閰嶇疆淇℃伅
+ if (bdFaceCheckConfig == null) {
+
+ return;
+ }
+ 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) {
+
+ livenessModel.clearIdentifyResults();
+ if (faceDetectCallBack != null) {
+ faceDetectCallBack.onFaceDetectCallback(livenessModel);
+ }
+ return;
+ }
+
+ // 鏈�浼樹汉鑴告帶鍒�
+ if (!onBestImageCheck(livenessModel, bdFaceCheckConfig, faceDetectCallBack)) {
+ livenessModel.setQualityCheck(true);
+ livenessModel.clearIdentifyResults();
+
+ if (faceDetectCallBack != null) {
+ faceDetectCallBack.onFaceDetectCallback(livenessModel);
+ }
+ return;
+ }
+
+ // 璐ㄩ噺妫�娴嬫湭閫氳繃,閿�姣丅DFaceImageInstance锛岀粨鏉熷嚱鏁�
+
+ if (!onQualityCheck(
+ faceInfos, bdFaceCheckConfig.bdQualityConfig, faceDetectCallBack)) {
+ livenessModel.setQualityCheck(true);
+ livenessModel.clearIdentifyResults();
+
+ if (faceDetectCallBack != null) {
+ faceDetectCallBack.onFaceDetectCallback(livenessModel);
+ }
+ return;
+ }
+
+ livenessModel.setQualityCheck(false);
+ // 鑾峰彇LivenessConfig liveCheckMode 閰嶇疆閫夐」锛氥�愪笉浣跨敤娲讳綋锛�0銆戯紱銆怰GB娲讳綋锛�1銆戯紱銆怰GB+NIR娲讳綋锛�2銆戯紱銆怰GB+Depth娲讳綋锛�3銆戯紱銆怰GB+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 (rgbScores != null){
+ int size = rgbScores.length;
+ Log.d("Attend", "score size:" + size);
+ for (int i = 0; i < size; i++) {
+ Log.d("Attend", "score:" + rgbScores[i]);
+ }
+ } */
+
+ 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妫�娴嬪叧閿偣鍦↖R瀵归綈娲讳綋绋冲畾锛屽鍔犵孩澶栨娴�
+ 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);
+ }
+ }
+
+ @Override
+ public void onDetectFail() {
+
+ if (faceDetectCallBack != null) {
+ faceDetectCallBack.onFaceDetectCallback(livenessModel);
+ }
+ }
+ });
+ }
+ });
+ }
+
+ /**
+ * 鏈�浼樹汉鑴告帶鍒�
+ *
+ * @param livenessModel
+ * @param faceDetectCallBack
+ * @return
+ */
+ public boolean onBestImageCheck(
+ LivenessModel livenessModel, BDFaceCheckConfig bdFaceCheckConfig, FaceDetectCallBack faceDetectCallBack) {
+ boolean isBestImageCheck = false;
+ if (livenessModel != null && livenessModel.getFaceInfos() != null) {
+ FaceInfo[] faceInfos = livenessModel.getFaceInfos();
+ int size = faceInfos.length;
+ for (int i = 0; i < size; i++) {
+ float bestImageScore = faceInfos[i].bestImageScore;
+ if (bestImageScore > 0.5) {
+ isBestImageCheck = true;
+ }
+ }
+ }
+ return isBestImageCheck;
+ }
+
+ /**
+ * 鐗瑰緛鎻愬彇-浜鸿劯璇嗗埆姣斿
+ *
+ * @param rgbInstance 鍙鍏夊簳灞傞�佹瀵硅薄
+ * @param landmark 妫�娴嬬溂鐫涳紝鍢村反锛岄蓟瀛愶紝72涓叧閿偣
+ * @param faceInfos nir浜鸿劯鏁版嵁
+ * @param nirInstance nir 鍥惧儚鍙ユ焺
+ * @param livenessModel 妫�娴嬬粨鏋滄暟鎹泦鍚�
+ * @param featureCheckMode 鐗瑰緛鎶藉彇妯″紡銆愪笉鎻愬彇鐗瑰緛锛�1銆戯紱銆愭彁鍙栫壒寰侊細2銆戯紱銆愭彁鍙栫壒寰�+1锛歂妫�绱細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);
+ }
+ }
+
+ /**
+ * 鐗瑰緛鎻愬彇-浜鸿劯璇嗗埆姣斿
+ *
+ * @param rgbInstance 鍙鍏夊簳灞傞�佹瀵硅薄
+ * @param rgbFaceInfos rgb浜鸿劯鏁版嵁
+ * @param faceInfos nir浜鸿劯鏁版嵁
+ * @param nirInstance nir 鍥惧儚鍙ユ焺
+ * @param livenessModel 妫�娴嬬粨鏋滄暟鎹泦鍚�
+ * @param featureCheckMode 鐗瑰緛鎶藉彇妯″紡銆愪笉鎻愬彇鐗瑰緛锛�1銆戯紱銆愭彁鍙栫壒寰侊細2銆戯紱銆愭彁鍙栫壒寰�+1锛歂妫�绱細3銆戯紱
+ * @param featureType 鐗瑰緛鎶藉彇妯℃�佹墽琛� 銆愮敓娲荤収锛�1銆戯紱銆愯瘉浠剁収锛�2銆戯紱銆愭贩鍚堟ā鎬侊細3銆戯紱
+ * @param rgbScores 鍙鍏夊緱鍒�
+ * @param liveScore 鍙鍏夋椿浣撻槇鍊�
+ */
+ private void onFeatureChecks(
+ int index,
+ BDFaceImageInstance rgbInstance,
+ BDFaceCheckConfig bdFaceCheckConfig,
+ FaceInfo[] rgbFaceInfos,
+ FaceInfo[] faceInfos,
+ BDFaceImageInstance nirInstance,
+ LivenessModel livenessModel,
+ byte[] secondFeature,
+ final int featureCheckMode,
+ final int featureType,
+ float[] rgbScores,
+ float liveScore) {
+ // 濡傛灉涓嶆娊鍙栫壒寰侊紝鐩存帴杩斿洖
+
+ 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;
+
+ if (rgbFaceInfos == null) {
+ return;
+ }
+ int size = faceInfos.length;
+
+ if (rgbFaceInfos[index].landmarks == null) {
+ return;
+ }
+
+ if (rgbScores != null) {
+ float score = rgbScores[index];
+ if (score < liveScore) {
+ return;
+ }
+ }
+
+ float[] landmarks = rgbFaceInfos[index].landmarks;
+
+ long startFeatureTime = System.currentTimeMillis();
+ float featureSize = faceModel.getFaceFeature().feature(type, bdFaceImageInstance, landmarks, feature);
+ livenessModel.setFeatureDuration(System.currentTimeMillis() - startFeatureTime);
+ livenessModel.setFeature(feature);
+ // 浜鸿劯妫�绱�
+ featureSearchs(
+ index,
+ featureCheckMode,
+ livenessModel,
+ bdFaceCheckConfig,
+ feature,
+ secondFeature,
+ featureSize,
+ BDFaceSDKCommon.FeatureType.BDFACE_FEATURE_TYPE_LIVE_PHOTO);
+
+ } else {
+ // 鐢熸椿鐓ф绱�
+ long startFeatureTime = System.currentTimeMillis();
+ if (rgbFaceInfos == null) {
+ return;
+ }
+
+ int size = rgbFaceInfos.length;
+
+ if (rgbFaceInfos[index].landmarks == null) {
+ return;
+ }
+
+ if (rgbScores != null) {
+ float score = rgbScores[index];
+ if (score < liveScore) {
+ return;
+ }
+ }
+
+ float featureSize =
+ faceModel
+ .getFaceFeature()
+ .feature(
+ BDFaceSDKCommon.FeatureType.BDFACE_FEATURE_TYPE_LIVE_PHOTO,
+ rgbInstance,
+ rgbFaceInfos[index].landmarks,
+ feature);
+
+ livenessModel.setFeatureDuration(System.currentTimeMillis() - startFeatureTime);
+ livenessModel.setFeature(feature);
+ livenessModel.setFeatureDuration(System.currentTimeMillis() - startFeatureTime);
+ // 浜鸿劯妫�绱�
+ featureSearchs(
+ index,
+ featureCheckMode,
+ livenessModel,
+ bdFaceCheckConfig,
+ feature,
+ secondFeature,
+ featureSize,
+ BDFaceSDKCommon.FeatureType.BDFACE_FEATURE_TYPE_LIVE_PHOTO);
+ }
+ }
+
+ /**
+ * 浜鸿劯搴撴绱�
+ *
+ * @param featureCheckMode 鐗瑰緛鎶藉彇妯″紡銆愪笉鎻愬彇鐗瑰緛锛�1銆戯紱銆愭彁鍙栫壒寰侊細2銆戯紱銆愭彁鍙栫壒寰�+1锛歂妫�绱細3銆戯紱
+ * @param livenessModel 妫�娴嬬粨鏋滄暟鎹泦鍚�
+ * @param feature 鐗瑰緛鐐�
+ * @param secondFeature 1:1 鐗瑰緛鐐�
+ * @param featureSize 鐗瑰緛鐐圭殑size
+ * @param type 鐗瑰緛鎻愬彇绫诲瀷
+ */
+ private void featureSearch(
+ final int featureCheckMode,
+ LivenessModel livenessModel,
+ BDFaceCheckConfig bdFaceCheckConfig,
+ byte[] feature,
+ byte[] secondFeature,
+ float featureSize,
+ BDFaceSDKCommon.FeatureType type) {
+
+ // 濡傛灉鍙彁鍘荤壒寰侊紝涓嶅仛妫�绱紝姝ゅ杩斿洖
+ if (featureCheckMode == 2) {
+ livenessModel.setFeatureCode(featureSize);
+ return;
+ }
+ // 濡傛灉鎻愬彇鐗瑰緛+妫�绱紝璋冪敤search 鏂规硶
+ if (featureSize == FEATURE_SIZE / 4) {
+ long startFeature = System.currentTimeMillis();
+ // 鐗瑰緛鎻愬彇鎴愬姛
+ // TODO 闃堝�煎彲浠ユ牴鎹笉鍚屾ā鍨嬭皟鏁�
+ if (featureCheckMode == 3) {
+ List<? extends Feature> featureResult =
+ faceModel.getFaceSearch().search(type, bdFaceCheckConfig.scoreThreshold, 1, feature, false);
+
+ // TODO 杩斿洖top num = 1 涓暟鎹泦鍚堬紝姝ゅ鍙互浠绘剰璁剧疆锛屼細杩斿洖姣斿浠庡ぇ鍒板皬鎺掑簭鐨刵um 涓暟鎹泦鍚�
+ if (featureResult != null && featureResult.size() > 0) {
+
+ // 鑾峰彇绗竴涓暟鎹�
+ Feature topFeature = featureResult.get(0);
+ // 鍒ゆ柇绗竴涓槇鍊兼槸鍚﹀ぇ浜庤瀹氶槇鍊硷紝濡傛灉澶т簬锛屾绱㈡垚鍔�
+ threholdScore = bdFaceCheckConfig.scoreThreshold;
+ if (topFeature != null && topFeature.getScore() > threholdScore) {
+ // 褰撳墠featureEntity 鍙湁id+feature 绱㈠紩锛屽湪鏁版嵁搴撲腑鏌ュ埌瀹屾暣淇℃伅
+ User user = FaceApi.getInstance().getUserListById(topFeature.getId());
+ if (user != null) {
+ livenessModel.setUser(user);
+ livenessModel.setFeatureScore(topFeature.getScore());
+ /*faceId = livenessModel.getFaceInfo().faceID;
+ trackTime = System.currentTimeMillis();
+ faceAdoptModel = livenessModel;
+ failNumber = 0;
+ isFail = false;*/
+ setFail(livenessModel);
+ } else {
+ setFail(livenessModel);
+ }
+ } else {
+ setFail(livenessModel);
+ }
+ } else {
+ setFail(livenessModel);
+ }
+ } else if (featureCheckMode == 4) {
+ // 鐩墠浠呮敮鎸�
+ float score =
+ faceModel
+ .getFaceSearch()
+ .compare(
+ BDFaceSDKCommon.FeatureType.BDFACE_FEATURE_TYPE_ID_PHOTO,
+ livenessModel.getFeature(),
+ secondFeature,
+ true);
+ livenessModel.setScore(score);
+ if (score > threholdScore) {
+ /*faceId = livenessModel.getFaceInfo().faceID;
+ trackTime = System.currentTimeMillis();
+ faceAdoptModel = livenessModel;
+ failNumber = 0;
+ isFail = false;*/
+ setFail(livenessModel);
+ } else {
+ setFail(livenessModel);
+ }
+ }
+ livenessModel.setCheckDuration(System.currentTimeMillis() - startFeature);
+ }
+ }
+
+ /**
+ * 浜鸿劯搴撴绱�
+ *
+ * @param featureCheckMode 鐗瑰緛鎶藉彇妯″紡銆愪笉鎻愬彇鐗瑰緛锛�1銆戯紱銆愭彁鍙栫壒寰侊細2銆戯紱銆愭彁鍙栫壒寰�+1锛歂妫�绱細3銆戯紱
+ * @param livenessModel 妫�娴嬬粨鏋滄暟鎹泦鍚�
+ * @param feature 鐗瑰緛鐐�
+ * @param secondFeature 1:1 鐗瑰緛鐐�
+ * @param featureSize 鐗瑰緛鐐圭殑size
+ * @param type 鐗瑰緛鎻愬彇绫诲瀷
+ */
+ private void featureSearchs(
+ final int index,
+ final int featureCheckMode,
+ LivenessModel livenessModel,
+ BDFaceCheckConfig bdFaceCheckConfig,
+ byte[] feature,
+ byte[] secondFeature,
+ float featureSize,
+ BDFaceSDKCommon.FeatureType type) {
+
+ // 濡傛灉鍙彁鍘荤壒寰侊紝涓嶅仛妫�绱紝姝ゅ杩斿洖
+
+ if (featureCheckMode == 2) {
+ livenessModel.setFeatureCode(featureSize);
+ return;
+ }
+ // 濡傛灉鎻愬彇鐗瑰緛+妫�绱紝璋冪敤search 鏂规硶
+ if (featureSize == FEATURE_SIZE / 4) {
+ long startFeature = System.currentTimeMillis();
+ // 鐗瑰緛鎻愬彇鎴愬姛
+ // TODO 闃堝�煎彲浠ユ牴鎹笉鍚屾ā鍨嬭皟鏁�
+ if (featureCheckMode == 3) {
+ //System.out.println("==isOk==>44");
+ List<? extends Feature> featureResult =
+ faceModel.getFaceSearch().search(type, bdFaceCheckConfig.scoreThreshold, 5, feature, false);
+ //System.out.println("==isOk==>45");
+ // TODO 杩斿洖top num = 1 涓暟鎹泦鍚堬紝姝ゅ鍙互浠绘剰璁剧疆锛屼細杩斿洖姣斿浠庡ぇ鍒板皬鎺掑簭鐨刵um 涓暟鎹泦鍚�
+ if (featureResult != null && featureResult.size() > 0) {
+ //System.out.println("==isOk==>鍖归厤鍒版暟閲�"+featureResult.size());
+ User user = null;
+ Feature topFeature = null;
+ if(TextUtils.isEmpty(groupId)){
+ //涓虹┖锛岄渶瑕佹帓搴忥紝浼樺厛鍙栦細鍛�
+ for(Feature feat:featureResult) {
+ threholdScore = bdFaceCheckConfig.scoreThreshold;
+ if (feat != null && feat.getScore() > threholdScore) {
+ User userOld = FaceApi.getInstance().getUserListById(feat.getId());
+ //System.out.println("==isOk==>鍖归厤鍒扮被鍨�:"+userOld.getUserName());
+ if("1".equals(userOld.getGroupId())){
+ user = userOld;
+ topFeature = feat;
+ break;
+ }else if(user==null){
+ user = userOld;
+ topFeature = feat;
+ }
+ }
+ }
+ }else {
+ //鍙彇璇ョ被鍨嬬敤鎴�
+ for(Feature feat:featureResult) {
+ // 鑾峰彇鏁版嵁
+ // 鍒ゆ柇闃堝�兼槸鍚﹀ぇ浜庤瀹氶槇鍊硷紝濡傛灉澶т簬锛屾绱㈡垚鍔�
+ threholdScore = bdFaceCheckConfig.scoreThreshold;
+ if (feat != null && feat.getScore() > threholdScore) {
+ //System.out.println("==isOk==>50");
+ // 褰撳墠featureEntity 鍙湁id+feature 绱㈠紩锛屽湪鏁版嵁搴撲腑鏌ュ埌瀹屾暣淇℃伅
+ User userOld = FaceApi.getInstance().getUserListById(feat.getId());
+ if(groupId.equals(userOld.getGroupId())){
+ user = userOld;
+ topFeature = feat;
+ break;
+ }
+ }
+ }
+ }
+ if (user != null) {
+ //System.out.println("==isOk==>鍖归厤鍒�");
+ IdentifyResult idResult = new IdentifyResult(user, index, topFeature.getScore());
+ livenessModel.addIdentifyResult(idResult);
+ livenessModel.setUser(user);
+ livenessModel.setFeatureScore(topFeature.getScore());
+ setFail(livenessModel);
+ } else {
+ //IdentifyResult idResult = new IdentifyResult(user, index, topFeature.getScore());
+ setFail(livenessModel);
+ }
+ } else {
+ setFail(livenessModel);
+ }
+ } else if (featureCheckMode == 4) {
+ // 鐩墠浠呮敮鎸�
+ float score =
+ faceModel
+ .getFaceSearch()
+ .compare(
+ BDFaceSDKCommon.FeatureType.BDFACE_FEATURE_TYPE_ID_PHOTO,
+ livenessModel.getFeature(),
+ secondFeature,
+ true);
+ livenessModel.setScore(score);
+ if (score > threholdScore) {
+ /*faceId = livenessModel.getFaceInfo().faceID;
+ trackTime = System.currentTimeMillis();
+ faceAdoptModel = livenessModel;
+ failNumber = 0;
+ isFail = false;*/
+ setFail(livenessModel);
+ } else {
+ setFail(livenessModel);
+ }
+ }
+ livenessModel.setCheckDuration(System.currentTimeMillis() - startFeature);
+ }
+ }
+
+ /**
+ * 閲戣瀺娲绘-妫�娴�-娲讳綋
+ *
+ * @param bdFaceImageConfig 鍙鍏塝UV 鏁版嵁娴�
+ * @param bdNirFaceImageConfig 绾㈠YUV 鏁版嵁娴�
+ * @param bdDepthFaceImageConfig 娣卞害depth 鏁版嵁娴�
+ * @param bdFaceCheckConfig 璇嗗埆鍙傛暟
+ * @param faceDetectCallBack
+ */
+ public void onDetectSilentLiveCheck(
+ final BDFaceImageConfig bdFaceImageConfig,
+ final BDFaceImageConfig bdNirFaceImageConfig,
+ final BDFaceImageConfig bdDepthFaceImageConfig,
+ final BDFaceCheckConfig bdFaceCheckConfig,
+ final FaceDetectCallBack faceDetectCallBack) {
+ long startTime = System.currentTimeMillis();
+ // 鍒涘缓妫�娴嬬粨鏋滃瓨鍌ㄦ暟鎹�
+ LivenessModel livenessModel = new LivenessModel();
+ // 鍒涘缓妫�娴嬪璞★紝濡傛灉鍘熷鏁版嵁YUV锛岃浆涓虹畻娉曟娴嬬殑鍥剧墖BGR
+ // TODO: 鐢ㄦ埛璋冩暣鏃嬭浆瑙掑害鍜屾槸鍚﹂暅鍍忥紝鎵嬫満鍜屽紑鍙戠増闇�瑕佸姩鎬侀�傞厤
+ BDFaceImageInstance rgbInstance = getBdImage(bdFaceImageConfig, bdFaceCheckConfig.darkEnhance);
+ livenessModel.setTestBDFaceImageInstanceDuration(System.currentTimeMillis() - startTime);
+ onTrack(
+ rgbInstance,
+ livenessModel,
+ new DetectListener() {
+ @Override
+ public void onDetectSuccess(FaceInfo[] faceInfos, BDFaceImageInstance rgbInstance) {
+
+ // 淇濆瓨浜鸿劯鐗瑰緛鐐�
+ livenessModel.setLandmarks(faceInfos[0].landmarks);
+ // 淇濆瓨浜鸿劯鍥剧墖
+ livenessModel.setBdFaceImageInstance(rgbInstance.getImage());
+ // 璋冪敤缁樺埗浜鸿劯妗嗘帴鍙�
+ if (faceDetectCallBack != null) {
+ faceDetectCallBack.onFaceDetectDarwCallback(livenessModel);
+ }
+ // 閫佹璇嗗埆
+ onSilentLivenessCheck(
+ rgbInstance,
+ bdNirFaceImageConfig,
+ bdDepthFaceImageConfig,
+ bdFaceCheckConfig,
+ livenessModel,
+ startTime,
+ faceDetectCallBack,
+ faceInfos);
+ }
+
+ @Override
+ public void onDetectFail() {
+ // 娴佺▼缁撴潫閿�姣佸浘鐗囷紝寮�濮嬩笅涓�甯у浘鐗囨娴嬶紝鍚︾潃鍐呭瓨娉勯湶
+ if (faceDetectCallBack != null) {
+ faceDetectCallBack.onFaceDetectCallback(null);
+ livenessModel.setBdFaceImageInstance(rgbInstance.getImage());
+ faceDetectCallBack.onFaceDetectDarwCallback(livenessModel);
+ faceDetectCallBack.onTip(0, "鏈娴嬪埌浜鸿劯");
+ }
+
+ }
+ });
+ }
+
+ /**
+ * 閲戣瀺娲绘-娲讳綋
+ *
+ * @param rgbInstance 鍙鍏夊簳灞傞�佹瀵硅薄
+ * @param nirBDFaceImageConfig 绾㈠YUV 鏁版嵁娴�
+ * @param depthBDFaceImageConfig 娣卞害depth 鏁版嵁娴�
+ * @param livenessModel 妫�娴嬬粨鏋滄暟鎹泦鍚�
+ * @param startTime 寮�濮嬫娴嬫椂闂�
+ * @param faceDetectCallBack
+ */
+ public void onSilentLivenessCheck(
+ final BDFaceImageInstance rgbInstance,
+ final BDFaceImageConfig nirBDFaceImageConfig,
+ final BDFaceImageConfig depthBDFaceImageConfig,
+ final BDFaceCheckConfig bdFaceCheckConfig,
+ final LivenessModel livenessModel,
+ final long startTime,
+ final FaceDetectCallBack faceDetectCallBack,
+ final FaceInfo[] fastFaceInfos) {
+
+ if (future2 != null && !future2.isDone()) {
+ // 娴佺▼缁撴潫閿�姣佸浘鐗囷紝寮�濮嬩笅涓�甯у浘鐗囨娴嬶紝鍚︾潃鍐呭瓨娉勯湶
+
+ return;
+ }
+
+ future2 =
+ es2.submit(
+ new Runnable() {
+
+ @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銆戯紱銆怰GB娲讳綋锛�1銆戯紱銆怰GB+NIR娲讳綋锛�2銆戯紱銆怰GB+Depth娲讳綋锛�3銆戯紱銆怰GB+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) {
+
+ // 鍒涘缓妫�娴嬪璞★紝濡傛灉鍘熷鏁版嵁YUV-IR锛岃浆涓虹畻娉曟娴嬬殑鍥剧墖BGR
+ // TODO: 鐢ㄦ埛璋冩暣鏃嬭浆瑙掑害鍜屾槸鍚﹂暅鍍忥紝鎵嬫満鍜屽紑鍙戠増闇�瑕佸姩鎬侀�傞厤
+ nirInstance = getBdImage(nirBDFaceImageConfig, false);
+ livenessModel.setBdNirFaceImageInstance(nirInstance.getImage());
+
+ // 閬垮厤RGB妫�娴嬪叧閿偣鍦↖R瀵归綈娲讳綋绋冲畾锛屽鍔犵孩澶栨娴�
+ 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);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onDetectFail() {
+
+ if (faceDetectCallBack != null) {
+ faceDetectCallBack.onFaceDetectCallback(livenessModel);
+ }
+ }
+ });
+ }
+ });
+ }
+
+ private void onTrack(BDFaceImageInstance rgbInstance, LivenessModel livenessModel, DetectListener detectListener) {
+
+ long startDetectTime = System.currentTimeMillis();
+
+ livenessModel.setRgbDetectDuration(System.currentTimeMillis() - startDetectTime);
+ // track
+ FaceInfo[] faceInfos = null;
+ // 澶氫汉閲囩敤妫�娴嬶紝涓嶈兘璺熻釜
+ if (isMultiIdentify){
+ faceInfos = getDetectCheck(rgbInstance);
+ }
+ else{
+ faceInfos = getTrackCheck(rgbInstance);
+ }
+
+ // 妫�娴嬬粨鏋滃垽鏂�
+ if (faceInfos == null || faceInfos.length == 0) {
+ detectListener.onDetectFail();
+ return;
+ }
+ livenessModel.setTrackFaceInfo(faceInfos);
+ // livenessModel.setFaceInfo(faceInfos[0]);
+ // 淇敼涓鸿繑鍥炲浜鸿劯妗�
+ // livenessModel.setFaceInfos(faceInfos);
+ livenessModel.setFaceInfos(faceInfos);
+ livenessModel.setTrackLandmarks(faceInfos[0].landmarks);
+
+ livenessModel.setTrackStatus(1);
+
+ // detectListener.onDetectSuccess(faceInfos, rgbInstance);
+ detectListener.onDetectSuccess(faceInfos, rgbInstance);
+
+ /* if (size > 0) {
+ byte[] featureArr1 = new byte[512];
+ byte[] featureArr2 = new byte[512];
+
+ float featureSize = faceModel.getFaceFeature().feature(
+ BDFaceSDKCommon.FeatureType.BDFACE_FEATURE_TYPE_LIVE_PHOTO, rgbInstance, new_faceInfos[0].landmarks, featureArr1);
+
+ Log.d("Attend", "compare_score1111:" + featureSize);
+ featureSize = faceModel.getFaceFeature().feature(
+ BDFaceSDKCommon.FeatureType.BDFACE_FEATURE_TYPE_LIVE_PHOTO, rgbInstance, new_faceInfos[0].landmarks, featureArr1);
+
+ Log.d("Attend", "compare_score2222:" + featureSize);
+ FaceSearch faceSearch = new FaceSearch();
+ float featureScore = faceSearch.compare(
+ BDFaceSDKCommon.FeatureType.BDFACE_FEATURE_TYPE_LIVE_PHOTO,
+ featureArr1,
+ featureArr2,
+ true);
+ Log.d("Attend", "compare_score:" + featureScore);
+ } */
+
+ }
+
+ /**
+ * 璐ㄩ噺妫�娴嬬粨鏋滆繃婊わ紝濡傛灉闇�瑕佽川閲忔娴嬶紝
+ * 闇�瑕佽皟鐢� SingleBaseConfig.getBaseConfig().setQualityControl(true);璁剧疆涓簍rue锛�
+ * 鍐嶈皟鐢� FaceSDKManager.getInstance().initConfig() 鍔犺浇鍒板簳灞傞厤缃」涓�
+ *
+ * @param faceInfos
+ * @param faceInfos
+ * @param faceDetectCallBack
+ * @return
+ */
+ public void onQualityCheck(
+ final FaceInfo[] faceInfos,
+ final BDQualityConfig bdQualityConfig,
+ final FaceDetectCallBack faceDetectCallBack,
+ final QualityListener qualityListener) {
+
+ if (bdQualityConfig == null) {
+ qualityListener.onQualitySuccess();
+ return;
+ }
+ // 妫�娴嬬粨鏋滆繃婊�
+ // 瑙掑害杩囨护
+
+ boolean checkQualityOk = true;
+ String detectFail = "";
+ String occlusionFail = "";
+ if (faceInfos != null) {
+ int size = faceInfos.length;
+
+ for (int i = 0; i < size; i++) {
+ StringBuffer stringBufferDetected = new StringBuffer();
+ StringBuffer stringBufferOcclusion = new StringBuffer();
+
+ FaceInfo faceInfo = faceInfos[i];
+
+ // 瑙掑害杩囨护
+ if (Math.abs(faceInfo.yaw) > bdQualityConfig.gesture) {
+ faceDetectCallBack.onTip(-1, "浜鸿劯宸﹀彸鍋忚浆瑙掕秴鍑洪檺鍒�");
+ stringBufferDetected.append("浜鸿劯宸﹀彸鍋忚浆瑙掕秴鍑洪檺鍒�");
+ } else if (Math.abs(faceInfo.roll) > bdQualityConfig.gesture) {
+ faceDetectCallBack.onTip(-1, "浜鸿劯骞宠骞抽潰鍐呯殑澶撮儴鏃嬭浆瑙掕秴鍑洪檺鍒�");
+ stringBufferDetected.append("浜鸿劯骞宠骞抽潰鍐呯殑澶撮儴鏃嬭浆瑙掕秴鍑洪檺鍒�");
+ } else if (Math.abs(faceInfo.pitch) > bdQualityConfig.gesture) {
+ faceDetectCallBack.onTip(-1, "浜鸿劯涓婁笅鍋忚浆瑙掕秴鍑洪檺鍒�");
+ stringBufferDetected.append("浜鸿劯涓婁笅鍋忚浆瑙掕秴鍑洪檺鍒�");
+ }
+
+ // 妯$硦缁撴灉杩囨护
+ float blur = faceInfo.bluriness;
+ if (blur > bdQualityConfig.blur) {
+ faceDetectCallBack.onTip(-1, "鍥剧墖妯$硦");
+ stringBufferDetected.append("鍥剧墖妯$硦");
+ }
+
+ // 鍏夌収缁撴灉杩囨护
+ float illum = faceInfo.illum;
+ Log.e("illum", "illum = " + illum);
+ if (illum < bdQualityConfig.illum) {
+ faceDetectCallBack.onTip(-1, "鍥剧墖鍏夌収涓嶉�氳繃");
+ stringBufferDetected.append("鍥剧墖鍏夌収涓嶉�氳繃");
+ }
+
+ if (!checkMouthMask) {
+ // 閬尅缁撴灉杩囨护
+ if (faceInfo.occlusion != null) {
+ BDFaceOcclusion occlusion = faceInfo.occlusion;
+
+ if (occlusion.leftEye > bdQualityConfig.leftEye) {
+ // 宸︾溂閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "宸︾溂閬尅");
+ stringBufferOcclusion.append("宸︾溂閬尅");
+ } else if (occlusion.rightEye > bdQualityConfig.rightEye) {
+ // 鍙崇溂閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "鍙崇溂閬尅");
+ stringBufferOcclusion.append("鍙崇溂閬尅");
+ } else if (occlusion.nose > bdQualityConfig.nose) {
+ // 榧诲瓙閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "榧诲瓙閬尅");
+ stringBufferOcclusion.append("榧诲瓙閬尅");
+ } else if (occlusion.mouth > bdQualityConfig.mouth) {
+ // 鍢村反閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "鍢村反閬尅");
+ stringBufferOcclusion.append("鍢村反閬尅");
+ } else if (occlusion.leftCheek > bdQualityConfig.leftCheek) {
+ // 宸﹁劯閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "宸﹁劯閬尅");
+ stringBufferOcclusion.append("宸﹁劯閬尅");
+ } else if (occlusion.rightCheek > bdQualityConfig.rightCheek) {
+ // 鍙宠劯閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "鍙宠劯閬尅");
+ stringBufferOcclusion.append("鍙宠劯閬尅");
+ } else if (occlusion.chin > bdQualityConfig.chinContour) {
+ // 涓嬪反閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "涓嬪反閬尅");
+ stringBufferOcclusion.append("涓嬪反閬尅");
+ }
+ }
+ }
+ if (!TextUtils.isEmpty(stringBufferDetected.toString())
+ || !TextUtils.isEmpty(stringBufferOcclusion.toString())) {
+ if (!TextUtils.isEmpty(stringBufferDetected.toString())) {
+ detectFail = stringBufferDetected.toString();
+ }
+ if (!TextUtils.isEmpty(stringBufferOcclusion.toString())) {
+ occlusionFail = stringBufferOcclusion.toString();
+ }
+ checkQualityOk = false;
+ }
+ }
+ }
+ if (checkQualityOk) {
+ qualityListener.onQualitySuccess();
+ return;
+ }
+ qualityListener.onQualityFail(detectFail, occlusionFail);
+ }
+ /**
+ * 璐ㄩ噺妫�娴嬬粨鏋滆繃婊わ紝濡傛灉闇�瑕佽川閲忔娴嬶紝
+ * 闇�瑕佽皟鐢� SingleBaseConfig.getBaseConfig().setQualityControl(true);璁剧疆涓簍rue锛�
+ * 鍐嶈皟鐢� FaceSDKManager.getInstance().initConfig() 鍔犺浇鍒板簳灞傞厤缃」涓�
+ *
+ * @param faceInfos
+ * @param faceInfos
+ * @param faceDetectCallBack
+ * @return
+ */
+ public boolean onQualityCheck(
+ final FaceInfo[] faceInfos,
+ final BDQualityConfig bdQualityConfig,
+ final FaceDetectCallBack faceDetectCallBack) {
+
+ if (bdQualityConfig == null) {
+ return true;
+ }
+ boolean qualityCheck = false;
+ if (faceInfos != null) {
+ int size = faceInfos.length;
+ for (int i = 0; i < size; ++i) {
+ FaceInfo faceInfo = faceInfos[i];
+ boolean checkItem = true;
+ // 瑙掑害杩囨护
+ if (Math.abs(faceInfo.yaw) > bdQualityConfig.gesture) {
+ faceDetectCallBack.onTip(-1, "浜鸿劯宸﹀彸鍋忚浆瑙掕秴鍑洪檺鍒�");
+ checkItem = false;
+ } else if (Math.abs(faceInfo.roll) > bdQualityConfig.gesture) {
+ faceDetectCallBack.onTip(-1, "浜鸿劯骞宠骞抽潰鍐呯殑澶撮儴鏃嬭浆瑙掕秴鍑洪檺鍒�");
+ checkItem = false;
+ } else if (Math.abs(faceInfo.pitch) > bdQualityConfig.gesture) {
+ faceDetectCallBack.onTip(-1, "浜鸿劯涓婁笅鍋忚浆瑙掕秴鍑洪檺鍒�");
+ checkItem = false;
+ }
+
+ // 妯$硦缁撴灉杩囨护
+ float blur = faceInfo.bluriness;
+ if (blur > bdQualityConfig.blur) {
+ faceDetectCallBack.onTip(-1, "鍥剧墖妯$硦");
+ checkItem = false;
+ }
+
+ // 鍏夌収缁撴灉杩囨护
+ float illum = faceInfo.illum;
+ Log.e("illum", "illum = " + illum);
+ if (illum < bdQualityConfig.illum) {
+ faceDetectCallBack.onTip(-1, "鍥剧墖鍏夌収涓嶉�氳繃");
+ checkItem = false;
+ }
+
+ // 鍙g僵璇嗗埆涓嶈繘琛岃川閲忓垽鏂�
+ if (!checkMouthMask) {
+ // 閬尅缁撴灉杩囨护
+ if (faceInfo.occlusion != null) {
+ BDFaceOcclusion occlusion = faceInfo.occlusion;
+
+ if (occlusion.leftEye > bdQualityConfig.leftEye) {
+ // 宸︾溂閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "宸︾溂閬尅");
+ checkItem = false;
+ } else if (occlusion.rightEye > bdQualityConfig.rightEye) {
+ // 鍙崇溂閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "鍙崇溂閬尅");
+ checkItem = false;
+ } else if (occlusion.nose > bdQualityConfig.nose) {
+ // 榧诲瓙閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "榧诲瓙閬尅");
+ checkItem = false;
+ } else if (occlusion.mouth > bdQualityConfig.mouth) {
+ // 鍢村反閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "鍢村反閬尅");
+ checkItem = false;
+ } else if (occlusion.leftCheek > bdQualityConfig.leftCheek) {
+ // 宸﹁劯閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "宸﹁劯閬尅");
+ checkItem = false;
+ } else if (occlusion.rightCheek > bdQualityConfig.rightCheek) {
+ // 鍙宠劯閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "鍙宠劯閬尅");
+ checkItem = false;
+ } else if (occlusion.chin > bdQualityConfig.chinContour) {
+ // 涓嬪反閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "涓嬪反閬尅");
+ }
+ }
+ }
+ else{
+ return true;
+ }
+
+ if (checkItem) {
+ qualityCheck = true;
+ return qualityCheck;
+ }
+ }
+ }
+ return qualityCheck;
+ }
+
+ /**
+ * 璐ㄩ噺妫�娴嬬粨鏋滆繃婊わ紝濡傛灉闇�瑕佽川閲忔娴嬶紝
+ * 闇�瑕佽皟鐢� SingleBaseConfig.getBaseConfig().setQualityControl(true);璁剧疆涓簍rue锛�
+ * 鍐嶈皟鐢� FaceSDKManager.getInstance().initConfig() 鍔犺浇鍒板簳灞傞厤缃」涓�
+ *
+ * @param faceInfo
+ * @param faceInfo
+ * @param faceDetectCallBack
+ * @return
+ */
+ public boolean onPersonQualityCheck(
+ final FaceInfo faceInfo, final BDQualityConfig bdQualityConfig, final FaceDetectCallBack faceDetectCallBack) {
+
+ if (bdQualityConfig == null) {
+ return true;
+ }
+
+ if (faceInfo != null) {
+
+ // 瑙掑害杩囨护
+ if (Math.abs(faceInfo.yaw) > bdQualityConfig.gesture) {
+ faceDetectCallBack.onTip(-1, "浜鸿劯宸﹀彸鍋忚浆瑙掕秴鍑洪檺鍒�");
+ return false;
+ } else if (Math.abs(faceInfo.roll) > bdQualityConfig.gesture) {
+ faceDetectCallBack.onTip(-1, "浜鸿劯骞宠骞抽潰鍐呯殑澶撮儴鏃嬭浆瑙掕秴鍑洪檺鍒�");
+ return false;
+ } else if (Math.abs(faceInfo.pitch) > bdQualityConfig.gesture) {
+ faceDetectCallBack.onTip(-1, "浜鸿劯涓婁笅鍋忚浆瑙掕秴鍑洪檺鍒�");
+ return false;
+ }
+
+ // 妯$硦缁撴灉杩囨护
+ float blur = faceInfo.bluriness;
+ if (blur > bdQualityConfig.blur) {
+ faceDetectCallBack.onTip(-1, "鍥剧墖妯$硦");
+ return false;
+ }
+
+ // 鍏夌収缁撴灉杩囨护
+ float illum = faceInfo.illum;
+ Log.e("illum", "illum = " + illum);
+ if (illum < bdQualityConfig.illum) {
+ faceDetectCallBack.onTip(-1, "鍥剧墖鍏夌収涓嶉�氳繃");
+ return false;
+ }
+
+ // 鍙g僵璇嗗埆涓嶈繘琛岃川閲忓垽鏂�
+ if (!checkMouthMask) {
+ // 閬尅缁撴灉杩囨护
+ if (faceInfo.occlusion != null) {
+ BDFaceOcclusion occlusion = faceInfo.occlusion;
+
+ if (occlusion.leftEye > bdQualityConfig.leftEye) {
+ // 宸︾溂閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "宸︾溂閬尅");
+ } else if (occlusion.rightEye > bdQualityConfig.rightEye) {
+ // 鍙崇溂閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "鍙崇溂閬尅");
+ } else if (occlusion.nose > bdQualityConfig.nose) {
+ // 榧诲瓙閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "榧诲瓙閬尅");
+ } else if (occlusion.mouth > bdQualityConfig.mouth) {
+ // 鍢村反閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "鍢村反閬尅");
+ } else if (occlusion.leftCheek > bdQualityConfig.leftCheek) {
+ // 宸﹁劯閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "宸﹁劯閬尅");
+ } else if (occlusion.rightCheek > bdQualityConfig.rightCheek) {
+ // 鍙宠劯閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "鍙宠劯閬尅");
+ } else if (occlusion.chin > bdQualityConfig.chinContour) {
+ // 涓嬪反閬尅缃俊搴�
+ faceDetectCallBack.onTip(-1, "涓嬪反閬尅");
+ } else {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 妫�娴�-娲讳綋-鐗瑰緛- 鍏ㄦ祦绋�
+ * bluriness 妯$硦寰楀垎
+ * leftEye 宸︾溂閬搵寰楀垎
+ * rightEye 鍙崇溂閬搵寰楀垎
+ * nose 榧诲瓙閬搵寰楀垎
+ * mouth 鍢村反閬搵寰楀垎
+ * leftCheek 宸﹁噳鐪奸伄鎿嬪緱鍒�
+ * rightCheek 鍙宠噳閬搵寰楀垎
+ */
+ private boolean selectQuality(
+ float bluriness,
+ float leftEye,
+ float rightEye,
+ float nose,
+ float mouth,
+ float leftCheek,
+ float rightCheek,
+ float chin) {
+
+ return bluriness < 0.5
+ && leftEye < 0.75
+ && rightEye < 0.75
+ && nose < 0.75
+ && mouth < 0.75
+ && leftCheek < 0.75
+ && rightCheek < 0.75
+ && chin < 0.7;
+ }
+
+ // 浜鸿瘉鏍搁獙鐗瑰緛鎻愬彇
+ public float personDetect(
+ final Bitmap bitmap, final byte[] feature, final BDFaceCheckConfig bdFaceCheckConfig, Context context) {
+ if(bitmap==null||bitmap.isRecycled()){
+ return -1;
+ }
+ BDFaceImageInstance rgbInstance = new BDFaceImageInstance(bitmap);
+ float ret = -1;
+ FaceInfo[] faceInfos;
+ BDQualityConfig bdQualityConfig = bdFaceCheckConfig == null ? null : bdFaceCheckConfig.bdQualityConfig;
+ if (bdFaceCheckConfig != null) {
+ bdFaceCheckConfig.bdFaceDetectListConfig.usingDetect = true;
+ faceInfos =
+ faceModel
+ .getFaceDetectPerson()
+ .detect(
+ BDFaceSDKCommon.DetectType.DETECT_VIS,
+ BDFaceSDKCommon.AlignType.BDFACE_ALIGN_TYPE_RGB_ACCURATE,
+ rgbInstance,
+ null,
+ bdFaceCheckConfig.bdFaceDetectListConfig);
+ } else {
+ faceInfos = faceModel.getFaceDetectPerson().detect(BDFaceSDKCommon.DetectType.DETECT_VIS, rgbInstance);
+ }
+ if (faceInfos != null && faceInfos.length > 0) {
+ // 鍒ゆ柇璐ㄩ噺妫�娴嬶紝閽堝妯$硦搴︺�侀伄鎸°�佽搴�
+ if (onPersonQualityCheck(faceInfos[0], bdQualityConfig, new FaceQualityBack(context))) {
+ ret =
+ faceModel
+ .getFacePersonFeature()
+ .feature(
+ BDFaceSDKCommon.FeatureType.BDFACE_FEATURE_TYPE_LIVE_PHOTO,
+ rgbInstance,
+ faceInfos[0].landmarks,
+ feature);
+ }
+ } else {
+
+ return -1;
+ }
+
+ return ret;
+ }
+}
--
Gitblit v1.9.3