You've already forked FrameTour-BE
feat(ai-cam): 增强AI摄像头人脸检测逻辑
- 引入时间范围限制配置,支持按分钟设置检测窗口 - 创建DetectResult内部类,记录人脸检测的分数和时间信息 - 优化照片筛选逻辑,先按分数排序再应用时间范围过滤 - 更新设备类型名称,将"微单"改为"AI微单" - 增强日志记录,提供更详细的调试信息
This commit is contained in:
@@ -81,8 +81,30 @@ public class AppAiCamServiceImpl implements AppAiCamService {
|
||||
}
|
||||
}
|
||||
|
||||
// 收集该设备符合阈值的faceSampleId
|
||||
List<Long> deviceFaceSampleIds = new ArrayList<>();
|
||||
// 获取该设备的时间范围限制(分钟)
|
||||
Integer timeRangeMin = null;
|
||||
if (configManager != null) {
|
||||
Integer range = configManager.getInteger("ai_cam_time_range_min");
|
||||
if (range != null && range > 0) {
|
||||
timeRangeMin = range;
|
||||
log.debug("设备{}使用配置的时间范围: {}分钟", deviceId, timeRangeMin);
|
||||
}
|
||||
}
|
||||
|
||||
// 收集该设备符合阈值的faceSampleId,同时记录分数和时间信息用于后续过滤
|
||||
class DetectResult {
|
||||
Long faceSampleId;
|
||||
Float score;
|
||||
Date detectTime;
|
||||
|
||||
DetectResult(Long faceSampleId, Float score, Date detectTime) {
|
||||
this.faceSampleId = faceSampleId;
|
||||
this.score = score;
|
||||
this.detectTime = detectTime;
|
||||
}
|
||||
}
|
||||
|
||||
List<DetectResult> detectResults = new ArrayList<>();
|
||||
for (FaceDetectLogAiCamEntity detectLog : deviceLogs) {
|
||||
if (detectLog.getMatchRawResult() == null) {
|
||||
continue;
|
||||
@@ -95,7 +117,11 @@ public class AppAiCamServiceImpl implements AppAiCamService {
|
||||
if (item.getScore() != null && item.getScore() >= scoreThreshold && item.getExtData() != null) {
|
||||
try {
|
||||
Long faceSampleId = Long.parseLong(item.getExtData());
|
||||
deviceFaceSampleIds.add(faceSampleId);
|
||||
detectResults.add(new DetectResult(
|
||||
faceSampleId,
|
||||
item.getScore(),
|
||||
detectLog.getCreateTime()
|
||||
));
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("解析faceSampleId失败: extData={}", item.getExtData());
|
||||
}
|
||||
@@ -108,10 +134,50 @@ public class AppAiCamServiceImpl implements AppAiCamService {
|
||||
}
|
||||
|
||||
// 应用照片数量限制(保留前N个)
|
||||
if (deviceFaceSampleIds.size() > photoLimit) {
|
||||
if (detectResults.size() > photoLimit) {
|
||||
log.debug("设备{}的照片数量{}超过限制{},截取前{}张",
|
||||
deviceId, deviceFaceSampleIds.size(), photoLimit, photoLimit);
|
||||
deviceFaceSampleIds = deviceFaceSampleIds.subList(0, photoLimit);
|
||||
deviceId, detectResults.size(), photoLimit, photoLimit);
|
||||
detectResults = detectResults.subList(0, photoLimit);
|
||||
}
|
||||
|
||||
// 应用时间范围限制
|
||||
List<Long> deviceFaceSampleIds;
|
||||
if (timeRangeMin != null && !detectResults.isEmpty()) {
|
||||
// 找到分数最高的照片
|
||||
DetectResult highestScoreResult = detectResults.stream()
|
||||
.max(Comparator.comparing(r -> r.score))
|
||||
.orElse(null);
|
||||
|
||||
if (highestScoreResult != null && highestScoreResult.detectTime != null) {
|
||||
Date baseTime = highestScoreResult.detectTime;
|
||||
long halfRangeMillis = (long) timeRangeMin * 60 * 1000 / 2;
|
||||
Date startTime = new Date(baseTime.getTime() - halfRangeMillis);
|
||||
Date endTime = new Date(baseTime.getTime() + halfRangeMillis);
|
||||
|
||||
// 过滤出时间范围内的照片
|
||||
List<DetectResult> filteredResults = detectResults.stream()
|
||||
.filter(r -> r.detectTime != null
|
||||
&& !r.detectTime.before(startTime)
|
||||
&& !r.detectTime.after(endTime))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
log.debug("设备{}应用时间范围{}分钟过滤: {}张 -> {}张 (基准时间: {})",
|
||||
deviceId, timeRangeMin, detectResults.size(), filteredResults.size(), baseTime);
|
||||
|
||||
deviceFaceSampleIds = filteredResults.stream()
|
||||
.map(r -> r.faceSampleId)
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
// 没有时间信息,不过滤
|
||||
deviceFaceSampleIds = detectResults.stream()
|
||||
.map(r -> r.faceSampleId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
} else {
|
||||
// 不限制时间范围
|
||||
deviceFaceSampleIds = detectResults.stream()
|
||||
.map(r -> r.faceSampleId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
if (!deviceFaceSampleIds.isEmpty()) {
|
||||
|
||||
@@ -128,7 +128,7 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
} else if (sourceType == 2) {
|
||||
goodsNamePrefix = "图片";
|
||||
} else if (sourceType == 3) {
|
||||
goodsNamePrefix = "微单";
|
||||
goodsNamePrefix = "AI微单";
|
||||
} else {
|
||||
goodsNamePrefix = "其他类型";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user