后台入口
@PostMapping("/detectFaces") @ResponseBody public AjaxResult faceDiscern(HttpServletRequest request,@RequestParam("file") String file) { //return Resp.ok(); faceEngineService.detectFaces(file,request); return success(); }
人脸识别比对
public SysUser detectFaces(String file, HttpServletRequest request) { try { // file 字符串转 file 流 byte[] decode = Base64.decode(Base64Util.base64Process(file)); // 人脸图像检测 ImageInfo imageInfo = getRGBData(decode); List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>(); errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList); log.info("人脸图像检测 ,faceInfoList: {} ,errorCode: {}", JSON.toJSONString(faceInfoList), errorCode); // 提取人脸特征 FaceFeature faceFeature = new FaceFeature(); errorCode = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature); log.info("提取人脸特征大小,getFeatureData: {} ,errorCode:{}", faceFeature.getFeatureData().length, errorCode); List<SysUser> allUser = userMapper.selectUserList(new SysUser()); if (!CollectionUtils.isEmpty(allUser)) { for (SysUser user : allUser) { if (Objects.isNull(user.getDetectFaces())) { continue; } FaceSimilar faceSimilar = new FaceSimilar(); errorCode = faceEngine.compareFaceFeature( getFaceFeatureInstance(faceFeature.getFeatureData()), getFaceFeatureInstance(user.getDetectFaces()), faceSimilar); log.info("相似度:{}", faceSimilar.getScore()); if (faceSimilar.getScore() >= score) { // user.setFirstLogin(false); UsernamePasswordToken token=new UsernamePasswordToken(); request.setAttribute(ShiroConstants.CAMERA, "true"); token = new UsernamePasswordToken(user.getLoginName(), user.getPassword()); Subject subject = SecurityUtils.getSubject(); subject.login(token); log.info("老用户"); return user; } } } /* SysUser newUser = createNewUser(faceFeature.getFeatureData()); newUser.setFirstLogin(true);*/ log.info("新用户"); return null; } catch (Exception e) { e.printStackTrace(); } return null; }
虹软初始化
@PostConstruct public void init() { faceEngine = new FaceEngine(path); /** * 激活引擎 */ int errorCode = faceEngine.activeOnline(appId, sdkKey); log.info("激活引擎 ,errorCode: {}", errorCode); if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) { log.error("引擎激活失败,errorCode: {}", errorCode); } ActiveFileInfo activeFileInfo = new ActiveFileInfo(); errorCode = faceEngine.getActiveFileInfo(activeFileInfo); if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) { log.error("获取激活文件信息失败 ,errorCode: {}", errorCode); } /** * 引擎配置 */ 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()) { log.error("初始化引擎失败 ,errorCode: {}", errorCode); } }
主要代码
package com.ruoyi.system.service.impl; import com.alibaba.fastjson.JSON; 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.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.constant.ShiroConstants; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.exception.file.InvalidExtensionException; import com.ruoyi.common.utils.file.Base64ToMultipartFile; import com.ruoyi.common.utils.file.FileUploadUtils; import com.ruoyi.common.utils.file.MimeTypeUtils; import com.ruoyi.system.mapper.SysUserMapper; import com.ruoyi.system.service.FaceEngineService; import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.util.Base64Util; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.codec.Base64; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.web.multipart.MultipartFile; import javax.annotation.PostConstruct; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Objects; import static com.arcsoft.face.toolkit.ImageFactory.getRGBData; import static com.ruoyi.common.core.domain.AjaxResult.error; import static com.ruoyi.common.core.domain.AjaxResult.success; @Slf4j @Component public class FaceEngineServiceImpl implements FaceEngineService { @Resource private SysUserMapper userMapper; @Value("${face.appId}") private String appId; @Value("${face.sdkKey}") private String sdkKey; @Value("${face.path}") private String path; @Value("${face.score}") private double score; public Integer errorCode; public FaceEngine faceEngine; @Autowired private ISysUserService userService; @PostConstruct public void init() { faceEngine = new FaceEngine(path); /** * 激活引擎 */ int errorCode = faceEngine.activeOnline(appId, sdkKey); log.info("激活引擎 ,errorCode: {}", errorCode); if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) { log.error("引擎激活失败,errorCode: {}", errorCode); } ActiveFileInfo activeFileInfo = new ActiveFileInfo(); errorCode = faceEngine.getActiveFileInfo(activeFileInfo); if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) { log.error("获取激活文件信息失败 ,errorCode: {}", errorCode); } /** * 引擎配置 */ 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()) { log.error("初始化引擎失败 ,errorCode: {}", errorCode); } } @Override public SysUser detectFaces(String file, HttpServletRequest request) { try { // file 字符串转 file 流 byte[] decode = Base64.decode(Base64Util.base64Process(file)); // 人脸图像检测 ImageInfo imageInfo = getRGBData(decode); List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>(); errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList); log.info("人脸图像检测 ,faceInfoList: {} ,errorCode: {}", JSON.toJSONString(faceInfoList), errorCode); // 提取人脸特征 FaceFeature faceFeature = new FaceFeature(); errorCode = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature); log.info("提取人脸特征大小,getFeatureData: {} ,errorCode:{}", faceFeature.getFeatureData().length, errorCode); List<SysUser> allUser = userMapper.selectUserList(new SysUser()); if (!CollectionUtils.isEmpty(allUser)) { for (SysUser user : allUser) { if (Objects.isNull(user.getDetectFaces())) { continue; } FaceSimilar faceSimilar = new FaceSimilar(); errorCode = faceEngine.compareFaceFeature( getFaceFeatureInstance(faceFeature.getFeatureData()), getFaceFeatureInstance(user.getDetectFaces()), faceSimilar); log.info("相似度:{}", faceSimilar.getScore()); if (faceSimilar.getScore() >= score) { // user.setFirstLogin(false); UsernamePasswordToken token=new UsernamePasswordToken(); request.setAttribute(ShiroConstants.CAMERA, "true"); token = new UsernamePasswordToken(user.getLoginName(), user.getPassword()); Subject subject = SecurityUtils.getSubject(); subject.login(token); log.info("老用户"); return user; } } } /* SysUser newUser = createNewUser(faceFeature.getFeatureData()); newUser.setFirstLogin(true);*/ log.info("新用户"); return null; } catch (Exception e) { e.printStackTrace(); } return null; } /* *//** * 人脸识别后-创建新用户 * * @param detectFaces * @return *//* public SysUser createNewUser(byte[] detectFaces) { SysUser currentUser = new SysUser(); currentUser.setGender(getGender()); currentUser.setUserName("火书网友"); currentUser.setAvatarPath("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fblog%2F201612%2F02%2F20161202182753_ViyLX.thumb.700_0.png&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1638539316&t=3725638b9"); currentUser.setDetectFaces(detectFaces); currentUser.setFirstLogin(true); currentUser = userDao.save(currentUser); return currentUser; }*/ /** * 检测性别 * * @return */ public Integer getGender() { List<GenderInfo> genderInfoList = new ArrayList<>(); errorCode = faceEngine.getGender(genderInfoList); if (!CollectionUtils.isEmpty(genderInfoList)) { log.info("性别:{} ,errorCode: {}", genderInfoList.get(0).getGender(), errorCode); return genderInfoList.get(0).getGender(); } return -1; } public FaceFeature getFaceFeatureInstance(byte[] detectFaces) { FaceFeature faceFeature = new FaceFeature(); faceFeature.setFeatureData(detectFaces); return faceFeature; } @Override public byte[] updateUserFaces(MultipartFile file) { try { // file 字符串转 file 流 byte[] decode = file.getBytes(); // 人脸图像检测 ImageInfo imageInfo = getRGBData(decode); List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>(); errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList); log.info("人脸图像检测 ,faceInfoList: {} ,errorCode: {}", JSON.toJSONString(faceInfoList), errorCode); // 提取人脸特征 FaceFeature faceFeature = new FaceFeature(); errorCode = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature); log.info("提取人脸特征大小,getFeatureData: {} ,errorCode:{}", faceFeature.getFeatureData().length, errorCode); /* SysUser newUser = createNewUser(faceFeature.getFeatureData()); newUser.setFirstLogin(true);*/ log.info("获取人像信息成功"); return faceFeature.getFeatureData(); } catch (Exception e) { e.printStackTrace(); } return null; } @Override public AjaxResult takePhoto(String file, HttpServletRequest request) throws IOException, InvalidExtensionException { // file 字符串转 file 流 String userId=request.getParameter("userId"); SysUser currentUser = userService.selectUserById(Long.parseLong(userId)); MultipartFile files=Base64ToMultipartFile.base64Convert(file); String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), files, MimeTypeUtils.IMAGE_EXTENSION); currentUser.setAvatar(avatar); if (userService.updateUserInfo(currentUser) > 0) { return success(); } return error(); } }