package com.whyc.util; import com.arcsoft.face.*; import com.arcsoft.face.enums.DetectMode; import com.arcsoft.face.enums.DetectOrient; import com.arcsoft.face.enums.ErrorInfo; import com.arcsoft.face.toolkit.ImageInfo; import com.whyc.constant.YamlProperties; import com.whyc.dto.Response; import java.io.File; import java.util.ArrayList; import java.util.List; /** * @Description : 虹软人脸识别工具类 * @date 2020/10/28 **/ public class FaceIdentifyUtil { //外网激活 public static boolean activeOnline(){ boolean res = false; String appId=""; String sdkKey=""; FaceEngine faceEngine =null; /*//从官网我的应用中获取 String appId4Win = "AafPX5afzycEnTqH3v79gY3VozNVTSNqT8kzSmP7b48q"; String sdkKey4Win = "GsYwWhxzuQEE1WE34J3Fo8d2QppjkqYGojyc4625JhKb"; //Linux系统appId和sdkKey及文件加载 String appId4Linux ="AafPX5afzycEnTqH3v79gY3VozNVTSNqT8kzSmP7b48q"; String sdkKey4Linux ="GsYwWhxzuQEE1WE34J3Fo8d2GiFdddqH81ghetQQTGmv";*/ //从官网我的应用中获取 String appId4Win = YamlProperties.appId4Win; String sdkKey4Win = YamlProperties.sdkKey4Win; //Linux系统appId和sdkKey及文件加载 String appId4Linux =YamlProperties.appId4Linux; String sdkKey4Linux =YamlProperties.sdkKey4Linux; //String realPath = ActionUtil.getApplication().getRealPath("/"); String realPath = CommonUtil.classesPath(); System.out.println("========realPath=========:"+realPath); System.out.println("========faceEngine dll 路径=========:"+realPath+ File.separator+"lib"+File.separator+"WIN64"); //判断是什么系统 if(System.getProperty("os.name").toLowerCase().contains("window")){ appId=appId4Win; sdkKey=sdkKey4Win; faceEngine = new FaceEngine(realPath+ File.separator+"lib"+File.separator+"WIN64"); }else{ appId=appId4Linux; sdkKey=sdkKey4Linux; faceEngine = new FaceEngine(realPath+ File.separator+"WEB-INF"+File.separator+"lib"+File.separator+"LINUX64"); } //激活引擎,只需一次就行,后续无需再激活 int errorCode = faceEngine.activeOnline(appId, sdkKey); if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) { //激活失败 }else{ res=true; } return res; } /**初始化*/ public static FaceEngine init(){ FaceEngine faceEngine=null; String realPath = CommonUtil.classesPath(); if(System.getProperty("os.name").toLowerCase().contains("window")) { faceEngine = new FaceEngine(realPath + File.separator + "lib" + File.separator + "WIN64"); }else{ faceEngine = new FaceEngine(realPath + File.separator + "lib" + File.separator + "LINUX64"); } //引擎配置 EngineConfiguration engineConfiguration = new EngineConfiguration(); engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE); //对特定场景推荐单一角度而非全角度,那样精度更高 engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT); //最多支持的人脸数量 // engineConfiguration.setDetectFaceMaxNum(10); engineConfiguration.setDetectFaceMaxNum(1); engineConfiguration.setDetectFaceScaleVal(16); //功能配置 FunctionConfiguration functionConfiguration = new FunctionConfiguration(); // functionConfiguration.setSupportAge(true); functionConfiguration.setSupportFace3dAngle(true); functionConfiguration.setSupportFaceDetect(true); functionConfiguration.setSupportFaceRecognition(true); // functionConfiguration.setSupportGender(true); functionConfiguration.setSupportLiveness(true); // functionConfiguration.setSupportIRLiveness(true); engineConfiguration.setFunctionConfiguration(functionConfiguration); //初始化引擎 int errorCode = faceEngine.init(engineConfiguration); if (errorCode != ErrorInfo.MOK.getValue()) { System.out.println("初始化引擎失败:"+errorCode); return null; } System.out.println("初始化faceEngine引擎成功"); return faceEngine; } public static Response orientAndPxDetect(FaceEngine faceEngine, ImageInfo imageInfo) { //检查角度是否端正,检查人脸像素大小是否>50×50 List faceInfoList = new ArrayList(); faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList); if (faceInfoList.size()<1){ return new Response().set(1,false,"无效的人脸信息"); }else { FaceInfo faceInfo = faceInfoList.get(0); Rect rect = faceInfo.getRect(); if (faceInfo.getOrient() != 1) { return new Response().set(1,false,"人像姿势不端正"); } else if ((rect.bottom - rect.top) < 50 || (rect.right - rect.left) < 50) { return new Response().set(1,false,"人像面部像素太低"); } } return new Response().set(1,true,"校验通过"); } public static Response liveDetect(FaceEngine faceEngine, ImageInfo imageInfo) { Response res = new Response(); int errorCode=0; List faceInfoList = new ArrayList<>(); List livenessInfoList = new ArrayList<>(); errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList); //设置活体测试 //活体取值范围为[0~1],推荐阈值如下,高于此阈值的即可判断为活体。 // RGB 活体:0.5 // IR 活体:0.7 errorCode = faceEngine.setLivenessParam(0.5f, 0.7f); //人脸属性检测 FunctionConfiguration configuration = new FunctionConfiguration(); // configuration.setSupportAge(true); configuration.setSupportFace3dAngle(true); // configuration.setSupportGender(true); configuration.setSupportLiveness(true); errorCode = faceEngine.process(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList, configuration); faceEngine.getLiveness(livenessInfoList); if(livenessInfoList.size()<1 || livenessInfoList.get(0).getLiveness()!=1){ res.setCode(0); res.setMsg("无效的脸部信息"); }else{ res.setCode(1); } return res; } public static Response faceCompare(FaceEngine faceEngine, ImageInfo imageInfo, ImageInfo imageInfo2) { Response res = new Response(); int errorCode=0; //人脸检测 List faceInfoList = new ArrayList<>(); errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList); //特征提取 FaceFeature faceFeature = new FaceFeature(); errorCode = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature); //人脸检测2 List faceInfoList2 = new ArrayList<>(); errorCode = faceEngine.detectFaces(imageInfo2.getImageData(), imageInfo2.getWidth(), imageInfo2.getHeight(),imageInfo2.getImageFormat(), faceInfoList2); //特征提取2 FaceFeature faceFeature2 = new FaceFeature(); errorCode = faceEngine.extractFaceFeature(imageInfo2.getImageData(), imageInfo2.getWidth(), imageInfo2.getHeight(), imageInfo2.getImageFormat(), faceInfoList2.get(0), faceFeature2); //特征比对 FaceFeature targetFaceFeature = new FaceFeature(); targetFaceFeature.setFeatureData(faceFeature.getFeatureData()); FaceFeature sourceFaceFeature = new FaceFeature(); sourceFaceFeature.setFeatureData(faceFeature2.getFeatureData()); FaceSimilar faceSimilar = new FaceSimilar(); errorCode = faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, faceSimilar); //官方建议: //人脸比对取值范围为[0~1],推荐阈值如下,高于此阈值的即可判断为同一人。 // 用于生活照之间的特征比对,推荐阈值0.80 // 用于证件照或生活照与证件照之间的特征比对,推荐阈值0.82 float faceThreshold = YamlProperties.faceThreshold; if(faceSimilar.getScore()