zoukankan      html  css  js  c++  java
  • face++人脸识别相关技术

    face++主页

    首先需要创建faceSet,一个faceSet下有多个facetoken,facetoken就是人脸数据

    其次,一张图片每次可以生成多个不同的facetoken,

    可以只保留一个facetoken,然后直接判断facetoken是否与数据库的相同,如果执行这一步,可以使用删除的方法

    也可以保留多个facetoken,根据一张图片获取多个facetoken然后遍历与数据库相同的,确定人物身份

    查询时在faceSet里面查这个图片所对应的facetoken,如果系统只存了一个,那就返回这唯一的一个,如果多个就会返回多个

     定义实体类

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    class Face {
        private Double confidence;
        private String gender;
        private int age;
        private String faceToken;
    }
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    class FaceBean {
        private String imageId;
        private String requestId;
        private Map<String,Double> thresholds;
        private List<Face> faces;
        private List<Face> results;
    }
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    class FaceSet {
        private String facesetToken;
        private int faceCount;
        private int faceAdded;
        private String requestId;
        private String outerId;
        private String errorMessage;
    
    }
    public class FaceUtils {
    
        private Logger logger = LogManager.getLogger(FaceUtils.class);
    
        private final String API_KEY = "api_key";
        private final String API_SECRET = "api_secret";
    
        /**
         * 创建人脸并添加至指定的人脸库
         * @param file 图片文件
         * @param faceSet 人脸库
         * @return 返回face_token
         * @throws Exception  可能抛出创建人脸异常/绑定人脸异常
         */
        public String createAndBind(File file, String faceSet) throws Exception {
                @Cleanup InputStream inputStream = new FileInputStream(file);
                byte [] bytes = new byte[(int) file.length()];
                inputStream.read(bytes);
                String base64 = Base64.getEncoder().encodeToString(bytes);
                return createFace(base64,faceSet);
        }
    
        /**
         * 创建人脸并添加至指定的人脸库
         * @param file 图片文件
         * @param faceSet 人脸库
         * @return 返回face_token
         * @throws Exception  可能抛出创建人脸异常/绑定人脸异常
         */
        public String createAndBind(MultipartFile file, String faceSet) throws Exception {
            return  createFace(Base64.getEncoder().encodeToString(file.getBytes()),faceSet);
        }
    
        /**
         *
         * @param image_base64  图片文件Base64字符串
         * @param faceSet 人脸库
         */
        private String createFace(String image_base64, String faceSet) throws Exception {
            HashMap<String, Object> map = new HashMap<>();
            map.put("api_key", API_KEY);
            map.put("api_secret", API_SECRET);
            map.put("image_base64", image_base64);
            String url = "https://api-cn.faceplusplus.com/facepp/v3/detect";
            String str;
            try {
                byte[] bacd = post(url, map);
                str = new String(bacd);
            } catch (Exception e) {
                e.printStackTrace();
                throw new Exception("生成人脸token出现异常");
            }
            FaceBean faceBean = JSONObject.parseObject(str, FaceBean.class);
            if (ObjectUtils.isEmpty(faceBean.getFaces())){
                throw new Exception("生成人脸token出现异常");
            }
            String face_token = faceBean.getFaces().get(0).getFaceToken();
            url = "https://api-cn.faceplusplus.com/facepp/v3/faceset/addface";
            map.clear();
            map.put("api_key", API_KEY);
            map.put("api_secret", API_SECRET);
            map.put("faceset_token", faceSet);
            map.put("face_tokens", face_token);
            try {
                byte[] bacd = post(url, map);
                String result = new String(bacd);
                FaceSet set = JSONObject.parseObject(result, FaceSet.class);
                if (!ObjectUtils.isEmpty(set.getErrorMessage())) {
                    throw new Exception();
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new Exception("绑定人脸库出现异常");
            }
            return face_token;
        }
    
        /**
         * 查询人脸信息 传入图片 ,从指定人脸库查询人脸
         * @param file  图片文件
         * @param faceSet 人脸库 
         */
        public String searchFace(MultipartFile file, String faceSet) throws IOException {
            String image_base64 = Base64.getEncoder().encodeToString(file.getBytes());
            HashMap<String, Object> map = new HashMap<>();
            String url = "https://api-cn.faceplusplus.com/facepp/v3/search";
            map.put("api_key", API_KEY);
            map.put("api_secret", API_SECRET);
            map.put("faceset_token", faceSet);
            map.put("image_base64", image_base64);
            try {
                String result = new String(this.post(url, map));
                FaceBean faceBean = JSONObject.parseObject(result, FaceBean.class);
                if (ObjectUtils.isEmpty(faceBean.getResults())){
                    return "未找到人脸";
                }
                Double aDouble = faceBean.getThresholds().get("1e-3");
                logger.warn("对比度 {}",aDouble);
                //判断对比阈值
                if(faceBean.getResults().get(0).getConfidence()<aDouble){
                    return "未找到人脸";
                }
                return faceBean.getResults().get(0).getFaceToken();
            } catch (Exception e) {
                e.printStackTrace();
                return "未找到人脸";
            }
        }
    
        /**
         * 删除指定库中的指定某张图片
         */
        public String removeFace(HashMap<String, Object> map){
            map.put("api_key",API_KEY);
            map.put("api_secret",API_SECRET);
            String str = null;
            final String DELETE_FACE_SET_URL = "https://api-cn.faceplusplus.com/facepp/v3/faceset/removeface";
            try {
                byte[] bacd = post(DELETE_FACE_SET_URL, map);
                str = new String(bacd);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return str;
        }
    
        private String boundaryString = getBoundary();
    
        private byte[] post(String url, HashMap<String, Object> map) throws Exception {
            HttpURLConnection conne;
            URL url1 = new URL(url);
            conne = (HttpURLConnection) url1.openConnection();
            conne.setDoOutput(true);
            conne.setUseCaches(false);
            conne.setRequestMethod("POST");
            conne.setConnectTimeout(30000);
            conne.setReadTimeout(50000);
            conne.setRequestProperty("accept", "*/*");
            conne.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundaryString);
            conne.setRequestProperty("connection", "Keep-Alive");
            conne.setRequestProperty("user-agent", "Mozilla/4.0 (compatible;MSIE 6.0;Windows NT 5.1;SV1)");
            DataOutputStream obos = new DataOutputStream(conne.getOutputStream());
            for (Object o : map.entrySet()) {
                Map.Entry<String, String> entry = (Map.Entry) o;
                String key = entry.getKey();
                String value = String.valueOf(entry.getValue());
                obos.writeBytes("--" + boundaryString + "
    ");
                obos.writeBytes("Content-Disposition: form-data; name="" + key
                        + ""
    ");
                obos.writeBytes("
    ");
                obos.writeBytes(value + "
    ");
            }
            obos.writeBytes("--" + boundaryString + "--" + "
    ");
            obos.writeBytes("
    ");
            obos.flush();
            obos.close();
            InputStream ins = null;
            int code = conne.getResponseCode();
            try {
                if (code == 200) {
                    ins = conne.getInputStream();
                } else {
                    ins = conne.getErrorStream();
                }
            } catch (SSLException e) {
                e.printStackTrace();
                return new byte[0];
            }
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buff = new byte[4096];
            int len;
            while ((len = ins.read(buff)) != -1) {
                baos.write(buff, 0, len);
            }
            byte[] bytes = baos.toByteArray();
            ins.close();
            return bytes;
        }
    
        private static String getBoundary() {
            StringBuilder sb = new StringBuilder();
            Random random = new Random();
            for (int i = 0; i < 32; ++i) {
                sb.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-".charAt(random.nextInt("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_".length())));
            }
            return sb.toString();
        }
    }
  • 相关阅读:
    Java自学笔记(13):【面向对象】方法覆盖,final关键字,对象转型
    Java自学笔记(12):【面向对象】继承,super关键字,继承下的访问控制权限
    Java自学笔记(11):【面向对象】 package,import,访问控制修饰符,static
    计算机领域会议和期刊
    powershell真香
    C语言博客作业--结构体
    C博客作业--指针
    C语言博客作业--字符数组
    C语言博客作业--一二维数组
    C语言博客作业--数据类型
  • 原文地址:https://www.cnblogs.com/yeg0zj/p/13073409.html
Copyright © 2011-2022 走看看