人脸提取特征值(后台服务--公司版)
This commit is contained in:
		
							parent
							
								
									be5c5a8b86
								
							
						
					
					
						commit
						eb5c31e5a9
					
				| 
						 | 
				
			
			@ -1,13 +1,17 @@
 | 
			
		|||
package com.bonus.canteen.core.kitchen.service.impl;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.util.ObjectUtil;
 | 
			
		||||
import com.alibaba.fastjson.JSONArray;
 | 
			
		||||
import com.alibaba.fastjson.JSONObject;
 | 
			
		||||
import com.bonus.canteen.core.common.utils.FileUrlUtil;
 | 
			
		||||
import com.bonus.canteen.core.common.utils.MqUtil;
 | 
			
		||||
import com.bonus.canteen.core.kitchen.domain.KitchenStaffFace;
 | 
			
		||||
import com.bonus.canteen.core.kitchen.mapper.KitchenStaffFaceMapper;
 | 
			
		||||
import com.bonus.canteen.core.kitchen.service.IKitchenStaffFaceService;
 | 
			
		||||
import com.bonus.canteen.core.user.domain.DeviceMqPersonalUpdateMessageDTO;
 | 
			
		||||
import com.bonus.canteen.core.user.domain.UserFace;
 | 
			
		||||
import com.bonus.canteen.core.user.utils.ArcFaceHelper;
 | 
			
		||||
import com.bonus.canteen.core.user.utils.FaceFeatureDetector;
 | 
			
		||||
import com.bonus.canteen.core.user.utils.FaceResult;
 | 
			
		||||
import com.bonus.common.core.exception.ServiceException;
 | 
			
		||||
import com.bonus.common.core.utils.DateUtils;
 | 
			
		||||
| 
						 | 
				
			
			@ -57,16 +61,29 @@ public class KitchenStaffFaceServiceImpl implements IKitchenStaffFaceService {
 | 
			
		|||
            DeviceMqPersonalUpdateMessageDTO bean = new DeviceMqPersonalUpdateMessageDTO().setUpdatePersonPhoto(dto.getStaffId().intValue(),"del");
 | 
			
		||||
            MqUtil.pushToTenantAllDevice(bean, LeMqConstant.Topic.MORNING_INSPECTION_DEVICE_UPDATE_PERSONAL_CONFIG_V4);
 | 
			
		||||
        } else {
 | 
			
		||||
            log.info("开始采集虹软人脸");
 | 
			
		||||
            ArcFaceHelper arcFaceHelper = new ArcFaceHelper();
 | 
			
		||||
            long startTime = System.currentTimeMillis();
 | 
			
		||||
            //发送请求 调用人脸特征提取接口
 | 
			
		||||
            String url = FileUrlUtil.getFileUrl(dto.getPhotoUrl());
 | 
			
		||||
            FaceResult faceResult = arcFaceHelper.getFaceFeatures(url);
 | 
			
		||||
            log.info("采集结束");
 | 
			
		||||
            System.out.println("人脸特征提取url:" + url);
 | 
			
		||||
            String response = FaceFeatureDetector.detectFaceFeature(url);
 | 
			
		||||
            System.out.println("人脸特征提取接口返回结果:" + response);
 | 
			
		||||
            JSONObject jsonResponse = JSONObject.parseObject(response.toString());
 | 
			
		||||
            if (jsonResponse.getInteger("code") != 30002) {
 | 
			
		||||
                System.out.println("人脸特征提取失败," + jsonResponse.getString("msg"));
 | 
			
		||||
                log.error("人脸特征提取失败,{}", jsonResponse.getString("msg"));
 | 
			
		||||
                throw new ServiceException("人脸特征提取失败," + jsonResponse.getString("msg"));
 | 
			
		||||
            }
 | 
			
		||||
            long endTime = System.currentTimeMillis();
 | 
			
		||||
            System.out.println("人脸特征提取耗时:" + (endTime - startTime) + "ms");
 | 
			
		||||
            List<KitchenStaffFace> list = new ArrayList<>();
 | 
			
		||||
            if (faceResult != null) {
 | 
			
		||||
            String dataStr = jsonResponse.getString("data");
 | 
			
		||||
            // 将data字符串解析为JSONArray
 | 
			
		||||
            JSONArray dataArray = JSONArray.parseArray(dataStr);
 | 
			
		||||
            if (dataArray != null && !dataArray.isEmpty()) {
 | 
			
		||||
                Object faceFeature = dataArray.get(0);
 | 
			
		||||
                KitchenStaffFace faceVO = new KitchenStaffFace();
 | 
			
		||||
                faceVO.setErrorMsg("[软件]成功");
 | 
			
		||||
                faceVO.setFeatures(Base64.getEncoder().encodeToString(faceResult.getFeatures()));
 | 
			
		||||
                faceVO.setFeatures(faceFeature.toString());
 | 
			
		||||
                faceVO.setCreateBy(String.valueOf(SecurityUtils.getUserId()));
 | 
			
		||||
                faceVO.setStaffId(dto.getStaffId());
 | 
			
		||||
                faceVO.setPhotoUrl(dto.getPhotoUrl());
 | 
			
		||||
| 
						 | 
				
			
			@ -75,18 +92,17 @@ public class KitchenStaffFaceServiceImpl implements IKitchenStaffFaceService {
 | 
			
		|||
                faceVO.setCreateTime(DateUtils.getTime());
 | 
			
		||||
                faceVO.setUpdateTime(DateUtils.getTime());
 | 
			
		||||
                list.add(faceVO);
 | 
			
		||||
                log.info("faceResult.getFeatures():" + Base64.getEncoder().encodeToString(faceResult.getFeatures()));
 | 
			
		||||
                log.info("人脸采集成功");
 | 
			
		||||
            } else {
 | 
			
		||||
                throw new ServiceException("人脸照片识别失败");
 | 
			
		||||
                int code = kitchenStaffFaceMapper.insertStaffFace(list.get(0));
 | 
			
		||||
                if (code == 0) {
 | 
			
		||||
                    System.out.println("[人脸识别算法]:保存失败");
 | 
			
		||||
                    log.error("[人脸识别算法]:保存失败");
 | 
			
		||||
                    throw new ServiceException("[人脸识别算法]:保存失败");
 | 
			
		||||
                }
 | 
			
		||||
                DeviceMqPersonalUpdateMessageDTO bean = new DeviceMqPersonalUpdateMessageDTO().setUpdatePersonPhoto(dto.getStaffId().intValue(),"update");
 | 
			
		||||
                MqUtil.pushToTenantAllDevice(bean, LeMqConstant.Topic.MORNING_INSPECTION_DEVICE_UPDATE_PERSONAL_CONFIG_V4);
 | 
			
		||||
            }else{
 | 
			
		||||
                throw new ServiceException("人脸特征提取失败,未检测到人脸");
 | 
			
		||||
            }
 | 
			
		||||
            int code = kitchenStaffFaceMapper.insertStaffFace(list.get(0));
 | 
			
		||||
            if (code == 0){
 | 
			
		||||
                throw new ServiceException("人脸照片保存失败");
 | 
			
		||||
            }
 | 
			
		||||
//            //发送mq
 | 
			
		||||
            DeviceMqPersonalUpdateMessageDTO bean = new DeviceMqPersonalUpdateMessageDTO().setUpdatePersonPhoto(dto.getStaffId().intValue(),"update");
 | 
			
		||||
            MqUtil.pushToTenantAllDevice(bean, LeMqConstant.Topic.MORNING_INSPECTION_DEVICE_UPDATE_PERSONAL_CONFIG_V4);
 | 
			
		||||
        }
 | 
			
		||||
        return AjaxResult.success();
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,15 +1,22 @@
 | 
			
		|||
package com.bonus.canteen.core.user.service.impl;
 | 
			
		||||
 | 
			
		||||
import java.beans.FeatureDescriptor;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
import java.time.format.DateTimeFormatter;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Base64;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.util.ObjectUtil;
 | 
			
		||||
import com.alibaba.fastjson.JSONArray;
 | 
			
		||||
import com.alibaba.fastjson.JSONObject;
 | 
			
		||||
import com.bonus.canteen.core.common.utils.FileUrlUtil;
 | 
			
		||||
import com.bonus.canteen.core.common.utils.HttpClient;
 | 
			
		||||
import com.bonus.canteen.core.common.utils.MqUtil;
 | 
			
		||||
import com.bonus.canteen.core.user.domain.DeviceMqPersonalUpdateMessageDTO;
 | 
			
		||||
import com.bonus.canteen.core.user.utils.ArcFaceHelper;
 | 
			
		||||
import com.bonus.canteen.core.user.utils.FaceFeatureDetector;
 | 
			
		||||
import com.bonus.canteen.core.user.utils.FaceResult;
 | 
			
		||||
import com.bonus.common.core.exception.ServiceException;
 | 
			
		||||
import com.bonus.common.core.utils.DateUtils;
 | 
			
		||||
| 
						 | 
				
			
			@ -46,6 +53,7 @@ public class UserFaceServiceImpl implements IUserFaceService {
 | 
			
		|||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public AjaxResult uploadUserFace(UserFace dto) {
 | 
			
		||||
        System.out.println("开始人脸识别");
 | 
			
		||||
        if (ObjectUtil.isNull(dto)) {
 | 
			
		||||
            throw new ServiceException("参数为空!");
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -55,19 +63,32 @@ public class UserFaceServiceImpl implements IUserFaceService {
 | 
			
		|||
        if (StringUtils.isEmpty(dto.getPhotoUrl())) {
 | 
			
		||||
            userFaceMapper.deleteUserFace(dto);
 | 
			
		||||
            //发送mq
 | 
			
		||||
            DeviceMqPersonalUpdateMessageDTO bean = new DeviceMqPersonalUpdateMessageDTO().setUpdatePersonPhoto(dto.getUserId().intValue(),"del");
 | 
			
		||||
            DeviceMqPersonalUpdateMessageDTO bean = new DeviceMqPersonalUpdateMessageDTO().setUpdatePersonPhoto(dto.getUserId().intValue(), "del");
 | 
			
		||||
            MqUtil.pushToTenantAllDevice(bean, LeMqConstant.Topic.DEVICE_UPDATE_PERSONAL_CONFIG_V4);
 | 
			
		||||
        } else {
 | 
			
		||||
            log.info("开始采集虹软人脸");
 | 
			
		||||
            ArcFaceHelper arcFaceHelper = new ArcFaceHelper();
 | 
			
		||||
            long startTime = System.currentTimeMillis();
 | 
			
		||||
            //发送请求 调用人脸特征提取接口
 | 
			
		||||
            String url = FileUrlUtil.getFileUrl(dto.getPhotoUrl());
 | 
			
		||||
            FaceResult faceResult = arcFaceHelper.getFaceFeatures(url);
 | 
			
		||||
            log.info("采集结束");
 | 
			
		||||
            System.out.println("人脸特征提取url:" + url);
 | 
			
		||||
            String response = FaceFeatureDetector.detectFaceFeature(url);
 | 
			
		||||
            System.out.println("人脸特征提取接口返回结果:" + response);
 | 
			
		||||
            JSONObject jsonResponse = JSONObject.parseObject(response.toString());
 | 
			
		||||
            if (jsonResponse.getInteger("code") != 30002) {
 | 
			
		||||
                System.out.println("人脸特征提取失败," + jsonResponse.getString("msg"));
 | 
			
		||||
                log.error("人脸特征提取失败,{}", jsonResponse.getString("msg"));
 | 
			
		||||
                throw new ServiceException("人脸特征提取失败," + jsonResponse.getString("msg"));
 | 
			
		||||
            }
 | 
			
		||||
            long endTime = System.currentTimeMillis();
 | 
			
		||||
            System.out.println("人脸特征提取耗时:" + (endTime - startTime) + "ms");
 | 
			
		||||
            List<UserFace> list = new ArrayList<>();
 | 
			
		||||
            if (faceResult != null) {
 | 
			
		||||
            String dataStr = jsonResponse.getString("data");
 | 
			
		||||
            // 将data字符串解析为JSONArray
 | 
			
		||||
            JSONArray dataArray = JSONArray.parseArray(dataStr);
 | 
			
		||||
            if (dataArray != null && !dataArray.isEmpty()) {
 | 
			
		||||
                Object faceFeature = dataArray.get(0);
 | 
			
		||||
                UserFace faceVO = new UserFace();
 | 
			
		||||
                faceVO.setErrorMsg("[软件]成功");
 | 
			
		||||
                faceVO.setFeatures(Base64.getEncoder().encodeToString(faceResult.getFeatures()));
 | 
			
		||||
                faceVO.setFeatures(faceFeature.toString());
 | 
			
		||||
                faceVO.setCreateBy(String.valueOf(SecurityUtils.getUserId()));
 | 
			
		||||
                faceVO.setUserId(dto.getUserId());
 | 
			
		||||
                faceVO.setPhotoUrl(dto.getPhotoUrl());
 | 
			
		||||
| 
						 | 
				
			
			@ -76,18 +97,17 @@ public class UserFaceServiceImpl implements IUserFaceService {
 | 
			
		|||
                faceVO.setCreateTime(DateUtils.getTime());
 | 
			
		||||
                faceVO.setUpdateTime(DateUtils.getTime());
 | 
			
		||||
                list.add(faceVO);
 | 
			
		||||
                log.info("faceResult.getFeatures():" + Base64.getEncoder().encodeToString(faceResult.getFeatures()));
 | 
			
		||||
                log.info("人脸采集成功");
 | 
			
		||||
            } else {
 | 
			
		||||
                throw new ServiceException("[虹软算法]:特征值提取失败");
 | 
			
		||||
                int code = userFaceMapper.insertUserFace(list.get(0));
 | 
			
		||||
                if (code == 0) {
 | 
			
		||||
                    System.out.println("[人脸识别算法]:保存失败");
 | 
			
		||||
                    log.error("[人脸识别算法]:保存失败");
 | 
			
		||||
                    throw new ServiceException("[人脸识别算法]:保存失败");
 | 
			
		||||
                }
 | 
			
		||||
                DeviceMqPersonalUpdateMessageDTO bean = new DeviceMqPersonalUpdateMessageDTO().setUpdatePersonPhoto(dto.getUserId().intValue(), "update");
 | 
			
		||||
                MqUtil.pushToTenantAllDevice(bean, LeMqConstant.Topic.DEVICE_UPDATE_PERSONAL_CONFIG_V4);
 | 
			
		||||
            }else{
 | 
			
		||||
                throw new ServiceException("人脸特征提取失败,未检测到人脸");
 | 
			
		||||
            }
 | 
			
		||||
            int code = userFaceMapper.insertUserFace(list.get(0));
 | 
			
		||||
            if (code == 0){
 | 
			
		||||
                throw new ServiceException("[虹软算法]:保存失败");
 | 
			
		||||
            }
 | 
			
		||||
            //发送mq
 | 
			
		||||
            DeviceMqPersonalUpdateMessageDTO bean = new DeviceMqPersonalUpdateMessageDTO().setUpdatePersonPhoto(dto.getUserId().intValue(),"update");
 | 
			
		||||
            MqUtil.pushToTenantAllDevice(bean, LeMqConstant.Topic.DEVICE_UPDATE_PERSONAL_CONFIG_V4);
 | 
			
		||||
        }
 | 
			
		||||
        return AjaxResult.success();
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,107 @@
 | 
			
		|||
package com.bonus.canteen.core.user.utils;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.net.HttpURLConnection;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.nio.charset.StandardCharsets;
 | 
			
		||||
import java.util.Base64;
 | 
			
		||||
 | 
			
		||||
public class FaceFeatureDetector {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 检测人脸特征
 | 
			
		||||
     * @param imageInput 图片路径、base64编码或URL
 | 
			
		||||
     * @return 服务器响应
 | 
			
		||||
     */
 | 
			
		||||
    public static String detectFaceFeature(String imageInput) {
 | 
			
		||||
        String apiUrl = "http://10.145.136.229:16699/featuredetect/";
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            // 判断输入类型
 | 
			
		||||
            String imgType = determineImageInputType(imageInput);
 | 
			
		||||
            String imgData;
 | 
			
		||||
 | 
			
		||||
            if ("path".equals(imgType)) {
 | 
			
		||||
                // 如果是本地路径,读取文件并转为base64
 | 
			
		||||
                imgData = fileToBase64(imageInput);
 | 
			
		||||
            } else {
 | 
			
		||||
                // 如果是base64或URL,直接使用
 | 
			
		||||
                imgData = imageInput;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 创建JSON请求体
 | 
			
		||||
            String jsonInputString = String.format("{\"img\":\"%s\"}", imgData);
 | 
			
		||||
 | 
			
		||||
            // 创建连接
 | 
			
		||||
            URL url = new URL(apiUrl);
 | 
			
		||||
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
 | 
			
		||||
            connection.setRequestMethod("POST");
 | 
			
		||||
            connection.setRequestProperty("Content-Type", "application/json; utf-8");
 | 
			
		||||
            connection.setRequestProperty("Accept", "application/json");
 | 
			
		||||
            connection.setDoOutput(true);
 | 
			
		||||
 | 
			
		||||
            // 发送请求
 | 
			
		||||
            try (OutputStream os = connection.getOutputStream()) {
 | 
			
		||||
                byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8);
 | 
			
		||||
                os.write(input, 0, input.length);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 获取响应
 | 
			
		||||
            StringBuilder response = new StringBuilder();
 | 
			
		||||
            try (BufferedReader br = new BufferedReader(
 | 
			
		||||
                    new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
 | 
			
		||||
                String responseLine;
 | 
			
		||||
                while ((responseLine = br.readLine()) != null) {
 | 
			
		||||
                    response.append(responseLine.trim());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return response.toString();
 | 
			
		||||
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            return "{\"code\":\"500\",\"msg\":\"请求失败: " + e.getMessage() + "\"}";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 判断图片输入类型
 | 
			
		||||
     * @param input 输入字符串
 | 
			
		||||
     * @return 类型:path, base64, url
 | 
			
		||||
     */
 | 
			
		||||
    private static String determineImageInputType(String input) {
 | 
			
		||||
        // 检查是否是文件路径
 | 
			
		||||
        if (new File(input).exists()) {
 | 
			
		||||
            return "path";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 检查是否是base64编码(简单检查)
 | 
			
		||||
        if (input.matches("^[A-Za-z0-9+/]+={0,2}$")) {
 | 
			
		||||
            return "base64";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 检查是否是URL
 | 
			
		||||
        if (input.startsWith("http://") || input.startsWith("https://")) {
 | 
			
		||||
            return "url";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 默认认为是base64
 | 
			
		||||
        return "base64";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 将文件转为base64编码
 | 
			
		||||
     * @param filePath 文件路径
 | 
			
		||||
     * @return base64编码字符串
 | 
			
		||||
     * @throws IOException
 | 
			
		||||
     */
 | 
			
		||||
    private static String fileToBase64(String filePath) throws IOException {
 | 
			
		||||
        File file = new File(filePath);
 | 
			
		||||
        try (FileInputStream imageInFile = new FileInputStream(file)) {
 | 
			
		||||
            byte[] fileData = new byte[(int) file.length()];
 | 
			
		||||
            imageInFile.read(fileData);
 | 
			
		||||
            return Base64.getEncoder().encodeToString(fileData);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue