This commit is contained in:
Jerry Yan 2025-02-10 20:45:45 +08:00
parent a6157ddad8
commit 958dc05836
8 changed files with 55 additions and 7 deletions

View File

@ -13,4 +13,5 @@ public class MatchLocalRecord {
private Float confidence; private Float confidence;
private String idStr; private String idStr;
private Date shotDate; private Date shotDate;
private Boolean matched;
} }

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
/** /**
@ -60,4 +61,8 @@ public class ScenicConfigEntity {
private Integer videoSourceStoreDay; private Integer videoSourceStoreDay;
private Integer imageSourceStoreDay; private Integer imageSourceStoreDay;
private Integer userSourceExpireDay; private Integer userSourceExpireDay;
/**
* 人脸识别阈值是0~100的数值
*/
private Float faceScoreThreshold;
} }

View File

@ -15,6 +15,7 @@ import com.ycwl.basic.model.mobile.statistic.req.StatisticsRecordAddReq;
import com.ycwl.basic.model.pc.face.entity.FaceEntity; import com.ycwl.basic.model.pc.face.entity.FaceEntity;
import com.ycwl.basic.model.pc.face.req.FaceReqQuery; import com.ycwl.basic.model.pc.face.req.FaceReqQuery;
import com.ycwl.basic.model.pc.face.resp.FaceRespVO; import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity;
import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity; import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity;
import com.ycwl.basic.model.pc.source.entity.SourceEntity; import com.ycwl.basic.model.pc.source.entity.SourceEntity;
import com.ycwl.basic.model.task.resp.SearchFaceRespVo; import com.ycwl.basic.model.task.resp.SearchFaceRespVo;
@ -129,7 +130,7 @@ public class FaceServiceImpl implements FaceService {
String faceUrl = adapter.uploadFile(file, filePath, fileName); String faceUrl = adapter.uploadFile(file, filePath, fileName);
Long newFaceId = SnowFlakeUtil.getLongId(); Long newFaceId = SnowFlakeUtil.getLongId();
Long oldFaceId = null; Long oldFaceId = null;
SearchFaceRespVo userDbSearchResult = faceService.searchFace(USER_FACE_DB_NAME+scenicId, faceUrl); SearchFaceRespVo userDbSearchResult = faceService.searchFace(USER_FACE_DB_NAME+scenicId, faceUrl, "判断是否为用户上传过的人脸");
float strictScore = 0.6F; float strictScore = 0.6F;
if (userDbSearchResult == null) { if (userDbSearchResult == null) {
// 都是null了那得是新的 // 都是null了那得是新的
@ -203,6 +204,27 @@ public class FaceServiceImpl implements FaceService {
return null; return null;
} }
SearchFaceRespVo scenicDbSearchResult = faceService.searchFace(face.getScenicId(), face.getFaceUrl()); SearchFaceRespVo scenicDbSearchResult = faceService.searchFace(face.getScenicId(), face.getFaceUrl());
// 写死逻辑
if (scenicDbSearchResult.getSampleListIds() != null && scenicDbSearchResult.getFirstMatchRate() != null && !scenicDbSearchResult.getSampleListIds().isEmpty()) {
if (scenicDbSearchResult.getSampleListIds().size() < 2) {
// 补救逻辑
Long faceSampleId = scenicDbSearchResult.getSampleListIds().get(0);
FaceSampleEntity faceSample = faceRepository.getFaceSample(faceSampleId);
if (faceSample != null) {
// 以这个结果为人脸库的匹配结果
scenicDbSearchResult = faceService.searchFace(face.getScenicId().toString(), faceSample.getFaceUrl(), "补救措施1人脸数太少只有一张");
}
} else if (scenicDbSearchResult.getFirstMatchRate() > 0.75 && scenicDbSearchResult.getSampleListIds().size() < 2) {
// 如果匹配度高于阈值则使用景区第一张人脸去匹配景区库
// 找第一张人脸
Long faceSampleId = scenicDbSearchResult.getSampleListIds().get(0);
FaceSampleEntity faceSample = faceRepository.getFaceSample(faceSampleId);
if (faceSample != null) {
// 以这个结果为人脸库的匹配结果
scenicDbSearchResult = faceService.searchFace(face.getScenicId().toString(), faceSample.getFaceUrl(), "补救措施2存在得分够高但是结果少");
}
}
}
FaceEntity faceEntity = new FaceEntity(); FaceEntity faceEntity = new FaceEntity();
faceEntity.setId(faceId); faceEntity.setId(faceId);
faceEntity.setScore(scenicDbSearchResult.getScore()); faceEntity.setScore(scenicDbSearchResult.getScore());

View File

@ -13,6 +13,8 @@ public interface TaskFaceService {
SearchFaceRespVo searchFace(String dbName, String faceUrl); SearchFaceRespVo searchFace(String dbName, String faceUrl);
SearchFaceRespVo searchFace(String dbName, String faceUrl, String reason);
AddFaceSampleRespVo addFaceSample(Long faceSampleId); AddFaceSampleRespVo addFaceSample(Long faceSampleId);
AddFaceSampleRespVo addFaceSample(String dbName, String entityId, String faceUrl, String extData); AddFaceSampleRespVo addFaceSample(String dbName, String entityId, String faceUrl, String extData);

View File

@ -117,7 +117,7 @@ public class TaskFaceServiceImpl implements TaskFaceService {
return vo; return vo;
} }
Long scenicId = faceRespVO.getScenicId(); Long scenicId = faceRespVO.getScenicId();
SearchFaceRespVo respVo = searchFace(scenicId.toString(), faceRespVO.getFaceUrl()); SearchFaceRespVo respVo = searchFace(scenicId.toString(), faceRespVO.getFaceUrl(), "系统定时任务检索");
if (respVo != null) { if (respVo != null) {
FaceEntity faceEntity = new FaceEntity(); FaceEntity faceEntity = new FaceEntity();
faceEntity.setId(faceId); faceEntity.setId(faceId);
@ -162,11 +162,16 @@ public class TaskFaceServiceImpl implements TaskFaceService {
@Override @Override
public SearchFaceRespVo searchFace(Long scenicId, String faceUrl) { public SearchFaceRespVo searchFace(Long scenicId, String faceUrl) {
return searchFace(scenicId.toString(), faceUrl); return searchFace(scenicId.toString(), faceUrl, "预留字段");
} }
@Override @Override
public SearchFaceRespVo searchFace(String dbName, String faceUrl) { public SearchFaceRespVo searchFace(String dbName, String faceUrl) {
return searchFace(dbName, faceUrl, "预留字段");
}
@Override
public SearchFaceRespVo searchFace(String dbName, String faceUrl, String reason) {
assureFaceDB(dbName); assureFaceDB(dbName);
IAcsClient client = getClient(); IAcsClient client = getClient();
SearchFaceRequest request = new SearchFaceRequest(); SearchFaceRequest request = new SearchFaceRequest();
@ -174,11 +179,21 @@ public class TaskFaceServiceImpl implements TaskFaceService {
request.setImageUrl(faceUrl); request.setImageUrl(faceUrl);
request.setLimit(100); request.setLimit(100);
// request.setQualityScoreThreshold(60f); // request.setQualityScoreThreshold(60f);
FaceDetectLog log = FaceDetectLog.quickCreate("预留字段", request); FaceDetectLog log = FaceDetectLog.quickCreate(reason, request);
try { try {
searchFaceLimiter.acquire(); searchFaceLimiter.acquire();
} catch (InterruptedException ignored) { } catch (InterruptedException ignored) {
} }
float threshold = 0.525F;
if (StringUtils.isNumeric(dbName)) {
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(Long.valueOf(dbName));
if (scenicConfig != null) {
if (scenicConfig.getFaceScoreThreshold() != null) {
threshold = scenicConfig.getFaceScoreThreshold() / 100F;
}
}
}
final float _threshold = threshold;
try { try {
SearchFaceResponse response = client.getAcsResponse(request); SearchFaceResponse response = client.getAcsResponse(request);
log.fillResponse(response); log.fillResponse(response);
@ -195,7 +210,7 @@ public class TaskFaceServiceImpl implements TaskFaceService {
List<SearchFaceResponse.Data.MatchListItem.FaceItemsItem> records = matchList.get(0).getFaceItems(); List<SearchFaceResponse.Data.MatchListItem.FaceItemsItem> records = matchList.get(0).getFaceItems();
log.setMatchRawRecord(records); log.setMatchRawRecord(records);
List<Long> faceSampleIds = records.stream() List<Long> faceSampleIds = records.stream()
.filter(record -> record.getScore() > 0.525F) .filter(record -> record.getScore() > _threshold)
.map(SearchFaceResponse.Data.MatchListItem.FaceItemsItem::getExtraData) .map(SearchFaceResponse.Data.MatchListItem.FaceItemsItem::getExtraData)
.filter(StringUtils::isNumeric) .filter(StringUtils::isNumeric)
.map(Long::valueOf) .map(Long::valueOf)
@ -205,7 +220,6 @@ public class TaskFaceServiceImpl implements TaskFaceService {
return respVo; return respVo;
} catch (Exception e) { } catch (Exception e) {
log.setMatchRawResult("识别错误,错误为:["+e.getLocalizedMessage()+"]"); log.setMatchRawResult("识别错误,错误为:["+e.getLocalizedMessage()+"]");
e.printStackTrace();
throw new BaseException(e.getMessage()); throw new BaseException(e.getMessage());
} finally { } finally {
new Thread(() -> { new Thread(() -> {
@ -221,6 +235,7 @@ public class TaskFaceServiceImpl implements TaskFaceService {
if (device != null) { if (device != null) {
record.setDeviceName(device.getName()); record.setDeviceName(device.getName());
} }
record.setMatched(item.getScore() > _threshold);
record.setFaceUrl(faceSample.getFaceUrl()); record.setFaceUrl(faceSample.getFaceUrl());
record.setShotDate(faceSample.getCreateAt()); record.setShotDate(faceSample.getCreateAt());
} }

View File

@ -17,6 +17,7 @@ import com.ycwl.basic.repository.TemplateRepository;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -28,6 +29,7 @@ import java.util.Map;
@Component @Component
@EnableScheduling @EnableScheduling
@Slf4j @Slf4j
@Profile("prod")
public class DownloadNotificationTasker { public class DownloadNotificationTasker {
@Autowired @Autowired
private ScenicRepository scenicRepository; private ScenicRepository scenicRepository;

View File

@ -116,7 +116,7 @@ public class DynamicTaskGenerator {
return; return;
} }
log.info("开始执行任务:{}", task); log.info("开始执行任务:{}", task);
SearchFaceRespVo userDbSearchResult = faceService.searchFace(USER_FACE_DB_NAME+faceSample.getScenicId(), faceSample.getFaceUrl()); SearchFaceRespVo userDbSearchResult = faceService.searchFace(USER_FACE_DB_NAME+faceSample.getScenicId(), faceSample.getFaceUrl(), "预约流程检索");
// 如果人脸样本ID在人脸样本库中则创建任务 // 如果人脸样本ID在人脸样本库中则创建任务
if (!userDbSearchResult.getSampleListIds().isEmpty()) { if (!userDbSearchResult.getSampleListIds().isEmpty()) {
log.info("人脸样本ID在人脸样本库中创建任务{}", task); log.info("人脸样本ID在人脸样本库中创建任务{}", task);

View File

@ -96,6 +96,7 @@
video_source_store_day=#{videoSourceStoreDay}, video_source_store_day=#{videoSourceStoreDay},
image_source_store_day=#{imageSourceStoreDay}, image_source_store_day=#{imageSourceStoreDay},
user_source_expire_day=#{userSourceExpireDay}, user_source_expire_day=#{userSourceExpireDay},
face_score_threshold=#{faceScoreThreshold},
force_finish_time=#{forceFinishTime} force_finish_time=#{forceFinishTime}
</set> </set>
where id = #{id} where id = #{id}