| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- package me.zhengjie.base.face;
- import com.alibaba.fastjson.JSONObject;
- 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.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
- import lombok.RequiredArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import me.zhengjie.base.ResultCode;
- import me.zhengjie.base.config.thread.ThreadPoolExecutorUtil;
- import me.zhengjie.base.util.FileUploadUtil;
- import me.zhengjie.base.util.tencent.utils.HttpClientUtil;
- import me.zhengjie.dao.mybatis.FaceCompareRepository;
- import me.zhengjie.dao.mybatis.entity.FaceCompareEntity;
- import me.zhengjie.dao.mybatis.entity.FileInfoEntity;
- import me.zhengjie.dao.mybatis.mapper.FileInfoMapper;
- import me.zhengjie.utils.RedisUtils;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Component;
- import org.springframework.util.CollectionUtils;
- import javax.annotation.PostConstruct;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Base64;
- import java.util.List;
- import static com.arcsoft.face.toolkit.ImageFactory.getRGBData;
- @Component
- @RequiredArgsConstructor
- @Slf4j
- public class FaceCompareUtil {
- private final FileInfoMapper fileInfoMapper;
- private final RedisUtils redis;
- private final FaceCompareRepository thirdPartyInterfaceRepository;
- private static FaceEngine faceEngine;
- private static FunctionConfiguration functionConfiguration;
- private static EngineConfiguration engineConfiguration;
- private static int errorCode;
- //以下为测试部署环境
- @Value("${hongruan.appid}")
- private String appid;
- @Value("${hongruan.sdkkey}")
- private String sdkkey;
- @Value("${hongruan.libpath}")
- private String libpath;
- @PostConstruct
- private void init(){
- //从官网获取
- faceEngine = new FaceEngine(libpath);
- //激活引擎
- int errorCode = faceEngine.activeOnline(appid, sdkkey);
- if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
- throw new RuntimeException("引擎激活失败");
- }
- ActiveFileInfo activeFileInfo = new ActiveFileInfo();
- errorCode = faceEngine.getActiveFileInfo(activeFileInfo);
- if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
- throw new RuntimeException("获取激活文件信息失败");
- }
- //引擎配置
- engineConfiguration = new EngineConfiguration();
- engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
- engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
- engineConfiguration.setDetectFaceMaxNum(10);
- engineConfiguration.setDetectFaceScaleVal(16);
- //功能配置
- 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);
- //初始化引擎
- errorCode = faceEngine.init(engineConfiguration);
- if (errorCode != ErrorInfo.MOK.getValue()) {
- throw new RuntimeException("初始化引擎失败");
- }
- }
- /**
- * 验证照片是否居中
- * @param base
- * @return
- */
- public boolean imageCenter(File base) {
- //人脸检测
- ImageInfo imageInfo = getRGBData(base);
- List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
- errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
- System.out.println(faceInfoList);
- //人脸属性检测
- FunctionConfiguration configuration = new FunctionConfiguration();
- configuration.setSupportFace3dAngle(true);
- errorCode = faceEngine.process(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList, configuration);
- //3D信息检测
- List<Face3DAngle> face3DAngleList = new ArrayList<Face3DAngle>();
- errorCode = faceEngine.getFace3DAngle(face3DAngleList);
- if (CollectionUtils.isEmpty(face3DAngleList)) {
- return false;
- }
- //俯仰角
- float pitch = Math.abs(face3DAngleList.get(0).getPitch());
- //偏向角
- float yaw = Math.abs(face3DAngleList.get(0).getYaw());
- log.info("俯仰角:{}", pitch);
- log.info("偏向角:{}", yaw);
- if (pitch >= 10 || yaw >= 10) {
- //照片不符合标准
- log.info("图片不符合标准");
- return false;
- }
- return true;
- }
- /**
- * 校验图片的当事人是否为一个
- * @param base
- * @return
- */
- public boolean imageSingle(File base) {
- //人脸检测
- ImageInfo imageInfo = getRGBData(base);
- List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
- errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
- System.out.println(faceInfoList);
- if (faceInfoList.size()>1){
- return false;
- }
- return true;
- }
- /**
- * 虹软的人脸照片比对
- *
- * @param base 照片
- * @param id 文件库中照片的id
- * @param redisCount 数据库中的键
- * @param count redis当中的次数
- * @return
- */
- public ResultCode compareImage(File base, Integer id, String redisCount, FaceCompareEntity faceCompareEntity) {
- //人脸检测
- ImageInfo imageInfo = getRGBData(base);
- List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
- errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
- System.out.println(faceInfoList);
- //活体检测
- /*List<LivenessInfo> livenessInfoList = new ArrayList<LivenessInfo>();
- errorCode = faceEngine.getLiveness(livenessInfoList);
- if (CollectionUtils.isEmpty(livenessInfoList)){
- log.info("活体验证失败");
- return false;
- }
- System.out.println("活体:" + livenessInfoList.get(0).getLiveness());
- //IR属性处理
- ImageInfo imageInfoGray = getGrayData(base);
- List<FaceInfo> faceInfoListGray = new ArrayList<FaceInfo>();
- errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoListGray);
- FunctionConfiguration configuration2 = new FunctionConfiguration();
- configuration2.setSupportIRLiveness(true);
- errorCode = faceEngine.processIr(imageInfoGray.getImageData(), imageInfoGray.getWidth(), imageInfoGray.getHeight(), imageInfoGray.getImageFormat(), faceInfoListGray, configuration2);
- //IR活体检测
- List<IrLivenessInfo> irLivenessInfo = new ArrayList<>();
- errorCode = faceEngine.getLivenessIr(irLivenessInfo);
- if (CollectionUtils.isEmpty(irLivenessInfo)){
- log.info("活体验证失败");
- return false;
- }
- System.out.println("IR活体:" + irLivenessInfo.get(0).getLiveness());*/
- //特征提取
- FaceFeature faceFeature = new FaceFeature();
- errorCode = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature);
- //根据id 查找文件
- QueryWrapper<FileInfoEntity> fileInfoQw = new QueryWrapper<>();
- fileInfoQw.eq("id", id);
- FileInfoEntity fileInfoEntity = fileInfoMapper.selectOne(fileInfoQw);
- String filePath = fileInfoEntity.getPath();
- File file = null;
- try {
- file= FileUploadUtil.getFileWithPath(filePath);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- //人脸检测2
- ImageInfo imageInfo2 = getRGBData(file);
- List<FaceInfo> faceInfoList2 = new ArrayList<FaceInfo>();
- 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);
- //如果通过 上传文件 修改用户绑定id 如果没通过 返回null证明失败了
- //引擎卸载
- errorCode = faceEngine.unInit();
- float score = faceSimilar.getScore();
- faceCompareEntity.setScore(score+"");
- FileInputStream fileInputStream = null;
- try {
- fileInputStream = new FileInputStream(base);
- } catch (FileNotFoundException e) {
- throw new RuntimeException(e);
- }
- byte[] bytes = new byte[(int) base.length()];
- try {
- fileInputStream.read(bytes);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }finally {
- try {
- fileInputStream.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- String s = Base64.getEncoder().encodeToString(bytes);
- FileInfoEntity fileInfo = uploadFaceFile(s);
- faceCompareEntity.setFileId(fileInfo.getId()+"");
- faceCompareEntity.setType(0);
- if (score > 0.8) {
- log.info("人脸照片比对通过");
- faceCompareEntity.setResult(1);
- thirdPartyInterfaceRepository.insert(faceCompareEntity);
- file.delete();
- base.delete();
- redis.del(redisCount);
- return ResultCode.SUCCESS;
- }
- redis.increment(redisCount);
- log.info("人脸照片比对未通过");
- faceCompareEntity.setMessage("验证失败");
- faceCompareEntity.setResult(0);
- thirdPartyInterfaceRepository.insert(faceCompareEntity);
- file.delete();
- base.delete();
- return ResultCode.LIVE_VIDEO_INVALID;
- }
- public FileInfoEntity uploadFaceFile(String base64){
- String s = FileUploadUtil.saveFaceImage(base64);
- ThreadPoolExecutorUtil.getPoll().execute(new Runnable() {
- @Override
- public void run() {
- uploadFile(base64,s);
- }
- });
- String[] split = s.split("/");
- FileInfoEntity fileInfo = new FileInfoEntity();
- fileInfo.setLoanNo(split[0]);
- fileInfo.setFileName(split[split.length-1]);
- fileInfo.setPath(s);
- fileInfoMapper.insert(fileInfo);
- return fileInfo;
- }
- /**
- * 上传对比照片到minio
- * @param base64
- */
- public void uploadFile(String base64,String filePath){
- JSONObject params = new JSONObject();
- params.put("base64", base64);
- params.put("filePath",filePath);
- HttpClientUtil httpClientUtil = new HttpClientUtil();
- String xmlData = httpClientUtil.doPost("https://fqgz.flowbb.cn:6001/sp/upload/uploadFaceImage",params.toString(),"utf-8");
- JSONObject result = JSONObject.parseObject(xmlData);
- String code = result.getString("code");
- if ("100".equals(code)){
- log.info("上传成功");
- }
- }
- }
|