private bool filter(FaceInfo faceInfo, int bitMapWidth, int bitMapHeight) { if (faceInfo.MConf < 0.6) { livenessCallBack.onTip(0, "人脸置信度太低"); // clearInfo(); return(false); } float[] headPose = FaceFeature.PerformQuery <float>(faceInfo.HeadPose); // Log.i("wtf", "headpose->" + headPose[0] + " " + headPose[1] + " " + headPose[2]); if (Java.Lang.Math.Abs(headPose[0]) > 15 || Java.Lang.Math.Abs(headPose[1]) > 15 || Java.Lang.Math.Abs(headPose[2]) > 15) { livenessCallBack.onTip(0, "人脸置角度太大,请正对屏幕"); return(false); } // 判断人脸大小,若人脸超过屏幕二分一,则提示文案“人脸离手机太近,请调整与手机的距离”; // 若人脸小于屏幕三分一,则提示“人脸离手机太远,请调整与手机的距离” float ratio = (float)faceInfo.MWidth / (float)bitMapHeight; // Log.i("liveness_ratio", "ratio=" + ratio); if (ratio > 0.6) { livenessCallBack.onTip(0, "人脸离屏幕太近,请调整与屏幕的距离"); // clearInfo(); return(false); } else if (ratio < 0.2) { livenessCallBack.onTip(0, "人脸离屏幕太远,请调整与屏幕的距离"); // clearInfo(); return(false); } else if (faceInfo.MCenterX > bitMapWidth * 3 / 4) { livenessCallBack.onTip(0, "人脸在屏幕中太靠右"); clearInfo(); return(false); } else if (faceInfo.MCenterX < bitMapWidth / 4) { livenessCallBack.onTip(0, "人脸在屏幕中太靠左"); // clearInfo(); return(false); } else if (faceInfo.MCenterY > bitMapHeight * 3 / 4) { livenessCallBack.onTip(0, "人脸在屏幕中太靠下"); // clearInfo(); return(false); } else if (faceInfo.MCenterX < bitMapHeight / 4) { livenessCallBack.onTip(0, "人脸在屏幕中太靠上"); // clearInfo(); return(false); } return(true); }
private FaceSDKManager() { faceDetector = new FaceDetector(); faceFeature = new FaceFeature(); }
// 活体检测 private bool onLivenessCheck(int width, int height, int type) { bool isLiveness = false; // 判断当前是否有人脸 long startTime = DateTime.Now.Millisecond; int errorCode = FaceSDKManager.getInstance().getFaceDetector().detect(mRgbArray, width, height); LivenessModel livenessModel = new LivenessModel(); livenessModel.setRgbDetectDuration(DateTime.Now.Millisecond - startTime); livenessModel.getImageFrame().setArgb(mRgbArray); livenessModel.getImageFrame().setWidth(width); livenessModel.getImageFrame().setHeight(height); livenessModel.setLiveType(type); livenessModel.setFaceDetectCode(errorCode); Log.Debug(TAG, "max_face_verification: " + errorCode + " duration:" + (DateTime.Now.Millisecond - startTime)); if (errorCode == FaceTracker.ErrCode.Ok.Ordinal() || errorCode == FaceTracker.ErrCode.DataHitLast.Ordinal()) { FaceInfo[] trackedface = FaceSDKManager.getInstance().getFaceDetector().TrackedFaces; livenessModel.setTrackFaceInfo(trackedface); if (trackedface != null && trackedface.Length > 0) { FaceInfo faceInfo = trackedface[0]; livenessModel.setFaceInfo(faceInfo); // 塞选人脸,可以调节距离、角度 // if (!filter(faceInfo, width, height)) { // livenessCallBack.onCallback(null); // return isLiveness; // } if (livenessCallBack != null) { livenessCallBack.onTip(0, "活体判断中"); } float rgbScore = 0; if ((type & MASK_RGB) == MASK_RGB) { startTime = DateTime.Now.Millisecond; rgbScore = rgbLiveness(mRgbArray, width, height, FaceFeature.PerformQuery <int>(trackedface[0].Landmarks)); livenessModel.setRgbLivenessScore(rgbScore); livenessModel.setRgbLivenessDuration(DateTime.Now.Millisecond - startTime); } float irScore = 0; if ((type & MASK_IR) == MASK_IR) { float maxWidth = 0; int maxId = 0; float detectScore = 0; if (trackedface != null && trackedface.Length > 0) { for (int i = 0; i < trackedface.Length; i++) { if (trackedface[i].MWidth > maxWidth) { maxId = i; maxWidth = trackedface[i].MWidth; detectScore = trackedface[i].MConf; } } } if (trackedface != null) { float[] faceT = new float[] { trackedface[maxId].MCenterX, trackedface[maxId].MCenterY, trackedface[maxId].MWidth, trackedface[maxId].MAngle }; int[] shape = new int[144]; int[] nPoint = new int[] { 0 }; float[] score = new float[] { 0.0F }; FaceSDK.Run_align(nirRgbArray, height, width, FaceSDK.ImgType.Argb, FaceSDK.AlignMethodType.Cdnn, faceT, shape, nPoint, score, detectScore); livenessModel.setShape(shape); startTime = DateTime.Now.Millisecond; // irScore = irLiveness(mIrByte, width, height, trackedfaces[0].landmarks); irScore = irLiveness(mIrByte, width, height, shape); livenessModel.setIrLivenessDuration(DateTime.Now.Millisecond - startTime); livenessModel.setIrLivenessScore(irScore); } } float depthScore = 0; if ((type & MASK_DEPTH) == MASK_DEPTH) { startTime = DateTime.Now.Millisecond; if (trackedface != null) { depthScore = depthLiveness(mDepthArray, width, height, FaceFeature.PerformQuery <int>(trackedface[0].Landmarks)); livenessModel.setDetphtLivenessDuration(DateTime.Now.Millisecond - startTime); livenessModel.setDepthLivenessScore(depthScore); } } if (livenessCallBack != null) { livenessCallBack.onCallback(livenessModel); } // long time = System.currentTimeMillis(); // saveRgbImage(String.valueOf(time), rgbScore, mRgbArray, width, height); // saveFile(String.valueOf(time), "nir", irScore, mIrByte); // saveFile(String.valueOf(time), "depth", depthScore, mDepthArray); } } else { checkFaceCode(errorCode); if (livenessCallBack != null) { livenessCallBack.onCallback(null); } } // clearInfo(); FaceInfo[] trackedfaces = FaceSDKManager.getInstance().getFaceDetector().TrackedFaces; livenessModel.setTrackFaceInfo(trackedfaces); if (livenessCallBack != null) { livenessCallBack.onCanvasRectCallback(livenessModel); } return(isLiveness); }