人脸识别与大模型问答
This commit is contained in:
parent
aa74d0d128
commit
fb47f5554c
|
|
@ -18,7 +18,7 @@ public class FaceResultVo implements Serializable {
|
|||
/**
|
||||
* 人脸库表id
|
||||
*/
|
||||
private String faceId;
|
||||
private Long faceId;
|
||||
/**
|
||||
* 服务id
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ package com.bonus.ai.service;
|
|||
import com.bonus.ai.domain.vo.FaceResultVo;
|
||||
import com.bonus.common.core.web.domain.AjaxResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author bonus
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ public class AiFaceRecognizeResultServiceImpl implements AiFaceRecognizeResultSe
|
|||
public AjaxResult selectAllAiFaceRecognizeResults() {
|
||||
try {
|
||||
List<FaceResultVo> faceResultVos = aiFaceRecognizeResultMapper.selectAllAiFaceRecognizeResults();
|
||||
return ObjectUtils.isNotEmpty(faceResultVos) ? AjaxResult.success(faceResultVos) : AjaxResult.error();
|
||||
return AjaxResult.success(faceResultVos);
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
package com.bonus.ai.service.impl;
|
||||
|
||||
import cn.hutool.core.io.unit.DataUnit;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.bonus.ai.domain.vo.FaceResultVo;
|
||||
import com.bonus.ai.domain.vo.FaceVo;
|
||||
import com.bonus.ai.mapper.AiFaceRecognizeResultMapper;
|
||||
import com.bonus.ai.mapper.FaceMapper;
|
||||
import com.bonus.ai.service.FaceService;
|
||||
import com.bonus.ai.utils.FaceUtils;
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.common.core.utils.DateUtils;
|
||||
import com.bonus.common.core.web.domain.AjaxResult;
|
||||
import com.bonus.common.security.utils.SecurityUtils;
|
||||
import com.bonus.system.api.RemoteFileService;
|
||||
|
|
@ -17,16 +21,8 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author bonus
|
||||
* 人脸识别服务层
|
||||
*/
|
||||
@Service
|
||||
public class FaceServiceImpl implements FaceService {
|
||||
|
||||
|
|
@ -35,20 +31,18 @@ public class FaceServiceImpl implements FaceService {
|
|||
@Resource
|
||||
private RemoteFileService remoteFileService;
|
||||
|
||||
/**
|
||||
* 查询全部人脸信息
|
||||
*/
|
||||
@Resource
|
||||
private AiFaceRecognizeResultMapper aiFaceRecognizeResultMapper;
|
||||
|
||||
private static final Set<String> VALID_IMAGE_TYPES = new HashSet<>(Arrays.asList("image/jpeg", "image/png"));
|
||||
private static final String BASE64_PREFIX = "data:";
|
||||
private static final String BASE64_SUFFIX = ";base64,";
|
||||
|
||||
@Override
|
||||
public AjaxResult getList() {
|
||||
return AjaxResult.success(faceMapper.getList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入人脸信息
|
||||
*
|
||||
* @param face 人脸信息对象
|
||||
* @return 受影响的行数
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult insertFace(MultipartFile file, FaceVo face) {
|
||||
if (isFileOrFaceInvalid(file, face)) {
|
||||
|
|
@ -57,159 +51,153 @@ public class FaceServiceImpl implements FaceService {
|
|||
try {
|
||||
String base64WithMimeType = getBase64WithMimeType(file);
|
||||
String response = FaceUtils.updateDb(base64WithMimeType, "add", face.getIdCardNumber());
|
||||
return handleInsertResponse(file, response, face, base64WithMimeType);
|
||||
return handleInsertResponse(file, response, face);
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("插入人脸信息失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 人脸识别
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult recognition(MultipartFile file) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
if (ObjectUtils.isEmpty(file)) {
|
||||
return AjaxResult.error("文件不能为空, 请选择文件");
|
||||
}
|
||||
|
||||
try {
|
||||
String base64WithMimeType = getBase64WithMimeType(file);
|
||||
String response = FaceUtils.faceRecognition(base64WithMimeType);
|
||||
return handleRecognitionResponse(response);
|
||||
return handleRecognitionResponse(response, startTime);
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("人脸识别失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 识别结果统计
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult resultStatistics() {
|
||||
return AjaxResult.success(faceMapper.resultStatistics());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断文件的 MIME 类型是否为图片类型
|
||||
*/
|
||||
private boolean isImageMimeType(String mimeType) {
|
||||
Set<String> validMimeTypes = new HashSet<>();
|
||||
validMimeTypes.add("image/jpeg");
|
||||
validMimeTypes.add("image/png");
|
||||
return mimeType != null && validMimeTypes.contains(mimeType);
|
||||
return VALID_IMAGE_TYPES.contains(mimeType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查文件和人员信息是否为空
|
||||
*/
|
||||
private boolean isFileOrFaceInvalid(MultipartFile file, FaceVo face) {
|
||||
return ObjectUtils.isEmpty(file) ||
|
||||
ObjectUtils.isEmpty(face.getName()) ||
|
||||
ObjectUtils.isEmpty(face.getIdCardNumber());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Base64编码的文件内容,并添加MIME类型
|
||||
*/
|
||||
private String getBase64WithMimeType(MultipartFile file) throws Exception {
|
||||
String mimeType = file.getContentType();
|
||||
if (!isImageMimeType(mimeType)) {
|
||||
throw new IllegalArgumentException("文件类型不支持,请上传图片文件");
|
||||
}
|
||||
|
||||
byte[] fileBytes = file.getBytes();
|
||||
String base64String = Base64.getEncoder().encodeToString(fileBytes);
|
||||
return "data:" + mimeType + ";base64," + base64String;
|
||||
return BASE64_PREFIX + mimeType + BASE64_SUFFIX + base64String;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理插入人脸信息的响应
|
||||
*/
|
||||
private AjaxResult handleInsertResponse(MultipartFile file, String response, FaceVo face, String base64WithMimeType) {
|
||||
if (response == null) return AjaxResult.error();
|
||||
JSONObject jsonObject = JSON.parseObject(response);
|
||||
String code = jsonObject.getString("code");
|
||||
switch (code) {
|
||||
case "30002":
|
||||
face.setCreateTime(new Date());
|
||||
face.setCreateBy(SecurityUtils.getUsername());
|
||||
face.setUpdateBy(SecurityUtils.getUsername());
|
||||
face.setUpdateTime(new Date());
|
||||
try {
|
||||
R<SysFile> upload = remoteFileService.upload(file);
|
||||
if (upload.getCode() == 200) {
|
||||
face.setFaceAddress(upload.getData().getUrl().replaceFirst("http://[^/]+", ""));
|
||||
return faceMapper.insertFace(face) > 0 ? AjaxResult.success() : AjaxResult.error();
|
||||
} else {
|
||||
return AjaxResult.error();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error();
|
||||
}
|
||||
case "30006":
|
||||
return AjaxResult.error("文件类型不支持");
|
||||
case "30007":
|
||||
return AjaxResult.error("不支持的操作类型");
|
||||
case "30008":
|
||||
return AjaxResult.error("存在多张人脸");
|
||||
case "30009":
|
||||
return AjaxResult.error("光照条件差");
|
||||
case "30016":
|
||||
return AjaxResult.error("人脸图片不清晰");
|
||||
case "30010":
|
||||
case "30011":
|
||||
return AjaxResult.error("人脸不全");
|
||||
case "30019":
|
||||
return AjaxResult.error("人员信息已存在");
|
||||
case "30018":
|
||||
return AjaxResult.error("未检测到人脸");
|
||||
default:
|
||||
return AjaxResult.error();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理人脸识别的响应
|
||||
*/
|
||||
private AjaxResult handleRecognitionResponse(String response) {
|
||||
private AjaxResult handleInsertResponse(MultipartFile file, String response, FaceVo face) {
|
||||
if (response == null) {
|
||||
return AjaxResult.error();
|
||||
}
|
||||
JSONObject jsonObject = JSON.parseObject(response);
|
||||
String code = jsonObject.getString("code");
|
||||
switch (code) {
|
||||
case "30000":
|
||||
JSONArray dataArray = jsonObject.getJSONArray("data");
|
||||
String idCardNumber = dataArray.getString(0);
|
||||
List<FaceVo> faceByIdCardNumber = faceMapper.getFaceByIdCardNumber(idCardNumber);
|
||||
return faceByIdCardNumber != null && !faceByIdCardNumber.isEmpty()
|
||||
? AjaxResult.success(faceByIdCardNumber.get(0))
|
||||
: AjaxResult.error("人员不存在");
|
||||
case "30001":
|
||||
return AjaxResult.error("人员不存在");
|
||||
case "30006":
|
||||
return AjaxResult.error("文件类型不支持");
|
||||
case "30007":
|
||||
return AjaxResult.error("不支持的操作类型");
|
||||
case "30008":
|
||||
return AjaxResult.error("存在多张人脸");
|
||||
case "30009":
|
||||
return AjaxResult.error("光照条件差");
|
||||
case "30010":
|
||||
case "30011":
|
||||
return AjaxResult.error("人脸不全");
|
||||
case "30019":
|
||||
return AjaxResult.error("人员信息已存在");
|
||||
case "30018":
|
||||
return AjaxResult.error("未检测到人脸");
|
||||
default:
|
||||
|
||||
if ("30002".equals(code)) {
|
||||
face.setCreateTime(new Date());
|
||||
face.setCreateBy(SecurityUtils.getUsername());
|
||||
face.setUpdateBy(SecurityUtils.getUsername());
|
||||
face.setUpdateTime(new Date());
|
||||
|
||||
try {
|
||||
return handleFileUpload(file, face);
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error();
|
||||
}
|
||||
}
|
||||
|
||||
return handleCommonErrors(code, null, 0);
|
||||
}
|
||||
|
||||
private AjaxResult handleFileUpload(MultipartFile file, FaceVo face) throws Exception {
|
||||
R<SysFile> upload = remoteFileService.upload(file);
|
||||
if (upload.getCode() == 200) {
|
||||
face.setFaceAddress(upload.getData().getUrl().replaceFirst("http://[^/]+", ""));
|
||||
return faceMapper.insertFace(face) > 0 ? AjaxResult.success() : AjaxResult.error();
|
||||
}
|
||||
return AjaxResult.error();
|
||||
}
|
||||
|
||||
private AjaxResult handleCommonErrors(String code, FaceResultVo faceResultVo, long startTime) {
|
||||
Map<String, String> errorMessages = new HashMap<>();
|
||||
errorMessages.put("30006", "文件类型不支持");
|
||||
errorMessages.put("30007", "不支持的操作类型");
|
||||
errorMessages.put("30008", "存在多张人脸");
|
||||
errorMessages.put("30009", "光照条件差");
|
||||
errorMessages.put("30016", "人脸图片不清晰");
|
||||
errorMessages.put("30010", "人脸不全");
|
||||
errorMessages.put("30011", "人脸不全");
|
||||
errorMessages.put("30019", "人员信息已存在");
|
||||
errorMessages.put("30018", "未检测到人脸");
|
||||
if (ObjectUtils.isEmpty(faceResultVo)) {
|
||||
faceResultVo.setResultStatus("1");
|
||||
faceResultVo.setFailureReason(errorMessages.get(code));
|
||||
long endTime = System.currentTimeMillis();
|
||||
long elapsedTime = endTime - startTime;
|
||||
faceResultVo.setResponseLong(String.valueOf(elapsedTime));
|
||||
aiFaceRecognizeResultMapper.insertAiFaceRecognizeResult(faceResultVo);
|
||||
}
|
||||
return errorMessages.containsKey(code)
|
||||
? AjaxResult.error(errorMessages.get(code))
|
||||
: AjaxResult.error();
|
||||
}
|
||||
|
||||
private AjaxResult handleRecognitionResponse(String response, long startTime) {
|
||||
if (response == null) {
|
||||
return AjaxResult.error();
|
||||
}
|
||||
JSONObject jsonObject = JSON.parseObject(response);
|
||||
String code = jsonObject.getString("code");
|
||||
FaceResultVo faceResultVo = buildFaceResultVo();
|
||||
if ("30000".equals(code)) {
|
||||
return handleRecognitionSuccess(jsonObject, faceResultVo, startTime);
|
||||
}
|
||||
return handleCommonErrors(code, faceResultVo, startTime);
|
||||
}
|
||||
|
||||
private FaceResultVo buildFaceResultVo() {
|
||||
FaceResultVo faceResultVo = new FaceResultVo();
|
||||
faceResultVo.setInvokeIp("192.168.0.14");
|
||||
faceResultVo.setServiceId("4");
|
||||
faceResultVo.setResultType("0");
|
||||
faceResultVo.setDelFlag("0");
|
||||
faceResultVo.setUpdateBy(SecurityUtils.getUsername());
|
||||
faceResultVo.setUpdateTime(DateUtils.getTime());
|
||||
faceResultVo.setRecognizeTime(DateUtils.getTime());
|
||||
return faceResultVo;
|
||||
}
|
||||
|
||||
private AjaxResult handleRecognitionSuccess(JSONObject jsonObject, FaceResultVo faceResultVo, long startTime) {
|
||||
JSONArray dataArray = jsonObject.getJSONArray("data");
|
||||
String idCardNumber = dataArray.getString(0);
|
||||
List<FaceVo> faceByIdCardNumber = faceMapper.getFaceByIdCardNumber(idCardNumber);
|
||||
if (faceByIdCardNumber != null && !faceByIdCardNumber.isEmpty()) {
|
||||
faceResultVo.setFaceId(faceByIdCardNumber.get(0).getFaceId());
|
||||
faceResultVo.setFaceAddress(faceByIdCardNumber.get(0).getFaceAddress());
|
||||
faceResultVo.setResultStatus("0");
|
||||
long endTime = System.currentTimeMillis();
|
||||
long elapsedTime = endTime - startTime;
|
||||
faceResultVo.setResponseLong(String.valueOf(elapsedTime));
|
||||
aiFaceRecognizeResultMapper.insertAiFaceRecognizeResult(faceResultVo);
|
||||
return AjaxResult.success(faceByIdCardNumber.get(0));
|
||||
}
|
||||
faceResultVo.setResultStatus("1");
|
||||
faceResultVo.setFailureReason("人员不存在");
|
||||
long endTime = System.currentTimeMillis();
|
||||
long elapsedTime = endTime - startTime;
|
||||
faceResultVo.setResponseLong(String.valueOf(elapsedTime));
|
||||
aiFaceRecognizeResultMapper.insertAiFaceRecognizeResult(faceResultVo);
|
||||
return AjaxResult.error("人员不存在");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
result_status = #{resultStatus},
|
||||
failure_reason = #{failureReason}
|
||||
WHERE result_id = #{resultId}
|
||||
AND del_flag = '0'
|
||||
</update>
|
||||
|
||||
<!-- 根据主键ID查询记录 -->
|
||||
|
|
@ -57,6 +58,7 @@
|
|||
failure_reason AS failureReason
|
||||
FROM ai_facerecognize_result
|
||||
WHERE result_id = #{resultId}
|
||||
AND del_flag = '0'
|
||||
</select>
|
||||
|
||||
<!-- 查询所有记录 -->
|
||||
|
|
@ -76,6 +78,7 @@
|
|||
result_status AS resultStatus,
|
||||
failure_reason AS failureReason
|
||||
FROM ai_facerecognize_result
|
||||
WHERE del_flag = '0'
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
|
|||
Loading…
Reference in New Issue