From bf672a8af781ba79cf0ca2260cf85efe617f32dc Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Sat, 13 Sep 2025 15:04:06 +0800 Subject: [PATCH] =?UTF-8?q?feat(face):=20=E6=B7=BB=E5=8A=A0=E4=BD=8E?= =?UTF-8?q?=E9=98=88=E5=80=BC=E6=A3=80=E6=B5=8B=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 FaceConstant 中添加 FACE_LOW_THRESHOLD_PFX 常量 - 在 SearchFaceRespVo 中添加 lowThreshold 字段 - 在 FaceServiceImpl 中实现记录低阈值检测人脸的逻辑 - 在 TaskFaceServiceImpl 中添加低阈值检测的判断和结果设置 --- .../com/ycwl/basic/constant/FaceConstant.java | 1 + .../model/task/resp/SearchFaceRespVo.java | 1 + .../service/pc/impl/FaceServiceImpl.java | 31 +++++++++++++++++++ .../task/impl/TaskFaceServiceImpl.java | 11 +++++++ 4 files changed, 44 insertions(+) diff --git a/src/main/java/com/ycwl/basic/constant/FaceConstant.java b/src/main/java/com/ycwl/basic/constant/FaceConstant.java index 3ec9c34a..88107c28 100644 --- a/src/main/java/com/ycwl/basic/constant/FaceConstant.java +++ b/src/main/java/com/ycwl/basic/constant/FaceConstant.java @@ -5,4 +5,5 @@ public class FaceConstant { public static final String USER_FACE_DB_NAME="userFace"; public static final String FACE_USER_URL_PFX="face:user:url:"; public static final String FACE_RECOGNITION_COUNT_PFX="face:recognition:count:"; + public static final String FACE_LOW_THRESHOLD_PFX="face:low:threshold:"; } diff --git a/src/main/java/com/ycwl/basic/model/task/resp/SearchFaceRespVo.java b/src/main/java/com/ycwl/basic/model/task/resp/SearchFaceRespVo.java index 2c98e6a5..d590f119 100644 --- a/src/main/java/com/ycwl/basic/model/task/resp/SearchFaceRespVo.java +++ b/src/main/java/com/ycwl/basic/model/task/resp/SearchFaceRespVo.java @@ -10,4 +10,5 @@ public class SearchFaceRespVo { private List sampleListIds; private String searchResultJson; private Float firstMatchRate; + private boolean lowThreshold; } diff --git a/src/main/java/com/ycwl/basic/service/pc/impl/FaceServiceImpl.java b/src/main/java/com/ycwl/basic/service/pc/impl/FaceServiceImpl.java index 9747197b..351bf714 100644 --- a/src/main/java/com/ycwl/basic/service/pc/impl/FaceServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/pc/impl/FaceServiceImpl.java @@ -69,6 +69,7 @@ import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import static com.ycwl.basic.constant.FaceConstant.FACE_LOW_THRESHOLD_PFX; import static com.ycwl.basic.constant.FaceConstant.FACE_RECOGNITION_COUNT_PFX; import static com.ycwl.basic.constant.FaceConstant.USER_FACE_DB_NAME; import static com.ycwl.basic.constant.StorageConstant.USER_FACE; @@ -333,6 +334,12 @@ public class FaceServiceImpl implements FaceService { } } else { log.warn("人脸匹配无结果:faceId={}", faceId); + + // 检查低阈值检测结果,如果为true则记录该人脸ID到Redis + if (scenicDbSearchResult != null && scenicDbSearchResult.isLowThreshold()) { + recordLowThresholdFace(faceId); + log.debug("触发低阈值检测,记录faceId: {}", faceId); + } } return scenicDbSearchResult; @@ -835,4 +842,28 @@ public class FaceServiceImpl implements FaceService { log.error("记录人脸识别次数失败:faceId={}", faceId, e); } } + + /** + * 记录低阈值检测的人脸ID到Redis + * + * @param faceId 人脸ID + */ + private void recordLowThresholdFace(Long faceId) { + if (faceId == null) { + return; + } + + try { + String redisKey = FACE_LOW_THRESHOLD_PFX + faceId; + + // 设置标记,表示该人脸ID触发了低阈值检测 + redisTemplate.opsForValue().set(redisKey, "1", 2, TimeUnit.DAYS); + + log.debug("记录低阈值检测人脸:faceId={}", faceId); + + } catch (Exception e) { + // 记录失败不应影响主要业务逻辑,只记录错误日志 + log.error("记录低阈值检测人脸失败:faceId={}", faceId, e); + } + } } diff --git a/src/main/java/com/ycwl/basic/service/task/impl/TaskFaceServiceImpl.java b/src/main/java/com/ycwl/basic/service/task/impl/TaskFaceServiceImpl.java index 4d32ddad..5da5d8a4 100644 --- a/src/main/java/com/ycwl/basic/service/task/impl/TaskFaceServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/task/impl/TaskFaceServiceImpl.java @@ -171,6 +171,7 @@ public class TaskFaceServiceImpl implements TaskFaceService { request.setLimit(200); FaceDetectLog logEntity = FaceDetectLog.quickCreate(reason, request); float threshold = 0; + float lowThreshold = 100; ScenicConfigManager scenicConfig = null; if (StringUtils.isNumeric(dbName)) { scenicConfig = scenicRepository.getScenicConfigManager(Long.valueOf(dbName)); @@ -178,6 +179,9 @@ public class TaskFaceServiceImpl implements TaskFaceService { if (scenicConfig.getFloat("face_score_threshold") != null) { threshold = scenicConfig.getFloat("face_score_threshold") / 100F; } + if (scenicConfig.getFloat("face_score_low_threshold") != null) { + lowThreshold = scenicConfig.getFloat("face_score_low_threshold") / 100F; + } } } else if (StringUtils.isNumeric(dbName.replace(USER_FACE_DB_NAME, ""))) { Long scenicId = Long.valueOf(dbName.replace(USER_FACE_DB_NAME, "")); @@ -186,6 +190,9 @@ public class TaskFaceServiceImpl implements TaskFaceService { if (scenicConfig.getFloat("face_score_threshold") != null) { threshold = scenicConfig.getFloat("face_score_threshold") / 100F; } + if (scenicConfig.getFloat("face_score_low_threshold") != null) { + lowThreshold = scenicConfig.getFloat("face_score_low_threshold") / 100F; + } } } final float _threshold = threshold; @@ -212,6 +219,10 @@ public class TaskFaceServiceImpl implements TaskFaceService { .filter(StringUtils::isNumeric) .map(Long::valueOf) .collect(Collectors.toList()); + float _lowThreshold = lowThreshold; + boolean isLowThreshold = records.stream() + .anyMatch(record -> record.getScore() > _lowThreshold); + respVo.setLowThreshold(isLowThreshold); allFaceSampleIds = records.stream() .map(SearchFaceResultItem::getExtData) .filter(StringUtils::isNumeric)