package com.fgkj.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.fgkj.actions.ActionUtil;
|
import com.fgkj.dto.ServiceModel;
|
|
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 = "AafPX5afzycEnTqH3v79gY3Neb7KShspSKhJEjaLsxbY";
|
String sdkKey = "H8zJ6qGo8btTgwVksqqbp664Uenj4FSnBeEexPFAsnRi";
|
|
String realPath = ActionUtil.getApplication().getRealPath("/");
|
FaceEngine faceEngine = new FaceEngine(realPath+"\\WEB-INF\\lib\\WIN64");
|
//激活引擎,只需一次就行,后续无需再激活
|
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(){
|
String realPath = ActionUtil.getApplication().getRealPath("/");
|
FaceEngine faceEngine = new FaceEngine(realPath+"\\WEB-INF\\lib\\WIN64");
|
|
//引擎配置
|
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("初始化引擎失败");
|
return null;
|
}
|
System.out.println("初始化faceEngine引擎成功");
|
return faceEngine;
|
|
}
|
|
public static ServiceModel orientAndPxDetect(FaceEngine faceEngine,ImageInfo imageInfo) {
|
ServiceModel model = new ServiceModel();
|
model.setCode(1);
|
//检查角度是否端正,检查人脸像素大小是否>50×50
|
List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
|
faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
|
if (faceInfoList.size()<1){
|
model.setCode(0);
|
model.setMsg("无效的人脸信息");
|
}else {
|
FaceInfo faceInfo = faceInfoList.get(0);
|
Rect rect = faceInfo.getRect();
|
if (faceInfo.getOrient() != 1) {
|
model.setCode(0);
|
model.setMsg("人像姿势不端正");
|
} else if ((rect.bottom - rect.top) < 50 || (rect.right - rect.left) < 50) {
|
model.setCode(0);
|
model.setMsg("人像面部像素太低");
|
}
|
}
|
return model;
|
}
|
|
public static ServiceModel liveDetect(FaceEngine faceEngine,ImageInfo imageInfo) {
|
ServiceModel model = new ServiceModel();
|
|
int errorCode=0;
|
List<FaceInfo> faceInfoList = new ArrayList<>();
|
List<LivenessInfo> 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){
|
model.setCode(0);
|
model.setMsg("无效的脸部信息");
|
}else if(livenessInfoList.get(0).getLiveness()!=1){
|
model.setCode(0);
|
if(livenessInfoList.get(0).getLiveness()==0){
|
model.setMsg("非活体");
|
}
|
else if(livenessInfoList.get(0).getLiveness()==-2){
|
model.setMsg("人脸数不为1");
|
}
|
else if(livenessInfoList.get(0).getLiveness()==-3){
|
model.setMsg("人脸过小");
|
}
|
else if(livenessInfoList.get(0).getLiveness()==-4){
|
model.setMsg("人脸角度过大");
|
}
|
else if(livenessInfoList.get(0).getLiveness()==-5){
|
model.setMsg("人脸超出边界");
|
}
|
else if(livenessInfoList.get(0).getLiveness()==-6){
|
model.setMsg("深度图像错误");
|
}
|
else if(livenessInfoList.get(0).getLiveness()==-7){
|
model.setMsg("红外图像错误");
|
}else{
|
model.setMsg("非活体");
|
}
|
}else{
|
model.setCode(1);
|
}
|
return model;
|
}
|
|
public static ServiceModel faceCompare(FaceEngine faceEngine, ImageInfo imageInfo, ImageInfo imageInfo2) {
|
ServiceModel model = new ServiceModel();
|
int errorCode=0;
|
//人脸检测
|
List<FaceInfo> faceInfoList = new ArrayList<>();
|
errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
|
|
//特征提取
|
FaceFeature faceFeature = new FaceFeature();
|
if(faceInfoList.size()>0) {
|
errorCode = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature);
|
}else{
|
model.setCode(0);
|
model.setMsg("人脸面部无法识别");
|
}
|
|
//人脸检测2
|
List<FaceInfo> 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
|
if(faceSimilar.getScore()<0.8){
|
model.setCode(0);
|
model.setMsg("人脸不匹配");
|
}else{
|
model.setCode(1);
|
model.setMsg("匹配成功");
|
}
|
return model;
|
}
|
|
public static ServiceModel faceCompare2N(FaceEngine faceEngine, ImageInfo imageInfo, FaceFeature faceFeature2) {
|
ServiceModel model = new ServiceModel();
|
int errorCode = 0;
|
//人脸检测
|
List<FaceInfo> faceInfoList = new ArrayList<>();
|
errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
|
|
//特征提取
|
FaceFeature faceFeature = new FaceFeature();
|
if (faceInfoList.size() > 0) {
|
errorCode = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature);
|
} else {
|
model.setCode(0);
|
model.setMsg("人脸面部无法识别");
|
return model;
|
}
|
|
//特征比对
|
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
|
if (faceSimilar.getScore() < 0.88) {
|
model.setCode(0);
|
model.setMsg("人脸不匹配");
|
} else {
|
model.setCode(1);
|
}
|
return model;
|
}
|
|
}
|