Просмотр исходного кода

人脸识别修复,增加移除人脸和更新人脸操作。

wukai 1 год назад
Родитель
Сommit
89935e435e

+ 1 - 1
doc-admin/src/main/java/com/doc/web/controller/system/SysLoginController.java

@@ -127,7 +127,7 @@ public class SysLoginController {
     }
 
     @ApiOperation("人脸识别")
-    @PostMapping("/face-login")
+    @PostMapping("/face-login-file")
     public AjaxResult face(@RequestParam("file") MultipartFile file) throws Exception {
         String originalFilename = file.getOriginalFilename();
         String[] filename = originalFilename.split("\\.");

+ 1 - 1
doc-admin/src/main/java/com/doc/web/controller/system/SysProfileController.java

@@ -144,7 +144,7 @@ public class SysProfileController extends BaseController {
                 String localPath = RuoYiConfig.getProfile();
                 // 数据库资源地址
                 String path = localPath + StringUtils.substringAfter(avatar, Constants.RESOURCE_PREFIX);
-                boolean flag = faceService.detectFaces(new File(path));
+                boolean flag = faceService.detectFaces(SecurityUtils.getUserId(), new File(path));
                 tokenService.setLoginUser(loginUser);
                 ajax.put("face", flag);
                 return ajax;

+ 2 - 1
doc-biz/src/main/java/com/doc/face/service/IFaceService.java

@@ -14,10 +14,11 @@ public interface IFaceService {
     /**
      * 人脸检测
      *
+     * @param userId 用户ID
      * @param file 人脸图片
      * @return 返回是否检测到人脸
      */
-    boolean detectFaces(File file);
+    boolean detectFaces(Long userId, File file);
 
     /**
      * 人脸匹配

+ 54 - 35
doc-biz/src/main/java/com/doc/face/service/impl/FaceServiceImpl.java

@@ -6,7 +6,6 @@ import com.arcsoft.face.enums.ExtractType;
 import com.arcsoft.face.toolkit.ImageFactory;
 import com.arcsoft.face.toolkit.ImageInfo;
 import com.doc.common.core.domain.entity.SysUserExpand;
-import com.doc.common.utils.SecurityUtils;
 import com.doc.common.utils.sign.Base64;
 import com.doc.face.init.FaceEngineInit;
 import com.doc.face.service.IFaceService;
@@ -15,7 +14,6 @@ import com.doc.system.service.ISysUserExpandService;
 import javafx.util.Pair;
 import org.springframework.stereotype.Service;
 
-import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
 import java.io.File;
 import java.util.ArrayList;
@@ -34,40 +32,61 @@ public class FaceServiceImpl implements IFaceService {
     @Resource
     private ISysUserExpandService expandService;
 
-    private FaceEngine faceEngine;
-    private Boolean faceEnabled;
+    /**
+     * 获取face引擎
+     *
+     * @return engine
+     */
+    private FaceEngine faceEngine() {
+        return faceEngineInit.getFaceEngine();
+    }
 
-    private Float score;
+    /**
+     * 获取是否开启人脸识别
+     *
+     * @return true/false
+     */
+    private Boolean faceEnabled() {
+        return faceEngineInit.getFaceEnabled();
+    }
 
-    @PostConstruct
-    public void init() {
-        faceEngine = faceEngineInit.getFaceEngine();
-        faceEnabled = faceEngineInit.getFaceEnabled();
-        score = faceEngineInit.getScore();
+    /**
+     * 获取相似度分数标准
+     *
+     * @return score
+     */
+    private Float score() {
+        return faceEngineInit.getScore();
     }
 
     /**
      * 人脸检测
      *
-     * @param file 人脸图片
+     * @param userId 用户ID
+     * @param file   人脸图片
      * @return 返回是否检测到人脸
      */
     @Override
-    public boolean detectFaces(File file) {
-        if (!faceEnabled) {
+    public boolean detectFaces(Long userId, File file) {
+        if (!faceEnabled()) {
             return false;
         }
+        boolean res = true;
+        SysUserExpand expand = new SysUserExpand();
+        expand.setUserId(userId);
+        //不管有没有,先删了再说
+        FaceEngineUtil.removeFaceFeature(faceEngine(), userId);
         byte[] featureData = faceFeature(file);
         if (featureData != null) {
             String feature = Base64.encode(featureData);
-            SysUserExpand expand = new SysUserExpand();
-            expand.setUserId(SecurityUtils.getUserId());
             expand.setFaceFeature(feature);
-            expandService.updateSysUserExpand(expand);
-            FaceEngineUtil.registerFaceFeature(faceEngine, expand);
-            return true;
+            FaceEngineUtil.registerFaceFeature(faceEngine(), expand);
+        } else {
+            expand.setFaceFeature("");
+            res = false;
         }
-        return false;
+        expandService.updateSysUserExpand(expand);
+        return res;
     }
 
     /**
@@ -77,18 +96,18 @@ public class FaceServiceImpl implements IFaceService {
      * @return 特征值
      */
     private byte[] faceFeature(File file) {
-        if (!faceEnabled) {
+        if (!faceEnabled()) {
             return null;
         }
         ImageInfo imageInfo = ImageFactory.getRGBData(file);
         List<FaceInfo> faceInfoList = new ArrayList<>();
-        faceEngine.detectFaces(imageInfo, faceInfoList);
+        faceEngine().detectFaces(imageInfo, faceInfoList);
 
         if (faceInfoList.size() == 1) {
             //有且只有一个人脸信息时才提取特征值
             //提取特征值
             FaceFeature faceFeature = new FaceFeature();
-            faceEngine.extractFaceFeature(imageInfo, faceInfoList.get(0), ExtractType.REGISTER, 0, faceFeature);
+            faceEngine().extractFaceFeature(imageInfo, faceInfoList.get(0), ExtractType.REGISTER, 0, faceFeature);
             return faceFeature.getFeatureData();
         } else {
             return null;
@@ -103,7 +122,7 @@ public class FaceServiceImpl implements IFaceService {
      */
     @Override
     public Pair<Long, Float> searchFaces(File file) {
-        if (!faceEnabled) {
+        if (!faceEnabled()) {
             return null;
         }
         byte[] featureData = faceFeature(file);
@@ -111,18 +130,18 @@ public class FaceServiceImpl implements IFaceService {
             FaceFeature faceFeature = new FaceFeature();
             faceFeature.setFeatureData(featureData);
             SearchResult searchResult = new SearchResult();
-            faceEngine.searchFaceFeature(faceFeature, CompareModel.LIFE_PHOTO, searchResult);
-            int userId = searchResult.getFaceFeatureInfo().getSearchId();
-
-            //特征比对
-            FaceSimilar faceSimilar = new FaceSimilar();
-            FaceFeature targetFace = new FaceFeature();
-            targetFace.setFeatureData(searchResult.getFaceFeatureInfo().getFeatureData());
-            faceEngine.compareFaceFeature(faceFeature, targetFace, faceSimilar);
-            return new Pair<>((long) userId, faceSimilar.getScore());
-        } else {
-            return null;
+            faceEngine().searchFaceFeature(faceFeature, CompareModel.LIFE_PHOTO, searchResult);
+            if (searchResult.getFaceFeatureInfo() != null) {
+                int userId = searchResult.getFaceFeatureInfo().getSearchId();
+                //特征比对
+                FaceSimilar faceSimilar = new FaceSimilar();
+                FaceFeature targetFace = new FaceFeature();
+                targetFace.setFeatureData(searchResult.getFaceFeatureInfo().getFeatureData());
+                faceEngine().compareFaceFeature(faceFeature, targetFace, faceSimilar);
+                return new Pair<>((long) userId, faceSimilar.getScore());
+            }
         }
+        return null;
     }
 
     /**
@@ -134,7 +153,7 @@ public class FaceServiceImpl implements IFaceService {
     @Override
     public Long faceLogin(File upFile) {
         Pair<Long, Float> pair = searchFaces(upFile);
-        if (pair != null && pair.getValue() > score) {
+        if (pair != null && pair.getValue() > score()) {
             return pair.getKey();
         } else {
             return 0L;

+ 31 - 0
doc-biz/src/main/java/com/doc/face/util/FaceEngineUtil.java

@@ -12,6 +12,12 @@ import com.doc.common.utils.sign.Base64;
  * @date 2024/3/15 17:43
  */
 public class FaceEngineUtil {
+    /**
+     * 注册人脸信息
+     *
+     * @param faceEngine 引擎
+     * @param expand     用户信息
+     */
     public static void registerFaceFeature(FaceEngine faceEngine, SysUserExpand expand) {
         FaceFeatureInfo faceFeatureInfo = new FaceFeatureInfo();
         faceFeatureInfo.setSearchId(expand.getUserId().intValue());
@@ -20,4 +26,29 @@ public class FaceEngineUtil {
         faceFeatureInfo.setFeatureData(Base64.decode(feature));
         faceEngine.registerFaceFeature(faceFeatureInfo);
     }
+
+    /**
+     * 更新人脸信息
+     *
+     * @param faceEngine 引擎
+     * @param expand     用户信息
+     */
+    public static void updateFaceFeature(FaceEngine faceEngine, SysUserExpand expand) {
+        FaceFeatureInfo faceFeatureInfo = new FaceFeatureInfo();
+        faceFeatureInfo.setSearchId(expand.getUserId().intValue());
+        faceFeatureInfo.setFaceTag(expand.getRemark());
+        String feature = expand.getFaceFeature();
+        faceFeatureInfo.setFeatureData(Base64.decode(feature));
+        faceEngine.updateFaceFeature(faceFeatureInfo);
+    }
+
+    /**
+     * 移除人脸信息
+     *
+     * @param userId 用户ID
+     */
+    public static void removeFaceFeature(FaceEngine faceEngine, Long userId) {
+        int searchId = userId.intValue();
+        faceEngine.removeFaceFeature(searchId);
+    }
 }

+ 12 - 0
doc-common/src/main/java/com/doc/common/core/domain/entity/SysUserExpand.java

@@ -1,7 +1,9 @@
 package com.doc.common.core.domain.entity;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.doc.common.core.domain.BaseEntity;
+import com.doc.common.utils.StringUtils;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 
@@ -42,4 +44,14 @@ public class SysUserExpand extends BaseEntity {
      * 人脸特征值
      */
     private String faceFeature;
+    /**
+     * 支持人脸登录
+     */
+    @TableField(exist = false)
+    private String faceEnable;
+
+    public void setFaceFeature(String faceFeature) {
+        this.faceFeature = faceFeature;
+        faceEnable = StringUtils.isNotEmpty(this.faceFeature) ? "是" : "否";
+    }
 }

+ 7 - 1
doc-system/src/main/java/com/doc/system/mapper/SysUserExpandMapper.java

@@ -66,5 +66,11 @@ public interface SysUserExpandMapper extends BaseMapper<SysUserExpand> {
      * @return 结果
      */
     public int deleteSysUserExpandByUserIds(Long[] userIds);
-
+    /**
+     * 修改用户人脸信息
+     *
+     * @param expand 扩展信息
+     * @return 结果
+     */
+    int updateFaceFeature(SysUserExpand expand);
 }

+ 9 - 2
doc-system/src/main/java/com/doc/system/service/ISysUserExpandService.java

@@ -10,8 +10,7 @@ import java.util.List;
  * @author wukai
  * @date 2023-10-11
  */
-public interface ISysUserExpandService
-{
+public interface ISysUserExpandService {
     /**
      * 查询用户登录限制
      *
@@ -47,6 +46,14 @@ public interface ISysUserExpandService
     public int updateSysUserExpand(SysUserExpand sysUserExpand);
 
     /**
+     * 修改用户人脸信息
+     *
+     * @param expand 扩展信息
+     * @return 结果
+     */
+    public int updateFaceFeature(SysUserExpand expand);
+
+    /**
      * 批量删除用户登录限制
      *
      * @param userIds 需要删除的用户登录限制主键集合

+ 20 - 1
doc-system/src/main/java/com/doc/system/service/impl/SysUserExpandServiceImpl.java

@@ -70,7 +70,7 @@ public class SysUserExpandServiceImpl implements ISysUserExpandService {
      */
     @Override
     public int updateSysUserExpand(SysUserExpand sysUserExpand) {
-        SysUserExpand u = sysUserExpandMapper.selectSysUserExpandByUserId(sysUserExpand.getUserId());
+        SysUserExpand u = selectSysUserExpandByUserId(sysUserExpand.getUserId());
         /**
          * 查询用户扩展信息是否存在,如果不存在则创建
          */
@@ -82,6 +82,25 @@ public class SysUserExpandServiceImpl implements ISysUserExpandService {
     }
 
     /**
+     * 修改用户人脸信息
+     *
+     * @param expand 扩展信息
+     * @return 结果
+     */
+    @Override
+    public int updateFaceFeature(SysUserExpand expand) {
+        SysUserExpand u = selectSysUserExpandByUserId(expand.getUserId());
+        /**
+         * 查询用户扩展信息是否存在,如果不存在则创建
+         */
+        if (u != null) {
+            return sysUserExpandMapper.updateFaceFeature(expand);
+        } else {
+            return sysUserExpandMapper.insertSysUserExpand(expand);
+        }
+    }
+
+    /**
      * 批量删除用户登录限制
      *
      * @param userIds 需要删除的用户登录限制主键

+ 15 - 7
doc-system/src/main/resources/mapper/system/SysUserExpandMapper.xml

@@ -13,8 +13,11 @@
     </resultMap>
 
     <sql id="selectSysUserExpandVo">
-        select USER_ID, LAST_UPDATE_TIME, LOGIN_IP, LOGIN_TIME, FACE_FEATURE
-        from sys_user_expand
+        select *
+        from (select a.USER_ID, a.LAST_UPDATE_TIME, a.LOGIN_IP, a.LOGIN_TIME, a.FACE_FEATURE, b.nick_name remark
+              from sys_user_expand a,
+                   sys_user b
+              where a.user_id = b.user_id) a
     </sql>
 
     <select id="selectSysUserExpandList" parameterType="SysUserExpand" resultMap="SysUserExpandResult">
@@ -31,11 +34,8 @@
         where USER_ID = #{userId}
     </select>
     <select id="selectFaceFeatureList" resultType="com.doc.common.core.domain.entity.SysUserExpand">
-        select a.USER_ID, a.LAST_UPDATE_TIME, a.LOGIN_IP, a.LOGIN_TIME, a.FACE_FEATURE, b.nick_name remark
-        from sys_user_expand a,
-             sys_user b
-        where a.user_id = b.user_id
-          and a.face_feature is not null
+        <include refid="selectSysUserExpandVo"/>
+        where a.face_feature is not null
     </select>
 
     <insert id="insertSysUserExpand" parameterType="SysUserExpand">
@@ -67,6 +67,14 @@
         where USER_ID = #{userId}
     </update>
 
+    <update id="updateFaceFeature" parameterType="SysUserExpand">
+        update sys_user_expand
+        <trim prefix="SET" suffixOverrides=",">
+            FACE_FEATURE = #{faceFeature},
+        </trim>
+        where USER_ID = #{userId}
+    </update>
+
     <delete id="deleteSysUserExpandByUserId" parameterType="Long">
         delete
         from sys_user_expand