private void checkResult(LivenessModel model) { if (model == null) { ClearTip(); return; } displayResult(model); int type = model.getLiveType(); bool livenessSuccess = false; // 同一时刻都通过才认为活体通过,开发者也可以根据自己的需求修改策略 if ((type & FaceLiveness.MASK_RGB) == FaceLiveness.MASK_RGB) { livenessSuccess = (model.getRgbLivenessScore() > FaceEnvironment.LIVENESS_RGB_THRESHOLD) ? true : false; } if ((type & FaceLiveness.MASK_IR) == FaceLiveness.MASK_IR) { bool irScore = (model.getIrLivenessScore() > FaceEnvironment.LIVENESS_IR_THRESHOLD) ? true : false; if (!irScore) { livenessSuccess = false; } else { livenessSuccess &= irScore; } } if ((type & FaceLiveness.MASK_DEPTH) == FaceLiveness.MASK_DEPTH) { bool depthScore = (model.getDepthLivenessScore() > FaceEnvironment.LIVENESS_DEPTH_THRESHOLD) ? true : false; if (!depthScore) { livenessSuccess = false; } else { livenessSuccess &= depthScore; } } if (livenessSuccess) { attrCheck(model.getFaceInfo(), model.getImageFrame()); } }
/** * 绘制人脸框。 */ private void showFrame2(LivenessModel model) { if (camemra1IsRgb) { Canvas canvas2 = textureViewOne.LockCanvas(); if (canvas2 == null) { textureViewOne.UnlockCanvasAndPost(canvas2); return; } if (model == null) { canvas2.DrawColor(Color.Transparent, PorterDuff.Mode.Clear); textureViewOne.UnlockCanvasAndPost(canvas2); return; } FaceInfo[] faceInfos = model.getTrackFaceInfo(); ImageFrame imageFrame = model.getImageFrame(); if (faceInfos == null || faceInfos.Length == 0) { // 清空canvas canvas2.DrawColor(Color.Transparent, PorterDuff.Mode.Clear); textureViewOne.UnlockCanvasAndPost(canvas2); return; } canvas2.DrawColor(Color.Transparent, PorterDuff.Mode.Clear); FaceInfo faceInfo2 = faceInfos[0]; rectF.Set(getFaceRectTwo(faceInfo2, imageFrame)); // 检测图片的坐标和显示的坐标不一样,需要转换。 // mPreview[typeIndex].mapFromOriginalRect(rectF); float yaw2 = Java.Lang.Math.Abs(faceInfo2.HeadPose[0]); float patch2 = Java.Lang.Math.Abs(faceInfo2.HeadPose[1]); float roll2 = Java.Lang.Math.Abs(faceInfo2.HeadPose[2]); if (yaw2 > 20 || patch2 > 20 || roll2 > 20) { // 不符合要求,绘制黄框 paint.Color = (Color.Yellow); string text = "请正视屏幕"; float width = paint.MeasureText(text) + 50; float x = rectF.CenterX() - width / 2; paint.Color = (Color.Red); paint.SetStyle(Paint.Style.Fill); canvas2.DrawText(text, x + 25, rectF.Top - 20, paint); paint.Color = (Color.Yellow); } else { // 符合检测要求,绘制绿框 paint.Color = (Color.Green); } paint.SetStyle(Paint.Style.Stroke); // 绘制框 canvas2.DrawRect(rectF, paint); textureViewOne.UnlockCanvasAndPost(canvas2); Canvas canvas = textureView.LockCanvas(); if (canvas == null) { textureView.UnlockCanvasAndPost(canvas); return; } if (faceInfos == null || faceInfos.Length == 0) { // 清空canvas canvas.DrawColor(Color.Transparent, PorterDuff.Mode.Clear); textureView.UnlockCanvasAndPost(canvas); return; } canvas.DrawColor(Color.Transparent, PorterDuff.Mode.Clear); textureView.UnlockCanvasAndPost(canvas); } else { Canvas canvas = textureView.LockCanvas(); if (canvas == null) { textureView.UnlockCanvasAndPost(canvas); return; } if (model == null) { // 清空canvas canvas.DrawColor(Color.Transparent, PorterDuff.Mode.Clear); textureView.UnlockCanvasAndPost(canvas); return; } FaceInfo[] faceInfos = model.getTrackFaceInfo(); ImageFrame imageFrame = model.getImageFrame(); if (faceInfos == null || faceInfos.Length == 0) { // 清空canvas canvas.DrawColor(Color.Transparent, PorterDuff.Mode.Clear); textureView.UnlockCanvasAndPost(canvas); return; } canvas.DrawColor(Color.Transparent, PorterDuff.Mode.Clear); FaceInfo faceInfo = faceInfos[0]; rectF.Set(getFaceRectTwo(faceInfo, imageFrame)); // 检测图片的坐标和显示的坐标不一样,需要转换。 // mPreview[typeIndex].mapFromOriginalRect(rectF); float yaw = Java.Lang.Math.Abs(faceInfo.HeadPose[0]); float patch = Java.Lang.Math.Abs(faceInfo.HeadPose[1]); float roll = Java.Lang.Math.Abs(faceInfo.HeadPose[2]); if (yaw > 20 || patch > 20 || roll > 20) { // 不符合要求,绘制黄框 paint.Color = (Color.Yellow); string text = "请正视屏幕"; float width = paint.MeasureText(text) + 50; float x = rectF.CenterX() - width / 2; paint.Color = (Color.Red); paint.SetStyle(Paint.Style.Fill); canvas.DrawText(text, x + 25, rectF.Top - 20, paint); paint.Color = (Color.Yellow); } else { // 符合检测要求,绘制绿框 paint.Color = (Color.Green); } paint.SetStyle(Paint.Style.Stroke); // 绘制框 canvas.DrawRect(rectF, paint); textureView.UnlockCanvasAndPost(canvas); Canvas canvas2 = textureViewOne.LockCanvas(); if (canvas2 == null) { textureViewOne.UnlockCanvasAndPost(canvas2); return; } if (faceInfos == null || faceInfos.Length == 0) { // 清空canvas canvas2.DrawColor(Color.Transparent, PorterDuff.Mode.Clear); textureViewOne.UnlockCanvasAndPost(canvas2); return; } canvas2.DrawColor(Color.Transparent, PorterDuff.Mode.Clear); textureViewOne.UnlockCanvasAndPost(canvas2); } }
private void checkResult(LivenessModel model) { if (model == null) { return; } displayResult(model); int type = model.getLiveType(); bool livenessSuccess = false; // 同一时刻都通过才认为活体通过,开发者也可以根据自己的需求修改策略 if ((type & FaceLiveness.MASK_RGB) == FaceLiveness.MASK_RGB) { livenessSuccess = (model.getRgbLivenessScore() > FaceEnvironment.LIVENESS_RGB_THRESHOLD) ? true : false; } if ((type & FaceLiveness.MASK_IR) == FaceLiveness.MASK_IR) { bool irScore = (model.getIrLivenessScore() > FaceEnvironment.LIVENESS_IR_THRESHOLD) ? true : false; if (!irScore) { livenessSuccess = false; } else { livenessSuccess &= irScore; } } if ((type & FaceLiveness.MASK_DEPTH) == FaceLiveness.MASK_DEPTH) { bool depthScore = (model.getDepthLivenessScore() > FaceEnvironment.LIVENESS_DEPTH_THRESHOLD) ? true : false; if (!depthScore) { livenessSuccess = false; } else { livenessSuccess &= depthScore; } } if (livenessSuccess) { Bitmap bitmap = FaceCropper.getFace(model.getImageFrame().getArgb(), model.getFaceInfo(), model.getImageFrame().getWidth()); if (source == RegActivity.SOURCE_REG) { // 注册来源保存到注册人脸目录 File faceDir = FileUitls.getFaceDirectory(); if (faceDir != null) { string imageName = System.Guid.NewGuid().ToString(); File file = new File(faceDir, imageName); // 压缩人脸图片至300 * 300,减少网络传输时间 ImageUtils.resize(bitmap, file, 300, 300); Intent intent = new Intent(); intent.PutExtra("file_path", file.AbsolutePath); SetResult(Result.Ok, intent); success = true; Finish(); } else { toast("注册人脸目录未找到"); } } else { try { // 其他来源保存到临时目录 File file = File.CreateTempFile(System.Guid.NewGuid().ToString() + "", ".jpg"); ImageUtils.resize(bitmap, file, 300, 300); Intent intent = new Intent(); intent.PutExtra("file_path", file.AbsolutePath); SetResult(Result.Ok, intent); success = true; Finish(); } catch (IOException e) { e.PrintStackTrace(); } } } }
// 活体检测 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); }