人脸识别与大模型问答

This commit is contained in:
jiang 2024-08-26 17:48:30 +08:00
parent aa74d0d128
commit fb47f5554c
5 changed files with 116 additions and 127 deletions

View File

@ -18,7 +18,7 @@ public class FaceResultVo implements Serializable {
/**
* 人脸库表id
*/
private String faceId;
private Long faceId;
/**
* 服务id
*/

View File

@ -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
*/

View File

@ -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();
}

View File

@ -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("人员不存在");
}
}

View File

@ -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>