| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- package me.zhengjie.domain.notary.impl;
- 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.file.FaceMinioFileHandle;
- import me.zhengjie.base.file.FileHandleVo;
- import me.zhengjie.base.file.MinioFileHandle;
- import me.zhengjie.base.util.JuheServiceUtil;
- import me.zhengjie.base.util.tencent.utils.Img2Base64Util;
- import me.zhengjie.dao.mybatis.ThirdPartyInterfaceRepository;
- import me.zhengjie.dao.mybatis.entity.*;
- import me.zhengjie.dao.mybatis.mapper.ContractOrderMapper;
- import me.zhengjie.dao.mybatis.mapper.FileInfoMapper;
- import me.zhengjie.dao.mybatis.mapper.SysUserMapper;
- import me.zhengjie.dao.mybatis.mapper.UserAXQInfoMapper;
- import me.zhengjie.domain.img.CompareImageDomain;
- import me.zhengjie.domain.notary.NotaryDomain;
- import me.zhengjie.utils.RedisUtils;
- import me.zhengjie.utils.StringUtils;
- import org.springframework.stereotype.Component;
- import org.springframework.util.ObjectUtils;
- import java.io.File;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.concurrent.TimeUnit;
- import static com.arcsoft.face.toolkit.ImageFactory.getRGBData;
- @Component
- @RequiredArgsConstructor
- @Slf4j
- public class NotaryDomainImpl implements NotaryDomain {
- private final SysUserMapper userMapper;
- private final UserAXQInfoMapper userAXQInfoMapper;
- private final ContractOrderMapper contractOrderMapper;
- private final FaceMinioFileHandle minioFileHandle;
- private final FileInfoMapper fileInfoMapper;
- private final RedisUtils redis;
- private final ThirdPartyInterfaceRepository thirdPartyInterfaceRepository;
- //以下为测试部署环境
- // private static final String APPID = "6F5JVsCCeSEbBSLSXWVwPki71yK5Y4Jf7oUjA4Y3mLtu";
- // private static final String SDKKEY = "5qKM4a9oNSXNhXdwd7Ycrvnxdw2JXjcyeccYmb4zND7S";
- // private static final String LIBPATH = "/home/tom/nt-test/lib/so";
- //以下为本地测试
- private static final String APPID = "H6Er8ksqAcKc7Dk4Yum9Rkz4g9Gm77ZXAEMgvenjkTQQ";
- private static final String SDKKEY = "Abd9D8xZQUqG8vDtU2a1tEkdfThkK1tZppjXzydGwEd6";
- private static final String LIBPATH = "D:\\arcsoft_lib";
- /**
- * 获取base64取消文件头
- * @param base64
- * @return
- */
- public String getBase64(String base64){
- String[] base64s = base64.split("base64");
- if (base64s!=null && base64s.length>1){
- base64 = base64s[1];
- }
- return base64;
- }
- /**
- * app端的人脸核身
- * @param compareImageDomain
- * @return
- */
- public ResultCode appCompareFace(CompareImageDomain compareImageDomain){
- String base64 = compareImageDomain.getBase64();
- if (base64==null){
- return ResultCode.PARAM_IS_BLANK;
- }
- base64 = getBase64(base64);
- String idCard = compareImageDomain.getIdCard();
- String nickName = compareImageDomain.getName();
- //当事人的人脸核身
- QueryWrapper<UserAXQInfoEntity> userAXQInfoEntityQueryWrapper = new QueryWrapper<>();
- userAXQInfoEntityQueryWrapper.eq("id_card",idCard).eq("nick_name",nickName);
- UserAXQInfoEntity userAXQInfoEntity = userAXQInfoMapper.selectOne(userAXQInfoEntityQueryWrapper);
- if (ObjectUtils.isEmpty(userAXQInfoEntity)){
- return ResultCode.PARAM_IS_INVALID;
- }
- //做过安心签的用户 直接人脸核身 保存图片
- ThirdPartyInterfaceEntity thirdPartyInterfaceEntity = JuheServiceUtil.URLPost(idCard, nickName, base64);
- File base = null;
- try {
- base = File.createTempFile("compare", ".jpeg");
- base.deleteOnExit();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- if (!Img2Base64Util.generateImage(base64, base.getPath())) {
- log.info("base64转图片异常");
- return ResultCode.FACEAUTH_FAIL;
- }
- FileInfoEntity fileInfo = saveCompareImage(base);
- fileInfoMapper.insert(fileInfo);
- thirdPartyInterfaceEntity.setFileId(fileInfo.getId()+"");
- thirdPartyInterfaceEntity.setBusinessNo(compareImageDomain.getBusinessNo());
- if (StringUtils.isNotBlank(thirdPartyInterfaceEntity.getMessage())){
- //没有message说明人脸核身成功
- UserAXQInfoEntity userAxq = new UserAXQInfoEntity();
- userAxq.setId(userAXQInfoEntity.getId());
- userAxq.setCompareImgId(fileInfo.getId());
- userAXQInfoMapper.updateById(userAxq);
- log.info("当事人人脸核身通过");
- thirdPartyInterfaceRepository.insert(thirdPartyInterfaceEntity);
- return ResultCode.SUCCESS;
- }
- thirdPartyInterfaceRepository.insert(thirdPartyInterfaceEntity);
- return ResultCode.LIVE_VIDEO_INVALID;
- }
- /**
- * 照片比对
- *
- * @param compareImageDomain
- * @return
- */
- public ResultCode compareFace(CompareImageDomain compareImageDomain) {
- String base64 = compareImageDomain.getBase64();
- if (base64==null){
- return ResultCode.PARAM_IS_BLANK;
- }
- base64 = getBase64(base64);
- //先判断是银行客户经理还是当事人
- String roleId = compareImageDomain.getRoleId();
- SysUserEntity sysUserEntity = null;
- UserAXQInfoEntity userAXQInfoEntity = null;
- String idCard = compareImageDomain.getIdCard();
- String nickName = compareImageDomain.getName();
- boolean flag = "-1".equals(roleId);
- if (flag) {
- //说明是银行客户经理
- QueryWrapper<ContractOrderEntity> contractOrderEntityQueryWrapper = new QueryWrapper<>();
- contractOrderEntityQueryWrapper.eq("business_no",compareImageDomain.getBusinessNo()).eq("customer_name",compareImageDomain.getName());
- ContractOrderEntity contractOrderEntity = contractOrderMapper.selectOne(contractOrderEntityQueryWrapper);
- if (ObjectUtils.isEmpty(contractOrderEntity)){
- return ResultCode.ACCOUNT_MANAGER_NO_ASSIGNED;
- }
- QueryWrapper<SysUserEntity> sysUserEntityQueryWrapper = new QueryWrapper<>();
- sysUserEntityQueryWrapper.eq("id_card", idCard).eq("nick_name", nickName);
- sysUserEntity = userMapper.selectOne(sysUserEntityQueryWrapper);
- } else {
- //说明是当事人
- QueryWrapper<UserAXQInfoEntity> userAXQInfoEntityQueryWrapper = new QueryWrapper<>();
- userAXQInfoEntityQueryWrapper.eq("id_card", idCard).eq("user_name", nickName);
- userAXQInfoEntity = userAXQInfoMapper.selectOne(userAXQInfoEntityQueryWrapper);
- }
- if (ObjectUtils.isEmpty(sysUserEntity) && ObjectUtils.isEmpty(userAXQInfoEntity)) {
- return ResultCode.PARAM_IS_INVALID;
- }
- //后面需要的三个参数 base64 身份证号 姓名
- String redisCount = "idCard:" + idCard + ":COUNT:";
- Integer count = null;
- if (redis.hasKey(redisCount)) {
- count = (Integer) redis.get(redisCount);
- System.err.println("redis存入次数" + count);
- }
- //将base64转成图片
- File base = null;
- try {
- base = File.createTempFile("compare", ".jpeg");
- base.deleteOnExit();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- if (!Img2Base64Util.generateImage(base64, base.getPath())) {
- log.info("base64转图片异常");
- return ResultCode.FACEAUTH_FAIL;
- }
- FileInfoEntity fileInfo = saveCompareImage(base);
- fileInfoMapper.insert(fileInfo);
- boolean redisFlag = (count != null && count >= 2);
- if (flag) {
- //说明是客户经理
- if (sysUserEntity.getCompareImgId() == null || redisFlag) {
- //说明客户经理需要做人脸核身
- ThirdPartyInterfaceEntity thirdPartyInterfaceEntity = JuheServiceUtil.URLPost(idCard, nickName, base64);
- thirdPartyInterfaceEntity.setFileId(fileInfo.getId()+"");
- thirdPartyInterfaceEntity.setBusinessNo(compareImageDomain.getBusinessNo());
- if (StringUtils.isNotBlank(thirdPartyInterfaceEntity.getMessage())){
- //上传图片到minio FileInfo
- SysUserEntity bank = new SysUserEntity();
- bank.setUserId(sysUserEntity.getUserId());
- bank.setCompareImgId(fileInfo.getId());
- userMapper.updateById(bank);
- log.info("银行客户经理人脸核身通过");
- redis.del(redisCount);
- thirdPartyInterfaceRepository.insert(thirdPartyInterfaceEntity);
- return ResultCode.SUCCESS;
- }
- log.info("客户经理人脸核身失败");
- thirdPartyInterfaceRepository.insert(thirdPartyInterfaceEntity);
- return ResultCode.LIVE_VIDEO_INVALID;
- }
- } else {
- //说明是当事人
- if (userAXQInfoEntity.getCompareImgId() == null || redisFlag) {
- //说明当事人需要做人脸核身
- ThirdPartyInterfaceEntity thirdPartyInterfaceEntity = JuheServiceUtil.URLPost(idCard, nickName, base64);
- thirdPartyInterfaceEntity.setFileId(fileInfo.getId()+"");
- thirdPartyInterfaceEntity.setBusinessNo(compareImageDomain.getBusinessNo());
- if (thirdPartyInterfaceEntity.getResult()==1){
- //上传图片到minio FileInfo
- UserAXQInfoEntity userAxq = new UserAXQInfoEntity();
- userAxq.setId(userAXQInfoEntity.getId());
- userAxq.setCompareImgId(fileInfo.getId());
- userAXQInfoMapper.updateById(userAxq);
- log.info("当事人人脸核身通过");
- redis.del(redisCount);
- thirdPartyInterfaceRepository.insert(thirdPartyInterfaceEntity);
- return ResultCode.SUCCESS;
- }
- log.info("当事人人脸核身失败");
- thirdPartyInterfaceRepository.insert(thirdPartyInterfaceEntity);
- return ResultCode.LIVE_VIDEO_INVALID;
- }
- }
- //如果不用做人脸核身 那么就去做照片比对
- //获取比较图片的id
- Integer id = null;
- if (!ObjectUtils.isEmpty(sysUserEntity)) {
- id = sysUserEntity.getCompareImgId();
- }
- if (!ObjectUtils.isEmpty(userAXQInfoEntity)) {
- id = userAXQInfoEntity.getCompareImgId();
- }
- if (! compareImage(base, id,redisCount,count)) {
- return ResultCode.LIVE_VIDEO_INVALID;
- }
- if (count != null) {
- redis.del(redisCount);
- }
- return ResultCode.SUCCESS;
- }
- /**
- * 虹软的人脸照片比对
- * @param base 照片
- * @param id 文件库中照片的id
- * @param redisCount 数据库中的键
- * @param count redis当中的次数
- * @return
- */
- public boolean compareImage(File base, Integer id,String redisCount,Integer count) {
- //从官网获取
- FaceEngine 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 engineConfiguration = new EngineConfiguration();
- engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
- engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
- engineConfiguration.setDetectFaceMaxNum(10);
- 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);
- //初始化引擎
- errorCode = faceEngine.init(engineConfiguration);
- if (errorCode != ErrorInfo.MOK.getValue()) {
- throw new RuntimeException("初始化引擎失败");
- }
- //人脸检测
- 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);
- //俯仰角
- float pitch = Math.abs(face3DAngleList.get(0).getPitch());
- //偏向角
- float yaw = Math.abs(face3DAngleList.get(0).getYaw());
- if (pitch > 10 || yaw > 10) {
- //照片不符合标准
- log.info("图片不符合标准");
- return false;
- }
- //特征提取
- 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 = minioFileHandle.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证明失败了
- if (faceSimilar.getScore() > 0.8) {
- log.info("人脸照片比对通过");
- return true;
- }
- if (count == null) {
- redis.set(redisCount, 1, 30, TimeUnit.MINUTES);
- } else {
- redis.set(redisCount, count + 1, 30, TimeUnit.MINUTES);
- }
- log.info("人脸照片比对未通过");;
- return false;
- }
- private FileInfoEntity saveCompareImage(File base) {
- FileHandleVo fileHandleVo = new FileHandleVo();
- fileHandleVo.setFilePath(base.getPath());
- fileHandleVo.setSourceFilePath("/face/" + base.getName());
- fileHandleVo.setContentType("image/jpeg");
- try {
- minioFileHandle.uploadfilePath(fileHandleVo);
- } catch (Exception e) {
- throw new RuntimeException("照片保存到minio异常");
- }
- FileInfoEntity fileInfo = new FileInfoEntity();
- fileInfo.setLoanNo("face");
- fileInfo.setFileName(base.getName());
- fileInfo.setPath(fileInfo.getLoanNo() + "/" + base.getName());
- return fileInfo;
- }
- }
|